summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deleted_files/usr/src/cmd/fs.d/hsfs/ident/Makefile (renamed from usr/src/cmd/fs.d/hsfs/ident/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c (renamed from usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/pcfs/ident/Makefile (renamed from usr/src/cmd/fs.d/pcfs/ident/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c (renamed from usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/udfs/ident/Makefile (renamed from usr/src/cmd/fs.d/udfs/ident/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/udfs/ident/ident_udfs.c (renamed from usr/src/cmd/fs.d/udfs/ident/ident_udfs.c)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/ufs/ident/Makefile (renamed from usr/src/cmd/fs.d/ufs/ident/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c (renamed from usr/src/cmd/fs.d/ufs/ident/ident_ufs.c)0
-rw-r--r--deleted_files/usr/src/cmd/initpkg/init.d/volmgt (renamed from usr/src/cmd/initpkg/init.d/volmgt)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/Makefile (renamed from usr/src/cmd/volmgt/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/Makefile.volmgt (renamed from usr/src/cmd/volmgt/Makefile.volmgt)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/etc/Makefile (renamed from usr/src/cmd/volmgt/etc/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/etc/rmmount.conf (renamed from usr/src/cmd/volmgt/etc/rmmount.conf)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/etc/svc-volfs (renamed from usr/src/cmd/volmgt/etc/svc-volfs)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/etc/vold.conf (renamed from usr/src/cmd/volmgt/etc/vold.conf)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/etc/volfs.xml (renamed from usr/src/cmd/volmgt/etc/volfs.xml)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/req.flg (renamed from usr/src/cmd/volmgt/req.flg)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/Makefile (renamed from usr/src/cmd/volmgt/rmm/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/action_dvdvideo.c (renamed from usr/src/cmd/volmgt/rmm/action_dvdvideo.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/action_filemgr.c (renamed from usr/src/cmd/volmgt/rmm/action_filemgr.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/action_test.c (renamed from usr/src/cmd/volmgt/rmm/action_test.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/action_wabi.c (renamed from usr/src/cmd/volmgt/rmm/action_wabi.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/action_workman.c (renamed from usr/src/cmd/volmgt/rmm/action_workman.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/action_xmcd.c (renamed from usr/src/cmd/volmgt/rmm/action_xmcd.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/req.flg (renamed from usr/src/cmd/volmgt/rmm/req.flg)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/rmm.c (renamed from usr/src/cmd/volmgt/rmm/rmm.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/rmm_config.c (renamed from usr/src/cmd/volmgt/rmm/rmm_config.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/rmm_int.h (renamed from usr/src/cmd/volmgt/rmm/rmm_int.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/rmm/rmm_util.c (renamed from usr/src/cmd/volmgt/rmm/rmm_util.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/Makefile (renamed from usr/src/cmd/volmgt/test/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/README (renamed from usr/src/cmd/volmgt/test/README)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/devlink.vt (renamed from usr/src/cmd/volmgt/test/devlink.vt)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/stress (renamed from usr/src/cmd/volmgt/test/stress)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/test_class_list (renamed from usr/src/cmd/volmgt/test/test_class_list)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/test_suite_list (renamed from usr/src/cmd/volmgt/test/test_suite_list)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/test_utilities_list (renamed from usr/src/cmd/volmgt/test/test_utilities_list)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/voltestdrv.c (renamed from usr/src/cmd/volmgt/test/voltestdrv.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/voltestdrv.conf (renamed from usr/src/cmd/volmgt/test/voltestdrv.conf)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/voltestdrv.h (renamed from usr/src/cmd/volmgt/test/voltestdrv.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/test/vttest.c (renamed from usr/src/cmd/volmgt/test/vttest.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/Makefile (renamed from usr/src/cmd/volmgt/util/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volcancel.c (renamed from usr/src/cmd/volmgt/util/volcancel.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volck.c (renamed from usr/src/cmd/volmgt/util/volck.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volmissing.c (renamed from usr/src/cmd/volmgt/util/volmissing.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volrmmount.c (renamed from usr/src/cmd/volmgt/util/volrmmount.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volsetup (renamed from usr/src/cmd/volmgt/util/volsetup)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volstat.c (renamed from usr/src/cmd/volmgt/util/volstat.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/util/volutil.h (renamed from usr/src/cmd/volmgt/util/volutil.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/Makefile (renamed from usr/src/cmd/volmgt/vold/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/action.h (renamed from usr/src/cmd/volmgt/vold/action.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/blank_partition.c (renamed from usr/src/cmd/volmgt/vold/blank_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/db.h (renamed from usr/src/cmd/volmgt/vold/db.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/db_mem.c (renamed from usr/src/cmd/volmgt/vold/db_mem.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/db_nis.c (renamed from usr/src/cmd/volmgt/vold/db_nis.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/db_nis.h (renamed from usr/src/cmd/volmgt/vold/db_nis.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev.h (renamed from usr/src/cmd/volmgt/vold/dev.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_cdrom.c (renamed from usr/src/cmd/volmgt/vold/dev_cdrom.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_cdtest.c (renamed from usr/src/cmd/volmgt/vold/dev_cdtest.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_floppy.c (renamed from usr/src/cmd/volmgt/vold/dev_floppy.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_pcmem.c (renamed from usr/src/cmd/volmgt/vold/dev_pcmem.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_rmdisk.c (renamed from usr/src/cmd/volmgt/vold/dev_rmdisk.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_rmscsi.c (renamed from usr/src/cmd/volmgt/vold/dev_rmscsi.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/dev_test.c (renamed from usr/src/cmd/volmgt/vold/dev_test.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/fdisk_partition.c (renamed from usr/src/cmd/volmgt/vold/fdisk_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/hsfs_partition.c (renamed from usr/src/cmd/volmgt/vold/hsfs_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/label.h (renamed from usr/src/cmd/volmgt/vold/label.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/label_cdrom.c (renamed from usr/src/cmd/volmgt/vold/label_cdrom.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/label_dos.c (renamed from usr/src/cmd/volmgt/vold/label_dos.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/label_sun.c (renamed from usr/src/cmd/volmgt/vold/label_sun.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/label_test.c (renamed from usr/src/cmd/volmgt/vold/label_test.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/medium.c (renamed from usr/src/cmd/volmgt/vold/medium.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/medium.h (renamed from usr/src/cmd/volmgt/vold/medium.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/medium_private.h (renamed from usr/src/cmd/volmgt/vold/medium_private.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/name_factory.c (renamed from usr/src/cmd/volmgt/vold/name_factory.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/name_factory.h (renamed from usr/src/cmd/volmgt/vold/name_factory.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/nfs_server.c (renamed from usr/src/cmd/volmgt/vold/nfs_server.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/nfs_trace.c (renamed from usr/src/cmd/volmgt/vold/nfs_trace.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/node.h (renamed from usr/src/cmd/volmgt/vold/node.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/obj.h (renamed from usr/src/cmd/volmgt/vold/obj.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/partition.c (renamed from usr/src/cmd/volmgt/vold/partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/partition.h (renamed from usr/src/cmd/volmgt/vold/partition.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/partition_private.h (renamed from usr/src/cmd/volmgt/vold/partition_private.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/pcfs_partition.c (renamed from usr/src/cmd/volmgt/vold/pcfs_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/solaris_partition.c (renamed from usr/src/cmd/volmgt/vold/solaris_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/udfs_partition.c (renamed from usr/src/cmd/volmgt/vold/udfs_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/ufs_partition.c (renamed from usr/src/cmd/volmgt/vold/ufs_partition.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/util.h (renamed from usr/src/cmd/volmgt/vold/util.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold.h (renamed from usr/src/cmd/volmgt/vold/vold.h)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_action.c (renamed from usr/src/cmd/volmgt/vold/vold_action.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_config.c (renamed from usr/src/cmd/volmgt/vold/vold_config.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_db.c (renamed from usr/src/cmd/volmgt/vold/vold_db.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_dev.c (renamed from usr/src/cmd/volmgt/vold/vold_dev.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_err.c (renamed from usr/src/cmd/volmgt/vold/vold_err.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_label.c (renamed from usr/src/cmd/volmgt/vold/vold_label.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_main.c (renamed from usr/src/cmd/volmgt/vold/vold_main.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_mnt.c (renamed from usr/src/cmd/volmgt/vold/vold_mnt.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_node.c (renamed from usr/src/cmd/volmgt/vold/vold_node.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_obj.c (renamed from usr/src/cmd/volmgt/vold/vold_obj.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_path.c (renamed from usr/src/cmd/volmgt/vold/vold_path.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_proc.c (renamed from usr/src/cmd/volmgt/vold/vold_proc.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_props.c (renamed from usr/src/cmd/volmgt/vold/vold_props.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_sysevent.c (renamed from usr/src/cmd/volmgt/vold/vold_sysevent.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_util.c (renamed from usr/src/cmd/volmgt/vold/vold_util.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vold_vol.c (renamed from usr/src/cmd/volmgt/vold/vold_vol.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vtoc.c (renamed from usr/src/cmd/volmgt/vold/vtoc.c)0
-rw-r--r--deleted_files/usr/src/cmd/volmgt/vold/vtoc.h (renamed from usr/src/cmd/volmgt/vold/vtoc.h)0
-rw-r--r--deleted_files/usr/src/head/rmmount.h (renamed from usr/src/head/rmmount.h)0
-rw-r--r--deleted_files/usr/src/lib/libvolmgt/common/volattr.c (renamed from usr/src/lib/libvolmgt/common/volattr.c)0
-rw-r--r--deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi.c (renamed from usr/src/lib/libvolmgt/common/volmgt_fsi.c)0
-rw-r--r--deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h (renamed from usr/src/lib/libvolmgt/common/volmgt_fsi_private.h)0
-rw-r--r--deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c (renamed from usr/src/lib/libvolmgt/common/volmgt_fsidbi.c)0
-rw-r--r--deleted_files/usr/src/lib/libvolmgt/common/volname.c (renamed from usr/src/lib/libvolmgt/common/volname.c)0
-rw-r--r--deleted_files/usr/src/lib/libvolmgt/common/volutil.c (renamed from usr/src/lib/libvolmgt/common/volutil.c)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWpcmem/preinstall (renamed from usr/src/pkgdefs/SUNWpcmem/preinstall)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/Makefile (renamed from usr/src/pkgdefs/SUNWvolr/Makefile)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl (renamed from usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/postinstall (renamed from usr/src/pkgdefs/SUNWvolr/postinstall)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/preinstall (renamed from usr/src/pkgdefs/SUNWvolr/preinstall)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_com (renamed from usr/src/pkgdefs/SUNWvolr/prototype_com)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_i386 (renamed from usr/src/pkgdefs/SUNWvolr/prototype_i386)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_sparc (renamed from usr/src/pkgdefs/SUNWvolr/prototype_sparc)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/Makefile (renamed from usr/src/pkgdefs/SUNWvolu/Makefile)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/depend (renamed from usr/src/pkgdefs/SUNWvolu/depend)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl (renamed from usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/postremove (renamed from usr/src/pkgdefs/SUNWvolu/postremove)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_com (renamed from usr/src/pkgdefs/SUNWvolu/prototype_com)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_i386 (renamed from usr/src/pkgdefs/SUNWvolu/prototype_i386)0
-rw-r--r--deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_sparc (renamed from usr/src/pkgdefs/SUNWvolu/prototype_sparc)0
-rw-r--r--deleted_files/usr/src/pkgdefs/common_files/i.rmmconf (renamed from usr/src/pkgdefs/common_files/i.rmmconf)0
-rw-r--r--deleted_files/usr/src/pkgdefs/common_files/i.voldconf (renamed from usr/src/pkgdefs/common_files/i.voldconf)0
-rw-r--r--deleted_files/usr/src/uts/common/io/vol.c (renamed from usr/src/uts/common/io/vol.c)0
-rw-r--r--deleted_files/usr/src/uts/common/io/vol.conf (renamed from usr/src/uts/common/io/vol.conf)0
-rw-r--r--deleted_files/usr/src/uts/common/sys/vol.h (renamed from usr/src/uts/common/sys/vol.h)0
-rw-r--r--deleted_files/usr/src/uts/intel/vol/Makefile (renamed from usr/src/uts/intel/vol/Makefile)0
-rw-r--r--deleted_files/usr/src/uts/sparc/vol/Makefile (renamed from usr/src/uts/sparc/vol/Makefile)0
-rw-r--r--usr/src/Makefile.lint1
-rw-r--r--usr/src/Targetdirs20
-rw-r--r--usr/src/cmd/Makefile15
-rw-r--r--usr/src/cmd/bsmconv/bsmconv.sh28
-rw-r--r--usr/src/cmd/bsmrecord/audit_record_attr.txt21
-rw-r--r--usr/src/cmd/bsmunconv/bsmunconv.sh14
-rw-r--r--usr/src/cmd/devfsadm/disk_link.c15
-rw-r--r--usr/src/cmd/eject/Makefile52
-rw-r--r--usr/src/cmd/eject/eject.c726
-rw-r--r--usr/src/cmd/fs.d/hsfs/Makefile2
-rw-r--r--usr/src/cmd/fs.d/pcfs/Makefile10
-rw-r--r--usr/src/cmd/fs.d/udfs/Makefile2
-rw-r--r--usr/src/cmd/fs.d/ufs/Makefile2
-rw-r--r--usr/src/cmd/hal/LICENSE51
-rw-r--r--usr/src/cmd/hal/Makefile73
-rw-r--r--usr/src/cmd/hal/Makefile.hal63
-rw-r--r--usr/src/cmd/hal/addons/Makefile42
-rw-r--r--usr/src/cmd/hal/addons/storage/Makefile62
-rw-r--r--usr/src/cmd/hal/addons/storage/addon-storage.c357
-rw-r--r--usr/src/cmd/hal/fdi/Makefile74
-rw-r--r--usr/src/cmd/hal/fdi/README80
-rw-r--r--usr/src/cmd/hal/fdi/fdi.dtd.157
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-camera-ptp.fdi17
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-cd-dvd-burner.fdi31
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-card-readers.fdi127
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-music-players.fdi1025
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-pda.fdi117
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-zip-drives.fdi19
-rw-r--r--usr/src/cmd/hal/fdi/information/10freedesktop/10-wireless-mice.fdi127
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/10-keyboard-policy.fdi14
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi75
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi56
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi15
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/20-storage-methods.fdi207
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/20-zfs-methods.fdi21
-rw-r--r--usr/src/cmd/hal/fdi/preprobe/10osvendor/10-ide-drives.fdi70
-rw-r--r--usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-fixed-storage.fdi13
-rw-r--r--usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-lofi.fdi9
-rw-r--r--usr/src/cmd/hal/hal.conf.in67
-rw-r--r--usr/src/cmd/hal/hald-runner/Makefile58
-rw-r--r--usr/src/cmd/hal/hald-runner/main.c224
-rw-r--r--usr/src/cmd/hal/hald-runner/runner.c372
-rw-r--r--usr/src/cmd/hal/hald-runner/runner.h57
-rw-r--r--usr/src/cmd/hal/hald-runner/utils.c91
-rw-r--r--usr/src/cmd/hal/hald-runner/utils.h35
-rw-r--r--usr/src/cmd/hal/hald/Makefile91
-rw-r--r--usr/src/cmd/hal/hald/device.c1350
-rw-r--r--usr/src/cmd/hal/hald/device.h215
-rw-r--r--usr/src/cmd/hal/hald/device_info.c1648
-rw-r--r--usr/src/cmd/hal/hald/device_info.h43
-rw-r--r--usr/src/cmd/hal/hald/device_store.c493
-rw-r--r--usr/src/cmd/hal/hald/device_store.h122
-rw-r--r--usr/src/cmd/hal/hald/hald.c641
-rw-r--r--usr/src/cmd/hal/hald/hald.h65
-rw-r--r--usr/src/cmd/hal/hald/hald_dbus.c4383
-rw-r--r--usr/src/cmd/hal/hald/hald_dbus.h100
-rw-r--r--usr/src/cmd/hal/hald/hald_marshal.list6
-rw-r--r--usr/src/cmd/hal/hald/hald_runner.c593
-rw-r--r--usr/src/cmd/hal/hald/hald_runner.h82
-rw-r--r--usr/src/cmd/hal/hald/ids.c996
-rw-r--r--usr/src/cmd/hal/hald/ids.h47
-rw-r--r--usr/src/cmd/hal/hald/logger.c241
-rw-r--r--usr/src/cmd/hal/hald/logger.h86
-rw-r--r--usr/src/cmd/hal/hald/osspec.h61
-rw-r--r--usr/src/cmd/hal/hald/property.c490
-rw-r--r--usr/src/cmd/hal/hald/property.h103
-rw-r--r--usr/src/cmd/hal/hald/solaris/Makefile60
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo.c376
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo.h72
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.c84
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.h21
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_misc.c143
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_misc.h23
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_pci.c118
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_pci.h21
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_storage.c1669
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_storage.h31
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_usb.c227
-rw-r--r--usr/src/cmd/hal/hald/solaris/devinfo_usb.h21
-rw-r--r--usr/src/cmd/hal/hald/solaris/hal.xml89
-rw-r--r--usr/src/cmd/hal/hald/solaris/hotplug.c193
-rw-r--r--usr/src/cmd/hal/hald/solaris/hotplug.h60
-rw-r--r--usr/src/cmd/hal/hald/solaris/osspec.c235
-rw-r--r--usr/src/cmd/hal/hald/solaris/osspec_solaris.h23
-rwxr-xr-xusr/src/cmd/hal/hald/solaris/svc-hal39
-rw-r--r--usr/src/cmd/hal/hald/solaris/sysevent.c291
-rw-r--r--usr/src/cmd/hal/hald/solaris/sysevent.h22
-rw-r--r--usr/src/cmd/hal/hald/util.c1097
-rw-r--r--usr/src/cmd/hal/hald/util.h112
-rw-r--r--usr/src/cmd/hal/hald/util_helper.c188
-rw-r--r--usr/src/cmd/hal/hald/util_helper.h33
-rw-r--r--usr/src/cmd/hal/hald/util_pm.c227
-rw-r--r--usr/src/cmd/hal/hald/util_pm.h37
-rw-r--r--usr/src/cmd/hal/inc.flg34
-rw-r--r--usr/src/cmd/hal/probing/Makefile42
-rw-r--r--usr/src/cmd/hal/probing/storage/Makefile71
-rw-r--r--usr/src/cmd/hal/probing/storage/probe-storage.c488
-rw-r--r--usr/src/cmd/hal/probing/volume/Makefile71
-rw-r--r--usr/src/cmd/hal/probing/volume/probe-volume.c569
-rw-r--r--usr/src/cmd/hal/tools/Makefile146
-rw-r--r--usr/src/cmd/hal/tools/hal-device.c652
-rw-r--r--usr/src/cmd/hal/tools/hal-fdi-validate.sh32
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-cleanup-all-mountpoints.c180
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-cleanup-mountpoint.c192
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-closetray.c178
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-eject.c236
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-mount.c1156
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-shared.c838
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-shared.h81
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-unmount.c212
-rw-r--r--usr/src/cmd/hal/tools/hal-storage-zpool.c255
-rw-r--r--usr/src/cmd/hal/tools/hal_find_by_capability.c186
-rw-r--r--usr/src/cmd/hal/tools/hal_find_by_property.c193
-rw-r--r--usr/src/cmd/hal/tools/hal_get_property.c250
-rw-r--r--usr/src/cmd/hal/tools/hal_set_property.c288
-rw-r--r--usr/src/cmd/hal/tools/lshal.c737
-rw-r--r--usr/src/cmd/hal/utils/cdutils.c484
-rw-r--r--usr/src/cmd/hal/utils/cdutils.h61
-rw-r--r--usr/src/cmd/hal/utils/fsutils.c250
-rw-r--r--usr/src/cmd/hal/utils/fsutils.h28
-rw-r--r--usr/src/cmd/hwdata/Makefile47
-rw-r--r--usr/src/cmd/hwdata/pci.ids12419
-rw-r--r--usr/src/cmd/hwdata/usb.ids5959
-rw-r--r--usr/src/cmd/initpkg/init.d/Makefile1
-rw-r--r--usr/src/cmd/login/logindevperm.sh4
-rw-r--r--usr/src/cmd/pgrep/pgrep.c24
-rw-r--r--usr/src/cmd/policykit/Makefile55
-rw-r--r--usr/src/cmd/policykit/polkit-is-privileged.c205
-rw-r--r--usr/src/cmd/rmmount/Makefile71
-rw-r--r--usr/src/cmd/rmmount/rmmount.c274
-rw-r--r--usr/src/cmd/rmvolmgr/Makefile72
-rw-r--r--usr/src/cmd/rmvolmgr/rmm_common.c1355
-rw-r--r--usr/src/cmd/rmvolmgr/rmm_common.h106
-rw-r--r--usr/src/cmd/rmvolmgr/rmvolmgr.c607
-rw-r--r--usr/src/cmd/rmvolmgr/rmvolmgr.xml118
-rw-r--r--usr/src/cmd/rmvolmgr/svc-rmvolmgr56
-rw-r--r--usr/src/cmd/rmvolmgr/vold.c1089
-rw-r--r--usr/src/cmd/rmvolmgr/vold.h73
-rw-r--r--usr/src/cmd/smserverd/smserver.xml9
-rw-r--r--usr/src/cmd/svc/profile/generic_limited_net.xml5
-rw-r--r--usr/src/cmd/svc/profile/generic_open.xml5
-rw-r--r--usr/src/cmd/truss/codes.c25
-rw-r--r--usr/src/cmd/volcheck/Makefile67
-rw-r--r--usr/src/cmd/volcheck/volcheck.c108
-rw-r--r--usr/src/cmd/volmgt/util/eject.c1275
-rw-r--r--usr/src/cmd/volmgt/util/volcheck.c214
-rw-r--r--usr/src/cmd/volrmmount/Makefile67
-rw-r--r--usr/src/cmd/volrmmount/volrmmount.c153
-rw-r--r--usr/src/head/Makefile1
-rw-r--r--usr/src/lib/Makefile4
-rw-r--r--usr/src/lib/hal/Makefile56
-rw-r--r--usr/src/lib/hal/Makefile.com55
-rw-r--r--usr/src/lib/hal/libhal-storage/Makefile52
-rw-r--r--usr/src/lib/hal/libhal-storage/Makefile.com61
-rw-r--r--usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in19
-rw-r--r--usr/src/lib/hal/libhal-storage/common/libhal-storage.c2037
-rw-r--r--usr/src/lib/hal/libhal-storage/common/libhal-storage.h362
-rw-r--r--usr/src/lib/hal/libhal-storage/common/llib-lhal-storage30
-rw-r--r--usr/src/lib/hal/libhal-storage/common/mapfile-vers120
-rw-r--r--usr/src/lib/hal/libhal-storage/i386/Makefile30
-rw-r--r--usr/src/lib/hal/libhal-storage/sparc/Makefile30
-rw-r--r--usr/src/lib/hal/libhal/Makefile52
-rw-r--r--usr/src/lib/hal/libhal/Makefile.com57
-rw-r--r--usr/src/lib/hal/libhal/common/hal.pc.in19
-rw-r--r--usr/src/lib/hal/libhal/common/libhal.c3992
-rw-r--r--usr/src/lib/hal/libhal/common/libhal.h604
-rw-r--r--usr/src/lib/hal/libhal/common/llib-lhal30
-rw-r--r--usr/src/lib/hal/libhal/common/mapfile-vers119
-rw-r--r--usr/src/lib/hal/libhal/i386/Makefile30
-rw-r--r--usr/src/lib/hal/libhal/sparc/Makefile30
-rw-r--r--usr/src/lib/libbsm/audit_event.txt5
-rw-r--r--usr/src/lib/libbsm/common/adt_event.h47
-rw-r--r--usr/src/lib/libbsm/common/adt_xlate.c111
-rw-r--r--usr/src/lib/libbsm/common/adt_xml.txt108
-rw-r--r--usr/src/lib/libdevinfo/devinfo_devperm.c26
-rw-r--r--usr/src/lib/libdiskmgt/Makefile.com2
-rw-r--r--usr/src/lib/libdiskmgt/common/disks_private.h8
-rw-r--r--usr/src/lib/libdiskmgt/common/drive.c96
-rw-r--r--usr/src/lib/libdiskmgt/common/findevs.c16
-rw-r--r--usr/src/lib/libdiskmgt/common/media.c120
-rw-r--r--usr/src/lib/libdiskmgt/common/partition.c90
-rw-r--r--usr/src/lib/libdiskmgt/common/slice.c493
-rw-r--r--usr/src/lib/libsecdb/auth_attr.txt7
-rw-r--r--usr/src/lib/libsecdb/prof_attr.txt6
-rw-r--r--usr/src/lib/libvolmgt/Makefile.com3
-rw-r--r--usr/src/lib/libvolmgt/common/llib-lvolmgt10
-rw-r--r--usr/src/lib/libvolmgt/common/volmgt.c631
-rw-r--r--usr/src/lib/libvolmgt/common/volmgt_on_private.c144
-rw-r--r--usr/src/lib/libvolmgt/common/volmgt_private.h16
-rw-r--r--usr/src/lib/libvolmgt/common/volprivate.c144
-rw-r--r--usr/src/lib/policykit/Makefile56
-rw-r--r--usr/src/lib/policykit/Makefile.com54
-rw-r--r--usr/src/lib/policykit/Makefile.policykit36
-rw-r--r--usr/src/lib/policykit/libpolkit/Makefile52
-rw-r--r--usr/src/lib/policykit/libpolkit/Makefile.com59
-rw-r--r--usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c204
-rw-r--r--usr/src/lib/policykit/libpolkit/common/libpolkit.h77
-rw-r--r--usr/src/lib/policykit/libpolkit/common/llib-lpolkit30
-rw-r--r--usr/src/lib/policykit/libpolkit/common/mapfile-vers43
-rw-r--r--usr/src/lib/policykit/libpolkit/common/polkit.pc.in19
-rw-r--r--usr/src/lib/policykit/libpolkit/i386/Makefile30
-rw-r--r--usr/src/lib/policykit/libpolkit/sparc/Makefile30
-rw-r--r--usr/src/pkgdefs/Makefile10
-rw-r--r--usr/src/pkgdefs/SUNWcsr/Makefile5
-rw-r--r--usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl2
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_com7
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com4
-rw-r--r--usr/src/pkgdefs/SUNWesu/prototype_com1
-rw-r--r--usr/src/pkgdefs/SUNWhal/Makefile35
-rw-r--r--usr/src/pkgdefs/SUNWhal/depend61
-rw-r--r--usr/src/pkgdefs/SUNWhal/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWhal/prototype_com87
-rw-r--r--usr/src/pkgdefs/SUNWhal/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWhal/prototype_sparc49
-rw-r--r--usr/src/pkgdefs/SUNWhalr/Makefile37
-rw-r--r--usr/src/pkgdefs/SUNWhalr/depend55
-rw-r--r--usr/src/pkgdefs/SUNWhalr/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWhalr/postinstall46
-rw-r--r--usr/src/pkgdefs/SUNWhalr/preinstall38
-rw-r--r--usr/src/pkgdefs/SUNWhalr/prototype_com92
-rw-r--r--usr/src/pkgdefs/SUNWhalr/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWhalr/prototype_sparc49
-rw-r--r--usr/src/pkgdefs/SUNWhea/prototype_com7
-rw-r--r--usr/src/pkgdefs/SUNWhwdata/Makefile36
-rw-r--r--usr/src/pkgdefs/SUNWhwdata/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWhwdata/prototype_com50
-rw-r--r--usr/src/pkgdefs/SUNWhwdata/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWhwdata/prototype_sparc49
-rw-r--r--usr/src/pkgdefs/SUNWpcmem/postinstall103
-rw-r--r--usr/src/pkgdefs/SUNWpcmem/preremove65
-rw-r--r--usr/src/pkgdefs/SUNWpcmem/prototype_com10
-rw-r--r--usr/src/pkgdefs/SUNWpolkit/Makefile35
-rw-r--r--usr/src/pkgdefs/SUNWpolkit/depend56
-rw-r--r--usr/src/pkgdefs/SUNWpolkit/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWpolkit/prototype_com56
-rw-r--r--usr/src/pkgdefs/SUNWpolkit/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWpolkit/prototype_sparc49
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgr/Makefile35
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgr/depend57
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgr/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgr/prototype_com56
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgr/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgr/prototype_sparc48
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/Makefile37
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/depend56
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/postinstall45
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/preinstall38
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/prototype_com59
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWrmvolmgrr/prototype_sparc49
-rw-r--r--usr/src/pkgdefs/SUNWsmedia/Makefile36
-rw-r--r--usr/src/pkgdefs/SUNWsmedia/depend54
-rw-r--r--usr/src/pkgdefs/SUNWsmedia/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWsmedia/prototype_com57
-rw-r--r--usr/src/pkgdefs/SUNWsmedia/prototype_i38659
-rw-r--r--usr/src/pkgdefs/SUNWsmedia/prototype_sparc59
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/Makefile38
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/postinstall50
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/preinstall38
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/prototype_com55
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/prototype_i38649
-rw-r--r--usr/src/pkgdefs/SUNWsmediar/prototype_sparc49
-rw-r--r--usr/src/pkgdefs/SUNWudf/prototype_com1
-rw-r--r--usr/src/pkgdefs/common_files/i.logindevperm90
-rw-r--r--usr/src/tools/scripts/bfu.sh58
-rw-r--r--usr/src/tools/scripts/check_rtime.pl4
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/fs/pcfs/pc_vfsops.c12
-rw-r--r--usr/src/uts/common/io/lofi.c5
-rw-r--r--usr/src/uts/common/io/ramdisk.c12
-rw-r--r--usr/src/uts/common/io/scsi/targets/sd.c43
-rw-r--r--usr/src/uts/common/sys/Makefile1
-rw-r--r--usr/src/uts/intel/Makefile.intel.shared1
-rw-r--r--usr/src/uts/intel/os/name_to_major1
-rw-r--r--usr/src/uts/sparc/Makefile.sparc.shared2
-rw-r--r--usr/src/uts/sparc/os/name_to_major1
413 files changed, 65094 insertions, 2941 deletions
diff --git a/usr/src/cmd/fs.d/hsfs/ident/Makefile b/deleted_files/usr/src/cmd/fs.d/hsfs/ident/Makefile
index 075343c167..075343c167 100644
--- a/usr/src/cmd/fs.d/hsfs/ident/Makefile
+++ b/deleted_files/usr/src/cmd/fs.d/hsfs/ident/Makefile
diff --git a/usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c b/deleted_files/usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c
index f9aaf1d58b..f9aaf1d58b 100644
--- a/usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c
+++ b/deleted_files/usr/src/cmd/fs.d/hsfs/ident/ident_hsfs.c
diff --git a/usr/src/cmd/fs.d/pcfs/ident/Makefile b/deleted_files/usr/src/cmd/fs.d/pcfs/ident/Makefile
index 9118659b16..9118659b16 100644
--- a/usr/src/cmd/fs.d/pcfs/ident/Makefile
+++ b/deleted_files/usr/src/cmd/fs.d/pcfs/ident/Makefile
diff --git a/usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c b/deleted_files/usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c
index 7e720e7d24..7e720e7d24 100644
--- a/usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c
+++ b/deleted_files/usr/src/cmd/fs.d/pcfs/ident/ident_pcfs.c
diff --git a/usr/src/cmd/fs.d/udfs/ident/Makefile b/deleted_files/usr/src/cmd/fs.d/udfs/ident/Makefile
index f326e6a8d4..f326e6a8d4 100644
--- a/usr/src/cmd/fs.d/udfs/ident/Makefile
+++ b/deleted_files/usr/src/cmd/fs.d/udfs/ident/Makefile
diff --git a/usr/src/cmd/fs.d/udfs/ident/ident_udfs.c b/deleted_files/usr/src/cmd/fs.d/udfs/ident/ident_udfs.c
index 40b7d064e4..40b7d064e4 100644
--- a/usr/src/cmd/fs.d/udfs/ident/ident_udfs.c
+++ b/deleted_files/usr/src/cmd/fs.d/udfs/ident/ident_udfs.c
diff --git a/usr/src/cmd/fs.d/ufs/ident/Makefile b/deleted_files/usr/src/cmd/fs.d/ufs/ident/Makefile
index bd93aa9571..bd93aa9571 100644
--- a/usr/src/cmd/fs.d/ufs/ident/Makefile
+++ b/deleted_files/usr/src/cmd/fs.d/ufs/ident/Makefile
diff --git a/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c b/deleted_files/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c
index 4a6a1d2cf9..4a6a1d2cf9 100644
--- a/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c
+++ b/deleted_files/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c
diff --git a/usr/src/cmd/initpkg/init.d/volmgt b/deleted_files/usr/src/cmd/initpkg/init.d/volmgt
index e7a155f89e..e7a155f89e 100644
--- a/usr/src/cmd/initpkg/init.d/volmgt
+++ b/deleted_files/usr/src/cmd/initpkg/init.d/volmgt
diff --git a/usr/src/cmd/volmgt/Makefile b/deleted_files/usr/src/cmd/volmgt/Makefile
index 0c911856bc..0c911856bc 100644
--- a/usr/src/cmd/volmgt/Makefile
+++ b/deleted_files/usr/src/cmd/volmgt/Makefile
diff --git a/usr/src/cmd/volmgt/Makefile.volmgt b/deleted_files/usr/src/cmd/volmgt/Makefile.volmgt
index 56a9e93bbf..56a9e93bbf 100644
--- a/usr/src/cmd/volmgt/Makefile.volmgt
+++ b/deleted_files/usr/src/cmd/volmgt/Makefile.volmgt
diff --git a/usr/src/cmd/volmgt/etc/Makefile b/deleted_files/usr/src/cmd/volmgt/etc/Makefile
index 27cb690c94..27cb690c94 100644
--- a/usr/src/cmd/volmgt/etc/Makefile
+++ b/deleted_files/usr/src/cmd/volmgt/etc/Makefile
diff --git a/usr/src/cmd/volmgt/etc/rmmount.conf b/deleted_files/usr/src/cmd/volmgt/etc/rmmount.conf
index dc946b8871..dc946b8871 100644
--- a/usr/src/cmd/volmgt/etc/rmmount.conf
+++ b/deleted_files/usr/src/cmd/volmgt/etc/rmmount.conf
diff --git a/usr/src/cmd/volmgt/etc/svc-volfs b/deleted_files/usr/src/cmd/volmgt/etc/svc-volfs
index 17d4d7235c..17d4d7235c 100644
--- a/usr/src/cmd/volmgt/etc/svc-volfs
+++ b/deleted_files/usr/src/cmd/volmgt/etc/svc-volfs
diff --git a/usr/src/cmd/volmgt/etc/vold.conf b/deleted_files/usr/src/cmd/volmgt/etc/vold.conf
index 84a2181b8f..84a2181b8f 100644
--- a/usr/src/cmd/volmgt/etc/vold.conf
+++ b/deleted_files/usr/src/cmd/volmgt/etc/vold.conf
diff --git a/usr/src/cmd/volmgt/etc/volfs.xml b/deleted_files/usr/src/cmd/volmgt/etc/volfs.xml
index 995e309b5f..995e309b5f 100644
--- a/usr/src/cmd/volmgt/etc/volfs.xml
+++ b/deleted_files/usr/src/cmd/volmgt/etc/volfs.xml
diff --git a/usr/src/cmd/volmgt/req.flg b/deleted_files/usr/src/cmd/volmgt/req.flg
index ae2d8525f4..ae2d8525f4 100644
--- a/usr/src/cmd/volmgt/req.flg
+++ b/deleted_files/usr/src/cmd/volmgt/req.flg
diff --git a/usr/src/cmd/volmgt/rmm/Makefile b/deleted_files/usr/src/cmd/volmgt/rmm/Makefile
index 150a98ce17..150a98ce17 100644
--- a/usr/src/cmd/volmgt/rmm/Makefile
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/Makefile
diff --git a/usr/src/cmd/volmgt/rmm/action_dvdvideo.c b/deleted_files/usr/src/cmd/volmgt/rmm/action_dvdvideo.c
index 23a826b792..23a826b792 100644
--- a/usr/src/cmd/volmgt/rmm/action_dvdvideo.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/action_dvdvideo.c
diff --git a/usr/src/cmd/volmgt/rmm/action_filemgr.c b/deleted_files/usr/src/cmd/volmgt/rmm/action_filemgr.c
index c2d86e21b7..c2d86e21b7 100644
--- a/usr/src/cmd/volmgt/rmm/action_filemgr.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/action_filemgr.c
diff --git a/usr/src/cmd/volmgt/rmm/action_test.c b/deleted_files/usr/src/cmd/volmgt/rmm/action_test.c
index 8bdf766bbc..8bdf766bbc 100644
--- a/usr/src/cmd/volmgt/rmm/action_test.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/action_test.c
diff --git a/usr/src/cmd/volmgt/rmm/action_wabi.c b/deleted_files/usr/src/cmd/volmgt/rmm/action_wabi.c
index 76fe9901f0..76fe9901f0 100644
--- a/usr/src/cmd/volmgt/rmm/action_wabi.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/action_wabi.c
diff --git a/usr/src/cmd/volmgt/rmm/action_workman.c b/deleted_files/usr/src/cmd/volmgt/rmm/action_workman.c
index a51e05b9a4..a51e05b9a4 100644
--- a/usr/src/cmd/volmgt/rmm/action_workman.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/action_workman.c
diff --git a/usr/src/cmd/volmgt/rmm/action_xmcd.c b/deleted_files/usr/src/cmd/volmgt/rmm/action_xmcd.c
index 192dababcd..192dababcd 100644
--- a/usr/src/cmd/volmgt/rmm/action_xmcd.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/action_xmcd.c
diff --git a/usr/src/cmd/volmgt/rmm/req.flg b/deleted_files/usr/src/cmd/volmgt/rmm/req.flg
index a354bee79a..a354bee79a 100644
--- a/usr/src/cmd/volmgt/rmm/req.flg
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/req.flg
diff --git a/usr/src/cmd/volmgt/rmm/rmm.c b/deleted_files/usr/src/cmd/volmgt/rmm/rmm.c
index 630392553e..630392553e 100644
--- a/usr/src/cmd/volmgt/rmm/rmm.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/rmm.c
diff --git a/usr/src/cmd/volmgt/rmm/rmm_config.c b/deleted_files/usr/src/cmd/volmgt/rmm/rmm_config.c
index c84e2df636..c84e2df636 100644
--- a/usr/src/cmd/volmgt/rmm/rmm_config.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/rmm_config.c
diff --git a/usr/src/cmd/volmgt/rmm/rmm_int.h b/deleted_files/usr/src/cmd/volmgt/rmm/rmm_int.h
index 86e675585f..86e675585f 100644
--- a/usr/src/cmd/volmgt/rmm/rmm_int.h
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/rmm_int.h
diff --git a/usr/src/cmd/volmgt/rmm/rmm_util.c b/deleted_files/usr/src/cmd/volmgt/rmm/rmm_util.c
index 4133c470a9..4133c470a9 100644
--- a/usr/src/cmd/volmgt/rmm/rmm_util.c
+++ b/deleted_files/usr/src/cmd/volmgt/rmm/rmm_util.c
diff --git a/usr/src/cmd/volmgt/test/Makefile b/deleted_files/usr/src/cmd/volmgt/test/Makefile
index 56c3f26236..56c3f26236 100644
--- a/usr/src/cmd/volmgt/test/Makefile
+++ b/deleted_files/usr/src/cmd/volmgt/test/Makefile
diff --git a/usr/src/cmd/volmgt/test/README b/deleted_files/usr/src/cmd/volmgt/test/README
index a5a7d5c067..a5a7d5c067 100644
--- a/usr/src/cmd/volmgt/test/README
+++ b/deleted_files/usr/src/cmd/volmgt/test/README
diff --git a/usr/src/cmd/volmgt/test/devlink.vt b/deleted_files/usr/src/cmd/volmgt/test/devlink.vt
index 24aacab87a..24aacab87a 100644
--- a/usr/src/cmd/volmgt/test/devlink.vt
+++ b/deleted_files/usr/src/cmd/volmgt/test/devlink.vt
diff --git a/usr/src/cmd/volmgt/test/stress b/deleted_files/usr/src/cmd/volmgt/test/stress
index 1d369bbd97..1d369bbd97 100644
--- a/usr/src/cmd/volmgt/test/stress
+++ b/deleted_files/usr/src/cmd/volmgt/test/stress
diff --git a/usr/src/cmd/volmgt/test/test_class_list b/deleted_files/usr/src/cmd/volmgt/test/test_class_list
index 4344096171..4344096171 100644
--- a/usr/src/cmd/volmgt/test/test_class_list
+++ b/deleted_files/usr/src/cmd/volmgt/test/test_class_list
diff --git a/usr/src/cmd/volmgt/test/test_suite_list b/deleted_files/usr/src/cmd/volmgt/test/test_suite_list
index ae64ab5dda..ae64ab5dda 100644
--- a/usr/src/cmd/volmgt/test/test_suite_list
+++ b/deleted_files/usr/src/cmd/volmgt/test/test_suite_list
diff --git a/usr/src/cmd/volmgt/test/test_utilities_list b/deleted_files/usr/src/cmd/volmgt/test/test_utilities_list
index 9bf91e0d20..9bf91e0d20 100644
--- a/usr/src/cmd/volmgt/test/test_utilities_list
+++ b/deleted_files/usr/src/cmd/volmgt/test/test_utilities_list
diff --git a/usr/src/cmd/volmgt/test/voltestdrv.c b/deleted_files/usr/src/cmd/volmgt/test/voltestdrv.c
index 1c9fe7ea35..1c9fe7ea35 100644
--- a/usr/src/cmd/volmgt/test/voltestdrv.c
+++ b/deleted_files/usr/src/cmd/volmgt/test/voltestdrv.c
diff --git a/usr/src/cmd/volmgt/test/voltestdrv.conf b/deleted_files/usr/src/cmd/volmgt/test/voltestdrv.conf
index e0654f6571..e0654f6571 100644
--- a/usr/src/cmd/volmgt/test/voltestdrv.conf
+++ b/deleted_files/usr/src/cmd/volmgt/test/voltestdrv.conf
diff --git a/usr/src/cmd/volmgt/test/voltestdrv.h b/deleted_files/usr/src/cmd/volmgt/test/voltestdrv.h
index c3a5987d33..c3a5987d33 100644
--- a/usr/src/cmd/volmgt/test/voltestdrv.h
+++ b/deleted_files/usr/src/cmd/volmgt/test/voltestdrv.h
diff --git a/usr/src/cmd/volmgt/test/vttest.c b/deleted_files/usr/src/cmd/volmgt/test/vttest.c
index b97658f802..b97658f802 100644
--- a/usr/src/cmd/volmgt/test/vttest.c
+++ b/deleted_files/usr/src/cmd/volmgt/test/vttest.c
diff --git a/usr/src/cmd/volmgt/util/Makefile b/deleted_files/usr/src/cmd/volmgt/util/Makefile
index fbc549d34f..fbc549d34f 100644
--- a/usr/src/cmd/volmgt/util/Makefile
+++ b/deleted_files/usr/src/cmd/volmgt/util/Makefile
diff --git a/usr/src/cmd/volmgt/util/volcancel.c b/deleted_files/usr/src/cmd/volmgt/util/volcancel.c
index 8e36272ff5..8e36272ff5 100644
--- a/usr/src/cmd/volmgt/util/volcancel.c
+++ b/deleted_files/usr/src/cmd/volmgt/util/volcancel.c
diff --git a/usr/src/cmd/volmgt/util/volck.c b/deleted_files/usr/src/cmd/volmgt/util/volck.c
index 26abd29c98..26abd29c98 100644
--- a/usr/src/cmd/volmgt/util/volck.c
+++ b/deleted_files/usr/src/cmd/volmgt/util/volck.c
diff --git a/usr/src/cmd/volmgt/util/volmissing.c b/deleted_files/usr/src/cmd/volmgt/util/volmissing.c
index 085b13065d..085b13065d 100644
--- a/usr/src/cmd/volmgt/util/volmissing.c
+++ b/deleted_files/usr/src/cmd/volmgt/util/volmissing.c
diff --git a/usr/src/cmd/volmgt/util/volrmmount.c b/deleted_files/usr/src/cmd/volmgt/util/volrmmount.c
index d5009957f5..d5009957f5 100644
--- a/usr/src/cmd/volmgt/util/volrmmount.c
+++ b/deleted_files/usr/src/cmd/volmgt/util/volrmmount.c
diff --git a/usr/src/cmd/volmgt/util/volsetup b/deleted_files/usr/src/cmd/volmgt/util/volsetup
index e6b03c4e24..e6b03c4e24 100644
--- a/usr/src/cmd/volmgt/util/volsetup
+++ b/deleted_files/usr/src/cmd/volmgt/util/volsetup
diff --git a/usr/src/cmd/volmgt/util/volstat.c b/deleted_files/usr/src/cmd/volmgt/util/volstat.c
index 968e4d19a5..968e4d19a5 100644
--- a/usr/src/cmd/volmgt/util/volstat.c
+++ b/deleted_files/usr/src/cmd/volmgt/util/volstat.c
diff --git a/usr/src/cmd/volmgt/util/volutil.h b/deleted_files/usr/src/cmd/volmgt/util/volutil.h
index 396d21d368..396d21d368 100644
--- a/usr/src/cmd/volmgt/util/volutil.h
+++ b/deleted_files/usr/src/cmd/volmgt/util/volutil.h
diff --git a/usr/src/cmd/volmgt/vold/Makefile b/deleted_files/usr/src/cmd/volmgt/vold/Makefile
index 0cc8d97806..0cc8d97806 100644
--- a/usr/src/cmd/volmgt/vold/Makefile
+++ b/deleted_files/usr/src/cmd/volmgt/vold/Makefile
diff --git a/usr/src/cmd/volmgt/vold/action.h b/deleted_files/usr/src/cmd/volmgt/vold/action.h
index bea76d694b..bea76d694b 100644
--- a/usr/src/cmd/volmgt/vold/action.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/action.h
diff --git a/usr/src/cmd/volmgt/vold/blank_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/blank_partition.c
index 6cec1ea1e2..6cec1ea1e2 100644
--- a/usr/src/cmd/volmgt/vold/blank_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/blank_partition.c
diff --git a/usr/src/cmd/volmgt/vold/db.h b/deleted_files/usr/src/cmd/volmgt/vold/db.h
index c76afce776..c76afce776 100644
--- a/usr/src/cmd/volmgt/vold/db.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/db.h
diff --git a/usr/src/cmd/volmgt/vold/db_mem.c b/deleted_files/usr/src/cmd/volmgt/vold/db_mem.c
index 1890b0650a..1890b0650a 100644
--- a/usr/src/cmd/volmgt/vold/db_mem.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/db_mem.c
diff --git a/usr/src/cmd/volmgt/vold/db_nis.c b/deleted_files/usr/src/cmd/volmgt/vold/db_nis.c
index 6699792bf4..6699792bf4 100644
--- a/usr/src/cmd/volmgt/vold/db_nis.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/db_nis.c
diff --git a/usr/src/cmd/volmgt/vold/db_nis.h b/deleted_files/usr/src/cmd/volmgt/vold/db_nis.h
index 8f249262d0..8f249262d0 100644
--- a/usr/src/cmd/volmgt/vold/db_nis.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/db_nis.h
diff --git a/usr/src/cmd/volmgt/vold/dev.h b/deleted_files/usr/src/cmd/volmgt/vold/dev.h
index a5a78943a3..a5a78943a3 100644
--- a/usr/src/cmd/volmgt/vold/dev.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev.h
diff --git a/usr/src/cmd/volmgt/vold/dev_cdrom.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_cdrom.c
index 658c317f57..658c317f57 100644
--- a/usr/src/cmd/volmgt/vold/dev_cdrom.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_cdrom.c
diff --git a/usr/src/cmd/volmgt/vold/dev_cdtest.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_cdtest.c
index 2c15b2604a..2c15b2604a 100644
--- a/usr/src/cmd/volmgt/vold/dev_cdtest.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_cdtest.c
diff --git a/usr/src/cmd/volmgt/vold/dev_floppy.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_floppy.c
index d40013fbac..d40013fbac 100644
--- a/usr/src/cmd/volmgt/vold/dev_floppy.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_floppy.c
diff --git a/usr/src/cmd/volmgt/vold/dev_pcmem.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_pcmem.c
index 4ef211aeab..4ef211aeab 100644
--- a/usr/src/cmd/volmgt/vold/dev_pcmem.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_pcmem.c
diff --git a/usr/src/cmd/volmgt/vold/dev_rmdisk.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_rmdisk.c
index 99fb721d57..99fb721d57 100644
--- a/usr/src/cmd/volmgt/vold/dev_rmdisk.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_rmdisk.c
diff --git a/usr/src/cmd/volmgt/vold/dev_rmscsi.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_rmscsi.c
index febd7ed8c1..febd7ed8c1 100644
--- a/usr/src/cmd/volmgt/vold/dev_rmscsi.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_rmscsi.c
diff --git a/usr/src/cmd/volmgt/vold/dev_test.c b/deleted_files/usr/src/cmd/volmgt/vold/dev_test.c
index 217fb2ba09..217fb2ba09 100644
--- a/usr/src/cmd/volmgt/vold/dev_test.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/dev_test.c
diff --git a/usr/src/cmd/volmgt/vold/fdisk_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/fdisk_partition.c
index 001de14d9c..001de14d9c 100644
--- a/usr/src/cmd/volmgt/vold/fdisk_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/fdisk_partition.c
diff --git a/usr/src/cmd/volmgt/vold/hsfs_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/hsfs_partition.c
index 03dbf37c32..03dbf37c32 100644
--- a/usr/src/cmd/volmgt/vold/hsfs_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/hsfs_partition.c
diff --git a/usr/src/cmd/volmgt/vold/label.h b/deleted_files/usr/src/cmd/volmgt/vold/label.h
index 6ae2dd02e6..6ae2dd02e6 100644
--- a/usr/src/cmd/volmgt/vold/label.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/label.h
diff --git a/usr/src/cmd/volmgt/vold/label_cdrom.c b/deleted_files/usr/src/cmd/volmgt/vold/label_cdrom.c
index e1caa25390..e1caa25390 100644
--- a/usr/src/cmd/volmgt/vold/label_cdrom.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/label_cdrom.c
diff --git a/usr/src/cmd/volmgt/vold/label_dos.c b/deleted_files/usr/src/cmd/volmgt/vold/label_dos.c
index c8714e52c2..c8714e52c2 100644
--- a/usr/src/cmd/volmgt/vold/label_dos.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/label_dos.c
diff --git a/usr/src/cmd/volmgt/vold/label_sun.c b/deleted_files/usr/src/cmd/volmgt/vold/label_sun.c
index be8fb5e6b8..be8fb5e6b8 100644
--- a/usr/src/cmd/volmgt/vold/label_sun.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/label_sun.c
diff --git a/usr/src/cmd/volmgt/vold/label_test.c b/deleted_files/usr/src/cmd/volmgt/vold/label_test.c
index 0e1b478b1e..0e1b478b1e 100644
--- a/usr/src/cmd/volmgt/vold/label_test.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/label_test.c
diff --git a/usr/src/cmd/volmgt/vold/medium.c b/deleted_files/usr/src/cmd/volmgt/vold/medium.c
index 0d15f16b54..0d15f16b54 100644
--- a/usr/src/cmd/volmgt/vold/medium.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/medium.c
diff --git a/usr/src/cmd/volmgt/vold/medium.h b/deleted_files/usr/src/cmd/volmgt/vold/medium.h
index 526f13e797..526f13e797 100644
--- a/usr/src/cmd/volmgt/vold/medium.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/medium.h
diff --git a/usr/src/cmd/volmgt/vold/medium_private.h b/deleted_files/usr/src/cmd/volmgt/vold/medium_private.h
index be7da1ae01..be7da1ae01 100644
--- a/usr/src/cmd/volmgt/vold/medium_private.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/medium_private.h
diff --git a/usr/src/cmd/volmgt/vold/name_factory.c b/deleted_files/usr/src/cmd/volmgt/vold/name_factory.c
index 8503d16f9f..8503d16f9f 100644
--- a/usr/src/cmd/volmgt/vold/name_factory.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/name_factory.c
diff --git a/usr/src/cmd/volmgt/vold/name_factory.h b/deleted_files/usr/src/cmd/volmgt/vold/name_factory.h
index 5751cbc80a..5751cbc80a 100644
--- a/usr/src/cmd/volmgt/vold/name_factory.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/name_factory.h
diff --git a/usr/src/cmd/volmgt/vold/nfs_server.c b/deleted_files/usr/src/cmd/volmgt/vold/nfs_server.c
index 5803afe678..5803afe678 100644
--- a/usr/src/cmd/volmgt/vold/nfs_server.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/nfs_server.c
diff --git a/usr/src/cmd/volmgt/vold/nfs_trace.c b/deleted_files/usr/src/cmd/volmgt/vold/nfs_trace.c
index ecf854979c..ecf854979c 100644
--- a/usr/src/cmd/volmgt/vold/nfs_trace.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/nfs_trace.c
diff --git a/usr/src/cmd/volmgt/vold/node.h b/deleted_files/usr/src/cmd/volmgt/vold/node.h
index 2eafe1fd59..2eafe1fd59 100644
--- a/usr/src/cmd/volmgt/vold/node.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/node.h
diff --git a/usr/src/cmd/volmgt/vold/obj.h b/deleted_files/usr/src/cmd/volmgt/vold/obj.h
index 7441314290..7441314290 100644
--- a/usr/src/cmd/volmgt/vold/obj.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/obj.h
diff --git a/usr/src/cmd/volmgt/vold/partition.c b/deleted_files/usr/src/cmd/volmgt/vold/partition.c
index 0073b7c40e..0073b7c40e 100644
--- a/usr/src/cmd/volmgt/vold/partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/partition.c
diff --git a/usr/src/cmd/volmgt/vold/partition.h b/deleted_files/usr/src/cmd/volmgt/vold/partition.h
index 9cab616ceb..9cab616ceb 100644
--- a/usr/src/cmd/volmgt/vold/partition.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/partition.h
diff --git a/usr/src/cmd/volmgt/vold/partition_private.h b/deleted_files/usr/src/cmd/volmgt/vold/partition_private.h
index adf0ad657c..adf0ad657c 100644
--- a/usr/src/cmd/volmgt/vold/partition_private.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/partition_private.h
diff --git a/usr/src/cmd/volmgt/vold/pcfs_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/pcfs_partition.c
index 5cd91bf037..5cd91bf037 100644
--- a/usr/src/cmd/volmgt/vold/pcfs_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/pcfs_partition.c
diff --git a/usr/src/cmd/volmgt/vold/solaris_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/solaris_partition.c
index 3d2577b85d..3d2577b85d 100644
--- a/usr/src/cmd/volmgt/vold/solaris_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/solaris_partition.c
diff --git a/usr/src/cmd/volmgt/vold/udfs_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/udfs_partition.c
index f997debb63..f997debb63 100644
--- a/usr/src/cmd/volmgt/vold/udfs_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/udfs_partition.c
diff --git a/usr/src/cmd/volmgt/vold/ufs_partition.c b/deleted_files/usr/src/cmd/volmgt/vold/ufs_partition.c
index b5a29b3cc3..b5a29b3cc3 100644
--- a/usr/src/cmd/volmgt/vold/ufs_partition.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/ufs_partition.c
diff --git a/usr/src/cmd/volmgt/vold/util.h b/deleted_files/usr/src/cmd/volmgt/vold/util.h
index 70c9c79fb0..70c9c79fb0 100644
--- a/usr/src/cmd/volmgt/vold/util.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/util.h
diff --git a/usr/src/cmd/volmgt/vold/vold.h b/deleted_files/usr/src/cmd/volmgt/vold/vold.h
index b1f5b58fa5..b1f5b58fa5 100644
--- a/usr/src/cmd/volmgt/vold/vold.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold.h
diff --git a/usr/src/cmd/volmgt/vold/vold_action.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_action.c
index caabf06b08..caabf06b08 100644
--- a/usr/src/cmd/volmgt/vold/vold_action.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_action.c
diff --git a/usr/src/cmd/volmgt/vold/vold_config.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_config.c
index 989596a969..989596a969 100644
--- a/usr/src/cmd/volmgt/vold/vold_config.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_config.c
diff --git a/usr/src/cmd/volmgt/vold/vold_db.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_db.c
index 752a855ebd..752a855ebd 100644
--- a/usr/src/cmd/volmgt/vold/vold_db.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_db.c
diff --git a/usr/src/cmd/volmgt/vold/vold_dev.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_dev.c
index 930aee76c5..930aee76c5 100644
--- a/usr/src/cmd/volmgt/vold/vold_dev.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_dev.c
diff --git a/usr/src/cmd/volmgt/vold/vold_err.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_err.c
index 357ab8928a..357ab8928a 100644
--- a/usr/src/cmd/volmgt/vold/vold_err.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_err.c
diff --git a/usr/src/cmd/volmgt/vold/vold_label.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_label.c
index ccc4fe0f76..ccc4fe0f76 100644
--- a/usr/src/cmd/volmgt/vold/vold_label.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_label.c
diff --git a/usr/src/cmd/volmgt/vold/vold_main.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_main.c
index 39bac740e0..39bac740e0 100644
--- a/usr/src/cmd/volmgt/vold/vold_main.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_main.c
diff --git a/usr/src/cmd/volmgt/vold/vold_mnt.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_mnt.c
index 16b204ab3b..16b204ab3b 100644
--- a/usr/src/cmd/volmgt/vold/vold_mnt.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_mnt.c
diff --git a/usr/src/cmd/volmgt/vold/vold_node.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_node.c
index 1d10b3aa89..1d10b3aa89 100644
--- a/usr/src/cmd/volmgt/vold/vold_node.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_node.c
diff --git a/usr/src/cmd/volmgt/vold/vold_obj.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_obj.c
index 01d51c0a03..01d51c0a03 100644
--- a/usr/src/cmd/volmgt/vold/vold_obj.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_obj.c
diff --git a/usr/src/cmd/volmgt/vold/vold_path.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_path.c
index 39872bfd45..39872bfd45 100644
--- a/usr/src/cmd/volmgt/vold/vold_path.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_path.c
diff --git a/usr/src/cmd/volmgt/vold/vold_proc.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_proc.c
index 2750837225..2750837225 100644
--- a/usr/src/cmd/volmgt/vold/vold_proc.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_proc.c
diff --git a/usr/src/cmd/volmgt/vold/vold_props.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_props.c
index 352dc99c57..352dc99c57 100644
--- a/usr/src/cmd/volmgt/vold/vold_props.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_props.c
diff --git a/usr/src/cmd/volmgt/vold/vold_sysevent.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_sysevent.c
index 81515ac21c..81515ac21c 100644
--- a/usr/src/cmd/volmgt/vold/vold_sysevent.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_sysevent.c
diff --git a/usr/src/cmd/volmgt/vold/vold_util.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_util.c
index 829b4e1980..829b4e1980 100644
--- a/usr/src/cmd/volmgt/vold/vold_util.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_util.c
diff --git a/usr/src/cmd/volmgt/vold/vold_vol.c b/deleted_files/usr/src/cmd/volmgt/vold/vold_vol.c
index df2607c5d9..df2607c5d9 100644
--- a/usr/src/cmd/volmgt/vold/vold_vol.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vold_vol.c
diff --git a/usr/src/cmd/volmgt/vold/vtoc.c b/deleted_files/usr/src/cmd/volmgt/vold/vtoc.c
index a251d93c47..a251d93c47 100644
--- a/usr/src/cmd/volmgt/vold/vtoc.c
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vtoc.c
diff --git a/usr/src/cmd/volmgt/vold/vtoc.h b/deleted_files/usr/src/cmd/volmgt/vold/vtoc.h
index 3792f32354..3792f32354 100644
--- a/usr/src/cmd/volmgt/vold/vtoc.h
+++ b/deleted_files/usr/src/cmd/volmgt/vold/vtoc.h
diff --git a/usr/src/head/rmmount.h b/deleted_files/usr/src/head/rmmount.h
index ffd36eef65..ffd36eef65 100644
--- a/usr/src/head/rmmount.h
+++ b/deleted_files/usr/src/head/rmmount.h
diff --git a/usr/src/lib/libvolmgt/common/volattr.c b/deleted_files/usr/src/lib/libvolmgt/common/volattr.c
index 3e97f08449..3e97f08449 100644
--- a/usr/src/lib/libvolmgt/common/volattr.c
+++ b/deleted_files/usr/src/lib/libvolmgt/common/volattr.c
diff --git a/usr/src/lib/libvolmgt/common/volmgt_fsi.c b/deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi.c
index 31db6db23c..31db6db23c 100644
--- a/usr/src/lib/libvolmgt/common/volmgt_fsi.c
+++ b/deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi.c
diff --git a/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h b/deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h
index c6ed86b86c..c6ed86b86c 100644
--- a/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h
+++ b/deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsi_private.h
diff --git a/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c b/deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c
index 5a08d7b06b..5a08d7b06b 100644
--- a/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c
+++ b/deleted_files/usr/src/lib/libvolmgt/common/volmgt_fsidbi.c
diff --git a/usr/src/lib/libvolmgt/common/volname.c b/deleted_files/usr/src/lib/libvolmgt/common/volname.c
index d04ffa22cf..d04ffa22cf 100644
--- a/usr/src/lib/libvolmgt/common/volname.c
+++ b/deleted_files/usr/src/lib/libvolmgt/common/volname.c
diff --git a/usr/src/lib/libvolmgt/common/volutil.c b/deleted_files/usr/src/lib/libvolmgt/common/volutil.c
index fbb241f53f..fbb241f53f 100644
--- a/usr/src/lib/libvolmgt/common/volutil.c
+++ b/deleted_files/usr/src/lib/libvolmgt/common/volutil.c
diff --git a/usr/src/pkgdefs/SUNWpcmem/preinstall b/deleted_files/usr/src/pkgdefs/SUNWpcmem/preinstall
index e369314dbe..e369314dbe 100644
--- a/usr/src/pkgdefs/SUNWpcmem/preinstall
+++ b/deleted_files/usr/src/pkgdefs/SUNWpcmem/preinstall
diff --git a/usr/src/pkgdefs/SUNWvolr/Makefile b/deleted_files/usr/src/pkgdefs/SUNWvolr/Makefile
index e1f3286fde..e1f3286fde 100644
--- a/usr/src/pkgdefs/SUNWvolr/Makefile
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/Makefile
diff --git a/usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl b/deleted_files/usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl
index cb7dd66dc8..cb7dd66dc8 100644
--- a/usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/pkginfo.tmpl
diff --git a/usr/src/pkgdefs/SUNWvolr/postinstall b/deleted_files/usr/src/pkgdefs/SUNWvolr/postinstall
index d4f911d2ca..d4f911d2ca 100644
--- a/usr/src/pkgdefs/SUNWvolr/postinstall
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/postinstall
diff --git a/usr/src/pkgdefs/SUNWvolr/preinstall b/deleted_files/usr/src/pkgdefs/SUNWvolr/preinstall
index eb58b7bda6..eb58b7bda6 100644
--- a/usr/src/pkgdefs/SUNWvolr/preinstall
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/preinstall
diff --git a/usr/src/pkgdefs/SUNWvolr/prototype_com b/deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_com
index 01f3887392..01f3887392 100644
--- a/usr/src/pkgdefs/SUNWvolr/prototype_com
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_com
diff --git a/usr/src/pkgdefs/SUNWvolr/prototype_i386 b/deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_i386
index 9ff6ad825c..9ff6ad825c 100644
--- a/usr/src/pkgdefs/SUNWvolr/prototype_i386
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_i386
diff --git a/usr/src/pkgdefs/SUNWvolr/prototype_sparc b/deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_sparc
index 1d4720a7de..1d4720a7de 100644
--- a/usr/src/pkgdefs/SUNWvolr/prototype_sparc
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolr/prototype_sparc
diff --git a/usr/src/pkgdefs/SUNWvolu/Makefile b/deleted_files/usr/src/pkgdefs/SUNWvolu/Makefile
index 26450c2399..26450c2399 100644
--- a/usr/src/pkgdefs/SUNWvolu/Makefile
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/Makefile
diff --git a/usr/src/pkgdefs/SUNWvolu/depend b/deleted_files/usr/src/pkgdefs/SUNWvolu/depend
index f69df997e5..f69df997e5 100644
--- a/usr/src/pkgdefs/SUNWvolu/depend
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/depend
diff --git a/usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl b/deleted_files/usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl
index e5f3330411..e5f3330411 100644
--- a/usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/pkginfo.tmpl
diff --git a/usr/src/pkgdefs/SUNWvolu/postremove b/deleted_files/usr/src/pkgdefs/SUNWvolu/postremove
index 48b8106613..48b8106613 100644
--- a/usr/src/pkgdefs/SUNWvolu/postremove
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/postremove
diff --git a/usr/src/pkgdefs/SUNWvolu/prototype_com b/deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_com
index 3055f5f104..3055f5f104 100644
--- a/usr/src/pkgdefs/SUNWvolu/prototype_com
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_com
diff --git a/usr/src/pkgdefs/SUNWvolu/prototype_i386 b/deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_i386
index af8b7b81b4..af8b7b81b4 100644
--- a/usr/src/pkgdefs/SUNWvolu/prototype_i386
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_i386
diff --git a/usr/src/pkgdefs/SUNWvolu/prototype_sparc b/deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_sparc
index 30b5b1544b..30b5b1544b 100644
--- a/usr/src/pkgdefs/SUNWvolu/prototype_sparc
+++ b/deleted_files/usr/src/pkgdefs/SUNWvolu/prototype_sparc
diff --git a/usr/src/pkgdefs/common_files/i.rmmconf b/deleted_files/usr/src/pkgdefs/common_files/i.rmmconf
index 787790ceff..787790ceff 100644
--- a/usr/src/pkgdefs/common_files/i.rmmconf
+++ b/deleted_files/usr/src/pkgdefs/common_files/i.rmmconf
diff --git a/usr/src/pkgdefs/common_files/i.voldconf b/deleted_files/usr/src/pkgdefs/common_files/i.voldconf
index 1dfc66f7d0..1dfc66f7d0 100644
--- a/usr/src/pkgdefs/common_files/i.voldconf
+++ b/deleted_files/usr/src/pkgdefs/common_files/i.voldconf
diff --git a/usr/src/uts/common/io/vol.c b/deleted_files/usr/src/uts/common/io/vol.c
index 64db74b970..64db74b970 100644
--- a/usr/src/uts/common/io/vol.c
+++ b/deleted_files/usr/src/uts/common/io/vol.c
diff --git a/usr/src/uts/common/io/vol.conf b/deleted_files/usr/src/uts/common/io/vol.conf
index c8af484ad8..c8af484ad8 100644
--- a/usr/src/uts/common/io/vol.conf
+++ b/deleted_files/usr/src/uts/common/io/vol.conf
diff --git a/usr/src/uts/common/sys/vol.h b/deleted_files/usr/src/uts/common/sys/vol.h
index be766d5f4c..be766d5f4c 100644
--- a/usr/src/uts/common/sys/vol.h
+++ b/deleted_files/usr/src/uts/common/sys/vol.h
diff --git a/usr/src/uts/intel/vol/Makefile b/deleted_files/usr/src/uts/intel/vol/Makefile
index 6f8dbc7bc0..6f8dbc7bc0 100644
--- a/usr/src/uts/intel/vol/Makefile
+++ b/deleted_files/usr/src/uts/intel/vol/Makefile
diff --git a/usr/src/uts/sparc/vol/Makefile b/deleted_files/usr/src/uts/sparc/vol/Makefile
index 3bbf7cda81..3bbf7cda81 100644
--- a/usr/src/uts/sparc/vol/Makefile
+++ b/deleted_files/usr/src/uts/sparc/vol/Makefile
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index 8a5e5d9113..933f602643 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -112,6 +112,7 @@ COMMON_SUBDIRS = \
cmd/dumpadm \
cmd/dumpcs \
cmd/echo \
+ cmd/eject \
cmd/emul64ioctl \
cmd/env \
cmd/expand \
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index ddacfe9471..4e5f2c9ab9 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -83,6 +83,20 @@ ROOT.SYS= \
/etc/fs/nfs \
/etc/fs/zfs \
/etc/ftpd \
+ /etc/hal \
+ /etc/hal/fdi \
+ /etc/hal/fdi/information \
+ /etc/hal/fdi/information/10freedesktop \
+ /etc/hal/fdi/information/20thirdparty \
+ /etc/hal/fdi/information/30user \
+ /etc/hal/fdi/policy \
+ /etc/hal/fdi/policy/10osvendor \
+ /etc/hal/fdi/policy/20thirdparty \
+ /etc/hal/fdi/policy/30user \
+ /etc/hal/fdi/preprobe \
+ /etc/hal/fdi/preprobe/10osvendor \
+ /etc/hal/fdi/preprobe/20thirdparty \
+ /etc/hal/fdi/preprobe/30user \
/etc/iscsi \
/etc/rpcsec \
/etc/security \
@@ -181,6 +195,8 @@ sparc_ROOT.BIN= \
ROOT.BIN= \
$($(MACH)_ROOT.BIN) \
+ /etc/dbus-1 \
+ /etc/dbus-1/system.d \
/etc/saf \
/etc/sma \
/etc/sma/snmp \
@@ -207,8 +223,10 @@ ROOT.BIN= \
/usr/include/sys/crypto \
/usr/include/fm \
/usr/include/gssapi \
+ /usr/include/hal \
/usr/include/kerberosv5 \
/usr/include/libmilter \
+ /usr/include/libpolkit \
/usr/include/sasl \
/usr/include/tsol \
/usr/include/security \
@@ -236,6 +254,7 @@ ROOT.BIN= \
$(XROOT.BIN) \
/usr/lib/fm \
/usr/lib/gss \
+ /usr/lib/hal \
/usr/lib/krb5 \
/usr/lib/link_audit \
/usr/lib/libp \
@@ -339,6 +358,7 @@ ROOT.SYS2= \
/usr/lib/nfs \
/usr/net \
/usr/net/servers \
+ /usr/share/hwdata \
/usr/share/lib \
/usr/share/lib/xml \
/usr/share/lib/xml/dtd \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index fd41167eda..be422154a6 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -139,6 +139,7 @@ COMMON_SUBDIRS= \
ed \
eeprom \
egrep \
+ eject \
emul64ioctl \
enhance \
env \
@@ -183,10 +184,12 @@ COMMON_SUBDIRS= \
groups \
grpck \
gss \
+ hal \
halt \
head \
hostid \
hostname \
+ hwdata \
id \
infocmp \
init \
@@ -278,6 +281,7 @@ COMMON_SUBDIRS= \
pgrep \
picl \
plimit \
+ policykit \
pools \
power \
ppgsz \
@@ -314,7 +318,9 @@ COMMON_SUBDIRS= \
rm \
rmdir \
rmformat \
+ rmmount \
rmt \
+ rmvolmgr \
roles \
rpcbind \
rpcgen \
@@ -391,7 +397,8 @@ COMMON_SUBDIRS= \
valtools \
vgrind \
vi \
- volmgt \
+ volcheck \
+ volrmmount \
w \
wall \
wbem \
@@ -530,6 +537,7 @@ MSGSUBDIRS= \
du \
dumpcs \
ed \
+ eject \
env \
eqn \
expand \
@@ -621,6 +629,8 @@ MSGSUBDIRS= \
rm \
rmdir \
rmformat \
+ rmmount \
+ rmvolmgr \
scadm \
script \
sdiff \
@@ -658,7 +668,8 @@ MSGSUBDIRS= \
valtools \
vgrind \
vi \
- volmgt \
+ volcheck \
+ volrmmount \
w \
wbem \
wc \
diff --git a/usr/src/cmd/bsmconv/bsmconv.sh b/usr/src/cmd/bsmconv/bsmconv.sh
index 29cc02607c..3609293b9b 100644
--- a/usr/src/cmd/bsmconv/bsmconv.sh
+++ b/usr/src/cmd/bsmconv/bsmconv.sh
@@ -113,15 +113,25 @@ then
printf "${form}\n" $PROG
fi
-# Disable volume manager from running on reboot.
-cat >> ${ROOT}/var/svc/profile/upgrade <<SVC_UPGRADE
-svcadm disable svc:/system/filesystem/volfs:default
-SVC_UPGRADE
-
-# store the current state of volfs service for restoring later
-# in bsmunconv.sh
-svcs -o state -H svc:/system/filesystem/volfs:default > \
- ${ROOT}/etc/security/spool/vold.state
+# Prevent automount of removable and hotpluggable volumes
+# by forcing volume.ignore HAL property on all such volumes.
+if [ -d ${ROOT}/etc/hal/fdi ] ; then
+ cat > ${ROOT}/etc/hal/fdi/policy/30user/90-solaris-device-allocation.fdi <<FDI
+<?xml version="1.0" encoding="UTF-8"?>
+<deviceinfo version="0.2">
+ <device>
+ <match key="info.capabilities" contains="volume">
+ <match key="@block.storage_device:storage.removable" bool="true">
+ <merge key="volume.ignore" type="bool">true</merge>
+ </match>
+ <match key="@block.storage_device:storage.hotpluggable" bool="true">
+ <merge key="volume.ignore" type="bool">true</merge>
+ </match>
+ </match>
+ </device>
+</deviceinfo>
+FDI
+fi
# Turn on auditing in the loadable module
diff --git a/usr/src/cmd/bsmrecord/audit_record_attr.txt b/usr/src/cmd/bsmrecord/audit_record_attr.txt
index 45a7bfc605..6c3b3e63f2 100644
--- a/usr/src/cmd/bsmrecord/audit_record_attr.txt
+++ b/usr/src/cmd/bsmrecord/audit_record_attr.txt
@@ -2586,3 +2586,24 @@ label=AUE_usermgr_delete
label=AUE_zone_state
format=text1:zone2
comment=New zone state:zone name
+
+label=AUE_attach
+ program=hald
+ format=uauth1:text2:text3:[text4]
+ comment=authorization used:mount point:device:options
+label=AUE_detach
+ program=hald
+ format=uauth1:text2:text3:[text4]
+ comment=authorization used:mount point:device:options
+label=AUE_remove
+ program=hald
+ format=uauth1:[text2]:text3
+ comment=authorization used:mount point:device
+label=AUE_pool_import
+ program=hald
+ format=uauth1:text2:text3
+ comment=authorization used:pool:device
+label=AUE_pool_export
+ program=hald
+ format=uauth1:text2:text3
+ comment=authorization used:pool:device
diff --git a/usr/src/cmd/bsmunconv/bsmunconv.sh b/usr/src/cmd/bsmunconv/bsmunconv.sh
index ea2859dd7e..b77ad73771 100644
--- a/usr/src/cmd/bsmunconv/bsmunconv.sh
+++ b/usr/src/cmd/bsmunconv/bsmunconv.sh
@@ -98,18 +98,8 @@ cat >> ${ROOT}/var/svc/profile/upgrade <<SVC_UPGRADE
/usr/sbin/svcadm disable system/auditd
SVC_UPGRADE
-# restore volume manager startup on next boot using the
-# previous state saved by bsmconv.sh
-state="enable"
-if [ -f ${ROOT}/etc/security/spool/vold.state ]; then
- prev_state=`cat ${ROOT}/etc/security/spool/vold.state`
- if [ ${prev_state} != "online" ]; then
- state="disable"
- fi
-fi
-cat >> ${ROOT}/var/svc/profile/upgrade <<SVC_UPGRADE
-svcadm ${state} svc:/system/filesystem/volfs:default
-SVC_UPGRADE
+# Restore default policy for removable and hotpluggable volumes
+rm -f ${ROOT}/etc/hal/fdi/policy/30user/90-solaris-device-allocation.fdi
# Turn off auditing in the loadable module
diff --git a/usr/src/cmd/devfsadm/disk_link.c b/usr/src/cmd/devfsadm/disk_link.c
index f12f9cfb0d..3257738dbd 100644
--- a/usr/src/cmd/devfsadm/disk_link.c
+++ b/usr/src/cmd/devfsadm/disk_link.c
@@ -206,12 +206,14 @@ static void
disk_common(di_minor_t minor, di_node_t node, char *disk, int flags)
{
char l_path[PATH_MAX + 1];
+ char sec_path[PATH_MAX + 1];
char stale_re[DISK_SUBPATH_MAX];
char *dir;
char slice[4];
char *mn;
char *ctrl;
char *nt = NULL;
+ int *int_prop;
int nflags = 0;
if (strstr(mn = di_minor_name(minor), ",raw")) {
@@ -271,6 +273,19 @@ disk_common(di_minor_t minor, di_node_t node, char *disk, int flags)
(void) devfsadm_mklink(l_path, node, minor, nflags);
+ /* secondary links for removable and hotpluggable devices */
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "removable-media",
+ &int_prop) >= 0) {
+ (void) strcpy(sec_path, "removable-media/");
+ (void) strcat(sec_path, l_path);
+ (void) devfsadm_secondary_link(sec_path, l_path, 0);
+ } else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "hotpluggable",
+ &int_prop) >= 0) {
+ (void) strcpy(sec_path, "hotpluggable/");
+ (void) strcat(sec_path, l_path);
+ (void) devfsadm_secondary_link(sec_path, l_path, 0);
+ }
+
if ((flags & RM_STALE) == RM_STALE) {
(void) strcpy(stale_re, "^");
(void) strcat(stale_re, dir);
diff --git a/usr/src/cmd/eject/Makefile b/usr/src/cmd/eject/Makefile
new file mode 100644
index 0000000000..74f00c9c7c
--- /dev/null
+++ b/usr/src/cmd/eject/Makefile
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG= eject
+
+include ../Makefile.cmd
+
+LDLIBS += -lvolmgt -ladm
+
+CFLAGS += $(CCVERBOSE)
+
+# This flag is being added only for SCO (x86) compatibility
+CFLAGS += $(iBCS2FLAG)
+
+LINTFLAGS += -um
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/eject/eject.c b/usr/src/cmd/eject/eject.c
new file mode 100644
index 0000000000..820824e596
--- /dev/null
+++ b/usr/src/cmd/eject/eject.c
@@ -0,0 +1,726 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Program to eject one or more pieces of media.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fdio.h>
+#include <sys/dkio.h>
+#include <sys/cdio.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <locale.h>
+#include <libintl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <volmgt.h>
+#include <sys/mnttab.h>
+#include <signal.h>
+
+static char *prog_name = NULL;
+static boolean_t do_default = B_FALSE;
+static boolean_t do_list = B_FALSE;
+static boolean_t do_closetray = B_FALSE;
+static boolean_t force_eject = B_FALSE;
+static boolean_t do_query = B_FALSE;
+static boolean_t is_direct = B_FALSE;
+
+static int work(char *, char *);
+static void usage(void);
+static int ejectit(char *);
+static boolean_t query(char *, boolean_t);
+static boolean_t floppy_in_drive(char *, int, boolean_t *);
+static boolean_t display_busy(char *, boolean_t);
+static char *eject_getfullblkname(char *, boolean_t);
+extern char *getfullrawname(char *);
+
+/*
+ * ON-private libvolmgt routines
+ */
+int _dev_mounted(char *path);
+int _dev_unmount(char *path);
+char *_media_oldaliases(char *name);
+void _media_printaliases(void);
+
+
+/*
+ * Hold over from old eject.
+ * returns exit codes: (KEEP THESE - especially important for query)
+ * 0 = -n, -d or eject operation was ok, -q = media in drive
+ * 1 = -q only = media not in drive
+ * 2 = various parameter errors, etc.
+ * 3 = eject ioctl failed
+ * New Value (2/94)
+ * 4 = eject partially succeeded, but now manually remove media
+ */
+
+#define EJECT_OK 0
+#define EJECT_NO_MEDIA 1
+#define EJECT_PARM_ERR 2
+#define EJECT_IOCTL_ERR 3
+#define EJECT_MAN_EJ 4
+
+#define AVAIL_MSG "%s is available\n"
+#define NOT_AVAIL_MSG "%s is not available\n"
+
+#define OK_TO_EJECT_MSG "%s can now be manually ejected\n"
+
+#define FLOPPY_MEDIA_TYPE "floppy"
+#define CDROM_MEDIA_TYPE "cdrom"
+
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ const char *opts = "dqflnpt";
+ int excode;
+ int res;
+ boolean_t err_seen = B_FALSE;
+ boolean_t man_eject_seen = B_FALSE;
+ char *rmmount_opt = NULL;
+
+ (void) setlocale(LC_ALL, "");
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+ (void) textdomain(TEXT_DOMAIN);
+
+ prog_name = argv[0];
+
+ is_direct = (getenv("EJECT_DIRECT") != NULL);
+
+ /* process arguments */
+ while ((c = getopt(argc, argv, opts)) != EOF) {
+ switch (c) {
+ case 'd':
+ do_default = B_TRUE;
+ rmmount_opt = "-d";
+ break;
+ case 'q':
+ do_query = B_TRUE;
+ break;
+ case 'l':
+ do_list = B_TRUE;
+ rmmount_opt = "-l";
+ break;
+ case 'f':
+ force_eject = B_TRUE;
+ break;
+ case 'n':
+ case 'p':
+ /* obsolete options, just ignore */
+ break;
+ case 't':
+ do_closetray = B_TRUE;
+ break;
+ default:
+ usage();
+ exit(EJECT_PARM_ERR);
+ }
+ }
+
+ if (argc == optind) {
+ /* no argument -- use the default */
+ excode = work(NULL, rmmount_opt);
+ } else {
+ /* multiple things to eject */
+ for (; optind < argc; optind++) {
+ res = work(argv[optind], rmmount_opt);
+ if (res == EJECT_MAN_EJ) {
+ man_eject_seen = B_TRUE;
+ } else if (res != EJECT_OK) {
+ err_seen = B_TRUE;
+ }
+ }
+ if (err_seen) {
+ if (!is_direct) {
+ excode = res;
+ } else {
+ excode = EJECT_IOCTL_ERR;
+ }
+ } else if (man_eject_seen) {
+ excode = EJECT_MAN_EJ;
+ } else {
+ excode = EJECT_OK;
+ }
+ }
+
+ return (excode);
+}
+
+/*
+ * the the real work of ejecting (and notifying)
+ */
+static int
+work(char *arg, char *rmmount_opt)
+{
+ char *name;
+ int excode = EJECT_OK;
+ struct stat64 sb;
+ char *arg1, *arg2;
+ pid_t pid;
+ int status = 1;
+
+ if (!is_direct) {
+ /* exec rmmount */
+ if (do_closetray) {
+ (void) putenv("EJECT_CLOSETRAY=1");
+ }
+ if (do_query) {
+ (void) putenv("EJECT_QUERY=1");
+ }
+ pid = fork();
+ if (pid < 0) {
+ exit(1);
+ } else if (pid == 0) {
+ /* child */
+ if (rmmount_opt != NULL) {
+ arg1 = rmmount_opt;
+ arg2 = arg;
+ } else {
+ arg1 = arg;
+ arg2 = NULL;
+ }
+
+ if (execl("/usr/bin/rmmount", "eject",
+ arg1, arg2, 0) < 0) {
+ perror("execl");
+ exit(1);
+ } else {
+ exit(0);
+ }
+ }
+ /* parent */
+ if (waitpid(pid, &status, 0) != pid) {
+ excode = 1;
+ } else if (WIFEXITED(status) && (WEXITSTATUS(status) != 0)) {
+ excode = WEXITSTATUS(status);
+ } else {
+ excode = 0;
+ }
+ }
+
+ /*
+ * rmmount returns 99 if HAL not running -
+ * fallback to direct in that case
+ */
+ if (is_direct || (excode == 99)) {
+ if (arg == NULL) {
+ arg = "floppy";
+ }
+ if ((name = _media_oldaliases(arg)) == NULL) {
+ name = arg;
+ }
+ if (do_default) {
+ (void) printf("%s\n", name);
+ goto out;
+ }
+ if (do_list) {
+ (void) printf("%s\t%s\n", name, arg);
+ goto out;
+ }
+ if (access(name, R_OK) != 0) {
+ if (do_query) {
+ (void) fprintf(stderr,
+ gettext("%s: no media\n"), name);
+ return (EJECT_NO_MEDIA);
+ } else {
+ perror(name);
+ return (EJECT_PARM_ERR);
+ }
+ }
+
+ if (do_query) {
+ if ((stat64(name, &sb) == 0) && S_ISDIR(sb.st_mode)) {
+ (void) fprintf(stderr,
+ gettext("%s: no media\n"), name);
+ return (EJECT_NO_MEDIA);
+ }
+ if (!query(name, B_TRUE)) {
+ excode = EJECT_NO_MEDIA;
+ }
+ } else {
+ excode = ejectit(name);
+ }
+ }
+out:
+ return (excode);
+}
+
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ gettext("usage: %s [-fldqt] [name | nickname]\n"),
+ prog_name);
+ (void) fprintf(stderr,
+ gettext("options:\t-f force eject\n"));
+ (void) fprintf(stderr,
+ gettext("\t\t-l list ejectable devices\n"));
+ (void) fprintf(stderr,
+ gettext("\t\t-d show default device\n"));
+ (void) fprintf(stderr,
+ gettext("\t\t-q query for media present\n"));
+ (void) fprintf(stderr,
+ gettext("\t\t-t close tray\n"));
+}
+
+
+static int
+ejectit(char *name)
+{
+ int fd, r;
+ boolean_t mejectable = B_FALSE; /* manually ejectable */
+ int result = EJECT_OK;
+
+ /*
+ * If volume management is either not running or not being managed by
+ * vold, and the device is mounted, we try to umount the device. If we
+ * fail, we give up, unless he used the -f flag.
+ */
+
+ if (_dev_mounted(name)) {
+ r = _dev_unmount(name);
+ if (r == 0) {
+ if (!force_eject) {
+ (void) fprintf(stderr,
+gettext("WARNING: can not unmount %s, the file system is (probably) busy\n"),
+ name);
+ return (EJECT_PARM_ERR);
+ } else {
+ (void) fprintf(stderr,
+gettext("WARNING: %s has a mounted filesystem, ejecting anyway\n"),
+ name);
+ }
+ }
+ }
+
+ /*
+ * Require O_NDELAY for when floppy is not formatted
+ * will still id floppy in drive
+ */
+
+ /*
+ * make sure we are dealing with a raw device
+ *
+ * XXX: NOTE: results from getfullrawname()
+ * really should be free()d when no longer
+ * in use
+ */
+ name = getfullrawname(name);
+
+ if ((fd = open(name, O_RDONLY | O_NDELAY)) < 0) {
+ if (errno == EBUSY) {
+ (void) fprintf(stderr,
+gettext("%s is busy (try 'eject floppy' or 'eject cdrom'?)\n"),
+ name);
+ return (EJECT_PARM_ERR);
+ }
+ perror(name);
+ return (EJECT_PARM_ERR);
+ }
+
+ if (do_closetray) {
+ if (ioctl(fd, CDROMCLOSETRAY) < 0) {
+ result = EJECT_IOCTL_ERR;
+ }
+ } else if (ioctl(fd, DKIOCEJECT, 0) < 0) {
+ /* check on why eject failed */
+
+ /* check for no floppy in manually ejectable drive */
+ if ((errno == ENOSYS) &&
+ !floppy_in_drive(name, fd, &mejectable)) {
+ /* use code below to handle "not present" */
+ errno = ENXIO;
+ }
+
+ if (errno == ENOSYS || errno == ENOTSUP) {
+ (void) fprintf(stderr, gettext(OK_TO_EJECT_MSG), name);
+ }
+
+ if ((errno == ENOSYS || errno == ENOTSUP) && mejectable) {
+ /*
+ * keep track of the fact that this is a manual
+ * ejection
+ */
+ result = EJECT_MAN_EJ;
+
+ } else if (errno == EBUSY) {
+ /*
+ * if our pathname is s slice (UFS is great) then
+ * check to see what really is busy
+ */
+ if (!display_busy(name, B_FALSE)) {
+ perror(name);
+ }
+ result = EJECT_IOCTL_ERR;
+
+ } else if ((errno == EAGAIN) || (errno == ENODEV) ||
+ (errno == ENXIO)) {
+ (void) fprintf(stderr,
+ gettext("%s not present in a drive\n"),
+ name);
+ result = EJECT_OK;
+ } else {
+ perror(name);
+ result = EJECT_IOCTL_ERR;
+ }
+ }
+
+ (void) close(fd);
+ return (result);
+}
+
+
+/*
+ * return B_TRUE if a floppy is in the drive, B_FALSE otherwise
+ *
+ * this routine assumes that the file descriptor passed in is for
+ * a floppy disk. this works because it's only called if the device
+ * is "manually ejectable", which only (currently) occurs for floppies.
+ */
+static boolean_t
+floppy_in_drive(char *name, int fd, boolean_t *is_floppy)
+{
+ int ival = 0;
+ boolean_t rval = B_FALSE;
+
+
+ if (ioctl(fd, FDGETCHANGE, &ival) >= 0) {
+ if (!(ival & FDGC_CURRENT)) {
+ rval = B_TRUE;
+ }
+ *is_floppy = B_TRUE;
+ } else {
+ *is_floppy = B_FALSE;
+ (void) fprintf(stderr, gettext("%s is not a floppy disk\n"),
+ name);
+ }
+
+ return (rval);
+}
+
+
+/*
+ * display a "busy" message for the supplied pathname
+ *
+ * if the pathname is not a slice, then just display a busy message
+ * else if the pathname is some slice subdirectory then look for the
+ * *real* culprits
+ *
+ * if this is not done then the user can get a message like
+ * /vol/dev/rdsk/c0t6d0/solaris_2_5_sparc/s5: Device busy
+ * when they try to eject "cdrom0", but "s0" (e.g.) may be the only busy
+ * slice
+ *
+ * return B_TRUE iff we printed the appropriate error message, else
+ * return B_FALSE (and caller will print error message itself)
+ */
+static boolean_t
+display_busy(char *path, boolean_t vm_running)
+{
+ int errno_save = errno; /* to save errno */
+ char *blk; /* block name */
+ FILE *fp = NULL; /* for scanning mnttab */
+ struct mnttab mref; /* for scanning mnttab */
+ struct mnttab mp; /* for scanning mnttab */
+ boolean_t res = B_FALSE; /* return value */
+ char busy_base[MAXPATHLEN]; /* for keeping base dir name */
+ uint_t bblen; /* busy_base string length */
+ char *cp; /* for truncating path */
+
+
+
+#ifdef DEBUG
+ (void) fprintf(stderr, "display_busy(\"%s\"): entering\n", path);
+#endif
+
+ /*
+ * get the block pathname.
+ * eject_getfullblkname returns NULL or pathname which
+ * has length < MAXPATHLEN.
+ */
+ blk = eject_getfullblkname(path, vm_running);
+ if (blk == NULL)
+ goto dun;
+
+ /* open mnttab for scanning */
+ if ((fp = fopen(MNTTAB, "r")) == NULL) {
+ /* can't open mnttab!? -- give up */
+ goto dun;
+ }
+
+ (void) memset((void *)&mref, '\0', sizeof (struct mnttab));
+ mref.mnt_special = blk;
+ if (getmntany(fp, &mp, &mref) == 0) {
+ /* we found our entry -- we're done */
+ goto dun;
+ }
+
+ /* perhaps we have a sub-slice (which is what we exist to test for) */
+
+ /* create a base pathname */
+ (void) strcpy(busy_base, blk);
+ if ((cp = strrchr(busy_base, '/')) == NULL) {
+ /* no last slash in pathname!!?? -- give up */
+ goto dun;
+ }
+ *cp = '\0';
+ bblen = strlen(busy_base);
+ /* bblen = (uint)(cp - busy_base); */
+
+ /* scan for matches */
+ rewind(fp); /* rescan mnttab */
+ while (getmntent(fp, &mp) == 0) {
+ /*
+ * work around problem where '-' in /etc/mnttab for
+ * special device turns to NULL which isn't expected
+ */
+ if (mp.mnt_special == NULL)
+ mp.mnt_special = "-";
+ if (strncmp(busy_base, mp.mnt_special, bblen) == 0) {
+ res = B_TRUE;
+ (void) fprintf(stderr, "%s: %s\n", mp.mnt_special,
+ strerror(EBUSY));
+ }
+ }
+
+dun:
+ if (fp != NULL) {
+ (void) fclose(fp);
+ }
+#ifdef DEBUG
+ (void) fprintf(stderr, "display_busy: returning %s\n",
+ res ? "B_TRUE" : "B_FALSE");
+#endif
+ errno = errno_save;
+ return (res);
+}
+
+
+/*
+ * In my experience with removable media drivers so far... the
+ * most reliable way to tell if a piece of media is in a drive
+ * is simply to open it. If the open works, there's something there,
+ * if it fails, there's not. We check for two errnos which we
+ * want to interpret for the user, ENOENT and EPERM. All other
+ * errors are considered to be "media isn't there".
+ *
+ * return B_TRUE if media found, else B_FALSE (XXX: was 0 and -1)
+ */
+static boolean_t
+query(char *name, boolean_t doprint)
+{
+ int fd;
+ int rval; /* FDGETCHANGE return value */
+ enum dkio_state state;
+
+ if ((fd = open(name, O_RDONLY|O_NONBLOCK)) < 0) {
+ if ((errno == EPERM) || (errno == ENOENT)) {
+ if (doprint) {
+ perror(name);
+ }
+ } else {
+ if (doprint) {
+ (void) fprintf(stderr, gettext(NOT_AVAIL_MSG),
+ name);
+ }
+ }
+ return (B_FALSE);
+ }
+
+ rval = 0;
+ if (ioctl(fd, FDGETCHANGE, &rval) >= 0) {
+ /* hey, it worked, what a deal, it must be a floppy */
+ (void) close(fd);
+ if (!(rval & FDGC_CURRENT)) {
+ if (doprint) {
+ (void) fprintf(stderr, gettext(AVAIL_MSG),
+ name);
+ }
+ return (B_TRUE);
+ }
+ if (rval & FDGC_CURRENT) {
+ if (doprint) {
+ (void) fprintf(stderr, gettext(NOT_AVAIL_MSG),
+ name);
+ }
+ return (B_FALSE);
+ }
+ }
+
+again:
+ state = DKIO_NONE;
+ if (ioctl(fd, DKIOCSTATE, &state) >= 0) {
+ /* great, the fancy ioctl is supported. */
+ if (state == DKIO_INSERTED) {
+ if (doprint) {
+ (void) fprintf(stderr, gettext(AVAIL_MSG),
+ name);
+ }
+ (void) close(fd);
+ return (B_TRUE);
+ }
+ if (state == DKIO_EJECTED) {
+ if (doprint) {
+ (void) fprintf(stderr, gettext(NOT_AVAIL_MSG),
+ name);
+ }
+ (void) close(fd);
+ return (B_FALSE);
+ }
+ /*
+ * Silly retry loop.
+ */
+ (void) sleep(1);
+ goto again;
+ }
+ (void) close(fd);
+
+ /*
+ * Ok, we've tried the non-blocking/ioctl route. The
+ * device doesn't support any of our nice ioctls, so
+ * we'll just say that if it opens it's there, if it
+ * doesn't, it's not.
+ */
+ if ((fd = open(name, O_RDONLY)) < 0) {
+ if (doprint) {
+ (void) fprintf(stderr, gettext(NOT_AVAIL_MSG), name);
+ }
+ return (B_FALSE);
+ }
+
+ (void) close(fd);
+ if (doprint) {
+ (void) fprintf(stderr, gettext(AVAIL_MSG), name);
+ }
+ return (B_TRUE); /* success */
+}
+
+
+/*
+ * this routine will return the volmgt block name given the volmgt
+ * raw (char spcl) name
+ *
+ * if anything but a volmgt raw pathname is supplied that pathname will
+ * be returned
+ *
+ * NOTE: non-null return value will point to static data, overwritten with
+ * each call
+ *
+ * e.g. names starting with "/vol/r" will be changed to start with "/vol/",
+ * and names starting with "vol/dev/r" will be changed to start with
+ * "/vol/dev/"
+ */
+static char *
+eject_getfullblkname(char *path, boolean_t vm_running)
+{
+ char raw_root[MAXPATHLEN];
+ const char *vm_root;
+ static char res_buf[MAXPATHLEN];
+ uint_t raw_root_len;
+
+#ifdef DEBUG
+ (void) fprintf(stderr, "eject_getfullblkname(\"%s\", %s): entering\n",
+ path, vm_running ? "B_TRUE" : "B_FALSE");
+#endif
+ /*
+ * try different strategies based on whether or not vold is running
+ */
+ if (vm_running) {
+
+ /* vold IS running -- look in /vol (or its alternate) */
+
+ /* get vm root dir */
+ vm_root = volmgt_root();
+
+ /* get first volmgt root dev directory (and its length) */
+ (void) snprintf(raw_root, sizeof (raw_root), "%s/r", vm_root);
+ raw_root_len = strlen(raw_root);
+
+ /* see if we have a raw volmgt pathname (e.g. "/vol/r*") */
+ if (strncmp(path, raw_root, raw_root_len) == 0) {
+ if (snprintf(res_buf, sizeof (res_buf), "%s/%s",
+ vm_root, path + raw_root_len) >= sizeof (res_buf)) {
+ return (NULL);
+ }
+ goto dun; /* found match in /vol */
+ }
+
+ /* get second volmgt root dev directory (and its length) */
+ (void) snprintf(raw_root, sizeof (raw_root),
+ "%s/dev/r", vm_root);
+ raw_root_len = strlen(raw_root);
+
+ /* see if we have a raw volmgt pathname (e.g. "/vol/dev/r*") */
+ if (strncmp(path, raw_root, raw_root_len) == 0) {
+ if (snprintf(res_buf, sizeof (res_buf), "%s/dev/%s",
+ vm_root, path + raw_root_len) >= sizeof (res_buf)) {
+ return (NULL);
+ }
+ goto dun; /* found match in /vol/dev */
+ }
+
+ } else {
+
+ /* vold is NOT running -- look in /dev */
+
+ (void) strcpy(raw_root, "/dev/r");
+ raw_root_len = strlen(raw_root);
+ if (strncmp(path, raw_root, raw_root_len) == 0) {
+ if (snprintf(res_buf, sizeof (res_buf), "/dev/%s",
+ path + raw_root_len) >= sizeof (res_buf)) {
+ return (NULL);
+ }
+ goto dun; /* found match in /dev */
+ }
+ }
+
+ /* no match -- return what we got */
+ (void) strcpy(res_buf, path);
+
+dun:
+#ifdef DEBUG
+ (void) fprintf(stderr, "eject_getfullblkname: returning %s\n",
+ res_buf ? res_buf : "<null ptr>");
+#endif
+ return (res_buf);
+}
diff --git a/usr/src/cmd/fs.d/hsfs/Makefile b/usr/src/cmd/fs.d/hsfs/Makefile
index e6c0aeb8ae..9b385d404d 100644
--- a/usr/src/cmd/fs.d/hsfs/Makefile
+++ b/usr/src/cmd/fs.d/hsfs/Makefile
@@ -28,7 +28,7 @@
# whose executable reside in $(INSDIR1) and $(INSDIR2).
#
-SUBDIR1= fstyp labelit ident
+SUBDIR1= fstyp labelit
SUBDIR2= mount
SUBDIRS= $(SUBDIR1) $(SUBDIR2)
diff --git a/usr/src/cmd/fs.d/pcfs/Makefile b/usr/src/cmd/fs.d/pcfs/Makefile
index 1c6d1d6cab..9837a2d67d 100644
--- a/usr/src/cmd/fs.d/pcfs/Makefile
+++ b/usr/src/cmd/fs.d/pcfs/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,13 +21,14 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1982 by Sun Microsystems, Inc.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
# /usr/src/cmd/lib/fs/pcfs is the directory of all pcfs specific commands
# whose executable reside in $(INSDIR1) and $(INSDIR2).
#
-SUBDIR1= mount ident fstyp
+SUBDIR1= mount fstyp
SUBDIR2= mkfs fsck
SUBDIRS= $(SUBDIR1) $(SUBDIR2)
diff --git a/usr/src/cmd/fs.d/udfs/Makefile b/usr/src/cmd/fs.d/udfs/Makefile
index 8da2ab2e78..d6cb3ed343 100644
--- a/usr/src/cmd/fs.d/udfs/Makefile
+++ b/usr/src/cmd/fs.d/udfs/Makefile
@@ -26,7 +26,7 @@
#
SUBDIR1= fstyp
-SUBDIR2= fsck fsdb ident labelit mkfs mount
+SUBDIR2= fsck fsdb labelit mkfs mount
SUBDIRS= $(SUBDIR1) $(SUBDIR2)
all:= TARGET= all
diff --git a/usr/src/cmd/fs.d/ufs/Makefile b/usr/src/cmd/fs.d/ufs/Makefile
index 21fde7a49f..6ae7afd332 100644
--- a/usr/src/cmd/fs.d/ufs/Makefile
+++ b/usr/src/cmd/fs.d/ufs/Makefile
@@ -34,7 +34,7 @@
#
-SUBDIR1= clri edquota ff fsck fsckall fsdb fsirand fstyp ident \
+SUBDIR1= clri edquota ff fsck fsckall fsdb fsirand fstyp \
labelit lockfs ncheck quot quota quotacheck quotaon \
repquota tunefs
SUBDIR2= df fssnap mkfs mount newfs volcopy
diff --git a/usr/src/cmd/hal/LICENSE b/usr/src/cmd/hal/LICENSE
new file mode 100644
index 0000000000..5a1d7566a1
--- /dev/null
+++ b/usr/src/cmd/hal/LICENSE
@@ -0,0 +1,51 @@
+The Academic Free License
+v. 2.1
+
+This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following notice immediately following the copyright notice for the Original Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license to do the following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, to make, use, sell and offer for sale the Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work, and by publishing the address of that information repository in a notice immediately following the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior written permission of the Licensor. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor except as expressly stated herein. No patent license is granted to make, use, sell or offer to sell embodiments of any patent claims other than the licensed claims defined in Section 2. No right is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any Original Work that Licensor otherwise would have a right to license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately proceeding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to liability for death or personal injury resulting from Licensor's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. Nothing else but this License (or another written agreement between Licensor and You) grants You permission to create Derivative Works based upon the Original Work or to exercise any of the rights granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the equivalent laws of other countries, and international treaty. This section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+13) Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission is hereby granted to copy and distribute this license without modification. This license may not be modified without the express written permission of its copyright owner.
+
+
+
diff --git a/usr/src/cmd/hal/Makefile b/usr/src/cmd/hal/Makefile
new file mode 100644
index 0000000000..af8979f020
--- /dev/null
+++ b/usr/src/cmd/hal/Makefile
@@ -0,0 +1,73 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.cmd
+include Makefile.hal
+
+SUBDIRS1 = hald hald-runner addons probing tools
+SUBDIRS2 = fdi
+SUBDIRS = $(SUBDIRS1) $(SUBDIRS2)
+
+HAL_CONF = hal.conf
+ROOT_DBUS_CONF_DIR = $(ROOT)/etc/dbus-1/system.d
+ROOT_HAL_CONF = $(HAL_CONF:%=$(ROOT_DBUS_CONF_DIR)/%)
+
+CLOBBERFILES += $(HAL_CONF)
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+
+$(ROOT_HAL_CONF) := FILEMODE = 644
+$(ROOT_HAL_CONF) := OWNER = root
+$(ROOT_HAL_CONF) := GROUP = bin
+
+.KEEP_STATE:
+
+all: $(SUBDIRS) $(HAL_CONF)
+
+clean: $(SUBDIRS)
+
+install: $(SUBDIRS) $(ROOT_HAL_CONF)
+
+$(ROOT_DBUS_CONF_DIR):
+ $(INS.dir)
+
+$(ROOT_HAL_CONF): $(ROOT_DBUS_CONF_DIR) $(HAL_CONF)
+ $(INS.file) $(HAL_CONF)
+
+$(HAL_CONF): $(HAL_CONF).in
+ $(SED) -e "s@\@HAL_USER\@@$(HAL_USER)@" \
+ < $(HAL_CONF).in > $(HAL_CONF)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/hal/Makefile.hal b/usr/src/cmd/hal/Makefile.hal
new file mode 100644
index 0000000000..57d87e93eb
--- /dev/null
+++ b/usr/src/cmd/hal/Makefile.hal
@@ -0,0 +1,63 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Definitions common for HAL code and consumers
+#
+
+HAL_VERSION = 0.5.8
+
+ROOTLIB_HAL = $(ROOTLIB)/hal
+ROOTLIB_HAL_SCRIPTS = $(ROOTLIB)/hal
+
+ROOT_HAL_FDI = $(ROOT)/etc/hal/fdi
+
+HAL_USER = daemon
+HAL_GROUP = daemon
+
+# derived from the generated config.h
+HAL_CONFIG_CPPFLAGS = -DPACKAGE_DATA_DIR=\"/usr/lib\" \
+ -DPACKAGE_BIN_DIR=\"/usr/bin\" \
+ -DPACKAGE_LIBEXEC_DIR=\"/usr/lib/hal\" \
+ -DPACKAGE_SCRIPT_DIR=\"/usr/lib/hal\" \
+ -DPACKAGE_LOCALSTATEDIR=\"/var\" \
+ -DPACKAGE_SYSCONF_DIR=\"/etc\" \
+ -DPACKAGE_LOCALE_DIR=\"/usr/lib/locale\" \
+ -DPACKAGE_VERSION=\"$(HAL_VERSION)\" \
+ -DPACKAGE_STRING=\""hal $(HAL_VERSION)"\" \
+ -DHALD_PID_FILE=\"/var/run/hald/pid\" \
+ -DHALD_SOCKET_DIR=\"/var/run/hald\" \
+ -DHAVE_POLKIT \
+ -DHWDATA_DIR=\"/usr/share/hwdata\" \
+ -DHAL_USER=\"$(HAL_USER)\" \
+ -DHAL_GROUP=\"$(HAL_GROUP)\"
+
+HAL_DBUS_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE -DDBUS_SYSTEMD_DIR=\"/etc/dbus-1/system.d\" \
+ -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include
+
+HAL_GLIB_CPPFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
+
+HAL_GETTEXT_PACKAGE = $(TEXT_DOMAIN)
+
diff --git a/usr/src/cmd/hal/addons/Makefile b/usr/src/cmd/hal/addons/Makefile
new file mode 100644
index 0000000000..cbc741cac8
--- /dev/null
+++ b/usr/src/cmd/hal/addons/Makefile
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUBDIRS = storage
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+
+.KEEP_STATE:
+
+all install clean clobber: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/cmd/hal/addons/storage/Makefile b/usr/src/cmd/hal/addons/storage/Makefile
new file mode 100644
index 0000000000..3381cf98b2
--- /dev/null
+++ b/usr/src/cmd/hal/addons/storage/Makefile
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = hald-addon-storage
+OBJS = addon-storage.o logger.o
+SRCS = addon-storage.c ../../hald/logger.c
+
+include ../../../Makefile.cmd
+include ../../Makefile.hal
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -ldbus-1 -lhal
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal -I../../hald
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+logger.o: ../../hald/logger.c
+ $(COMPILE.c) -o $@ ../../hald/logger.c
+ $(POST_PROCESS_O)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD)
+
+clean:
+ $(RM) $(OBJS)
+
+FRC:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/hal/addons/storage/addon-storage.c b/usr/src/cmd/hal/addons/storage/addon-storage.c
new file mode 100644
index 0000000000..48d4067803
--- /dev/null
+++ b/usr/src/cmd/hal/addons/storage/addon-storage.c
@@ -0,0 +1,357 @@
+/***************************************************************************
+ *
+ * addon-storage.c : watch removable media state changes
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mnttab.h>
+#include <sys/dkio.h>
+#include <priv.h>
+
+#include <libhal.h>
+
+#include "../../hald/logger.h"
+
+#define SLEEP_PERIOD 5
+
+static void
+my_dbus_error_free(DBusError *error)
+{
+ if (dbus_error_is_set(error)) {
+ dbus_error_free(error);
+ }
+}
+
+static void
+force_unmount (LibHalContext *ctx, const char *udi)
+{
+ DBusError error;
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+ char **options = NULL;
+ unsigned int num_options = 0;
+ DBusConnection *dbus_connection;
+ char *device_file;
+
+ dbus_error_init (&error);
+
+ dbus_connection = libhal_ctx_get_dbus_connection (ctx);
+
+ msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Volume",
+ "Unmount");
+ if (msg == NULL) {
+ HAL_DEBUG (("Could not create dbus message for %s", udi));
+ goto out;
+ }
+
+
+ options = calloc (1, sizeof (char *));
+ if (options == NULL) {
+ HAL_DEBUG (("Could not allocate options array"));
+ goto out;
+ }
+
+ device_file = libhal_device_get_property_string (ctx, udi, "block.device", &error);
+ if (device_file != NULL) {
+ libhal_free_string (device_file);
+ }
+ dbus_error_free (&error);
+
+ if (!dbus_message_append_args (msg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
+ DBUS_TYPE_INVALID)) {
+ HAL_DEBUG (("Could not append args to dbus message for %s", udi));
+ goto out;
+ }
+
+ if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error))) {
+ HAL_DEBUG (("Unmount failed for %s: %s : %s\n", udi, error.name, error.message));
+ goto out;
+ }
+
+ if (dbus_error_is_set (&error)) {
+ HAL_DEBUG (("Unmount failed for %s\n%s : %s\n", udi, error.name, error.message));
+ goto out;
+ }
+
+ HAL_DEBUG (("Succesfully unmounted udi '%s'", udi));
+
+out:
+ dbus_error_free (&error);
+ if (options != NULL)
+ free (options);
+ if (msg != NULL)
+ dbus_message_unref (msg);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+}
+
+static void
+unmount_childs (LibHalContext *ctx, const char *udi)
+{
+ DBusError error;
+ int num_volumes;
+ char **volumes;
+
+ dbus_error_init (&error);
+
+ /* need to force unmount all partitions */
+ if ((volumes = libhal_manager_find_device_string_match (
+ ctx, "block.storage_device", udi, &num_volumes, &error)) != NULL) {
+ dbus_error_free (&error);
+ int i;
+
+ for (i = 0; i < num_volumes; i++) {
+ char *vol_udi;
+
+ vol_udi = volumes[i];
+ if (libhal_device_get_property_bool (ctx, vol_udi, "block.is_volume", &error)) {
+ dbus_error_free (&error);
+ if (libhal_device_get_property_bool (ctx, vol_udi, "volume.is_mounted", &error)) {
+ dbus_error_free (&error);
+ HAL_DEBUG (("Forcing unmount of child '%s'", vol_udi));
+ force_unmount (ctx, vol_udi);
+ }
+ }
+ }
+ libhal_free_string_array (volumes);
+ }
+ my_dbus_error_free (&error);
+}
+
+/** Check if a filesystem on a special device file is mounted
+ *
+ * @param device_file Special device file, e.g. /dev/cdrom
+ * @return TRUE iff there is a filesystem system mounted
+ * on the special device file
+ */
+static dbus_bool_t
+is_mounted (const char *device_file)
+{
+ FILE *f;
+ dbus_bool_t rc = FALSE;
+ struct mnttab mp;
+ struct mnttab mpref;
+
+ if ((f = fopen ("/etc/mnttab", "r")) == NULL)
+ return rc;
+
+ bzero(&mp, sizeof (mp));
+ bzero(&mpref, sizeof (mpref));
+ mpref.mnt_special = (char *)device_file;
+ if (getmntany(f, &mp, &mpref) == 0) {
+ rc = TRUE;
+ }
+
+ fclose (f);
+ return rc;
+}
+
+void
+close_device (int *fd)
+{
+ if (*fd > 0) {
+ close (*fd);
+ *fd = -1;
+ }
+}
+
+void
+drop_privileges ()
+{
+ priv_set_t *pPrivSet = NULL;
+ priv_set_t *lPrivSet = NULL;
+
+ /*
+ * Start with the 'basic' privilege set and then remove any
+ * of the 'basic' privileges that will not be needed.
+ */
+ if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ return;
+ }
+
+ /* Clear privileges we will not need from the 'basic' set */
+ (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
+ (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
+ (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
+
+ /* to open logindevperm'd devices */
+ (void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
+
+ /* Set the permitted privilege set. */
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
+ return;
+ }
+
+ /* Clear the limit set. */
+ if ((lPrivSet = priv_allocset()) == NULL) {
+ return;
+ }
+
+ priv_emptyset(lPrivSet);
+
+ if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
+ return;
+ }
+
+ priv_freeset(lPrivSet);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device_file, *raw_device_file;
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ char *bus;
+ char *drive_type;
+ int state, last_state;
+ char *support_media_changed_str;
+ int support_media_changed;
+ int fd = -1;
+
+ if ((udi = getenv ("UDI")) == NULL)
+ goto out;
+ if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
+ goto out;
+ if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
+ goto out;
+ if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
+ goto out;
+ if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
+ goto out;
+
+ drop_privileges ();
+
+ setup_logger ();
+
+ support_media_changed_str = getenv ("HAL_PROP_STORAGE_CDROM_SUPPORT_MEDIA_CHANGED");
+ if (support_media_changed_str != NULL && strcmp (support_media_changed_str, "true") == 0)
+ support_media_changed = TRUE;
+ else
+ support_media_changed = FALSE;
+
+ dbus_error_init (&error);
+
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ goto out;
+ }
+ my_dbus_error_free (&error);
+
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ goto out;
+ }
+ my_dbus_error_free (&error);
+
+ printf ("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)\n", device_file, bus, drive_type, udi);
+
+ last_state = state = DKIO_NONE;
+
+ /* Linux version of this addon attempts to re-open the device O_EXCL
+ * every 2 seconds, trying to figure out if some other app,
+ * like a cd burner, is using the device. Aside from questionable
+ * value of this (apps should use HAL's locked property or/and
+ * Solaris in_use facility), but also frequent opens/closes
+ * keeps media constantly spun up. All this needs more thought.
+ */
+ for (;;) {
+ if (is_mounted (device_file)) {
+ close_device (&fd);
+ sleep (SLEEP_PERIOD);
+ } else if ((fd < 0) && ((fd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0)) {
+ HAL_DEBUG (("open failed for %s: %s", raw_device_file, strerror (errno)));
+ sleep (SLEEP_PERIOD);
+ } else {
+ /* Check if a disc is in the drive */
+ /* XXX initial call always returns inserted
+ * causing unnecessary rescan - optimize?
+ */
+ if (ioctl (fd, DKIOCSTATE, &state) == 0) {
+ if (state == last_state) {
+ HAL_DEBUG (("state has not changed %d %s", state, device_file));
+ continue;
+ } else {
+ HAL_DEBUG (("new state %d %s", state, device_file));
+ }
+
+ switch (state) {
+ case DKIO_EJECTED:
+ HAL_DEBUG (("Media removal detected on %s", device_file));
+ last_state = state;
+
+ libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
+ my_dbus_error_free (&error);
+
+ /* attempt to unmount all childs */
+ unmount_childs (ctx, udi);
+
+ /* could have a fs on the main block device; do a rescan to remove it */
+ libhal_device_rescan (ctx, udi, &error);
+ my_dbus_error_free (&error);
+ break;
+
+ case DKIO_INSERTED:
+ HAL_DEBUG (("Media insertion detected on %s", device_file));
+ last_state = state;
+
+ libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
+ my_dbus_error_free (&error);
+
+ /* could have a fs on the main block device; do a rescan to add it */
+ libhal_device_rescan (ctx, udi, &error);
+ my_dbus_error_free (&error);
+ break;
+
+ case DKIO_DEV_GONE:
+ HAL_DEBUG (("Device gone detected on %s", device_file));
+ last_state = state;
+
+ unmount_childs (ctx, udi);
+ close_device (&fd);
+ goto out;
+
+ case DKIO_NONE:
+ default:
+ break;
+ }
+ } else {
+ HAL_DEBUG (("DKIOCSTATE failed: %s\n", strerror(errno)));
+ sleep (SLEEP_PERIOD);
+ }
+ }
+ }
+
+out:
+ if (ctx != NULL) {
+ my_dbus_error_free (&error);
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return 0;
+}
diff --git a/usr/src/cmd/hal/fdi/Makefile b/usr/src/cmd/hal/fdi/Makefile
new file mode 100644
index 0000000000..ba5565fe94
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/Makefile
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../../Makefile.cmd
+include ../Makefile.hal
+
+DTDS = fdi.dtd.1
+XMLDIR = $(ROOT)/usr/share/lib/xml/dtd
+ROOTDTDS = $(DTDS:%=$(XMLDIR)/%)
+
+$(ROOTDTDS) := FILEMODE = 444
+$(ROOTDTDS) := OWNER = root
+$(ROOTDTDS) := GROUP = bin
+
+FDIS = information/10freedesktop/10-camera-ptp.fdi \
+ information/10freedesktop/10-cd-dvd-burner.fdi \
+ information/10freedesktop/10-usb-card-readers.fdi \
+ information/10freedesktop/10-usb-music-players.fdi \
+ information/10freedesktop/10-usb-pda.fdi \
+ information/10freedesktop/10-usb-zip-drives.fdi \
+ information/10freedesktop/10-wireless-mice.fdi \
+ policy/10osvendor/10-keyboard-policy.fdi \
+ policy/10osvendor/10-laptop-panel-mgmt-policy.fdi \
+ policy/10osvendor/10-power-mgmt-policy.fdi \
+ policy/10osvendor/10-toshiba-buttons.fdi \
+ policy/10osvendor/20-storage-methods.fdi \
+ policy/10osvendor/20-zfs-methods.fdi \
+ preprobe/10osvendor/10-ide-drives.fdi \
+ preprobe/10osvendor/20-ignore-fixed-storage.fdi \
+ preprobe/10osvendor/20-ignore-lofi.fdi
+FDIDIR = $(ROOT_HAL_FDI)
+ROOTFDIS = $(FDIS:%=$(FDIDIR)/%)
+
+$(ROOTFDIS) := FILEMODE = 444
+$(ROOTFDIS) := OWNER = root
+$(ROOTFDIS) := GROUP = bin
+
+all:
+
+install: $(ROOTDTDS) $(ROOTFDIS)
+
+$(XMLDIR)/%: %
+ $(INS.file)
+
+$(FDIDIR)/%: %
+ $(INS.file)
+
+clean clobber:
+
+FRC:
+
diff --git a/usr/src/cmd/hal/fdi/README b/usr/src/cmd/hal/fdi/README
new file mode 100644
index 0000000000..fa184ff744
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/README
@@ -0,0 +1,80 @@
+
+This file describe the layout of device information files in the hal
+source tree and their three different applications. It should serve as
+a brief guide for IHV's and third party open source projects on how to
+integrate with hal.
+
+Said third parties need to name their files in a unique manner using
+the following format: <organization>-[<model>]-[<purpose>].fdi. As a
+device information file can be used to match several models the model
+field may be omitted (the <purpose> field may be useful if the <model>
+field is omitted). The filename of a device information file must
+contain only lowercase alphanumeric characters, the '-' and '_'
+characters, and not any whitespace.
+
+Device information files are processed in the following order:
+
+1. Preprobing
+-------------
+
+Contains device information files that are used to handle exceptional
+conditions such as telling hal to ignore a device and all children
+(using info.ignore), run programs to upload firmware or configure
+the device in an otherwise non-standard way that is incompatible with
+probing routines in hal (using info.callouts.preprobing) [1].
+
+These files are processed BEFORE the device have been been probed.
+
+Subdirs are installed in $(sysconfdir)/hal/preprobe (e.g. /etc/hal/preprobe)
+
+ preprobe
+ |-- 10osvendor # From the hal tarball and/or supplied by the os vendor
+ | # -> installs into /usr/share/hal/fdi/preprobe/10osvendor
+ |-- 20thirdparty # 3rd party projects and IHV's install here
+ | # -> installs into /usr/share/hal/fdi/preprobe/20thirdparty
+ `-- 30user # Installed by the user/admin
+ # -> installs into /etc/hal/fdi/preprobe/
+
+[1] : http://lists.freedesktop.org/archives/hal/2004-August/000858.html
+
+2. Information
+--------------
+
+Contains device information files that describe hardware such as what
+kind of media a card reader uses (compact flash, memorystick etc),
+what out-of-tree kernel drivers are needed, whether the device is a
+camera and not just a harddrive.
+
+These files are processed AFTER the device have been probed but before
+any policy device information files.
+
+Subdirs are installed in $(datadir)/hal/fdi (e.g. /usr/share/hal/fdi)
+
+ information
+ |-- 10freedesktop # From the hal tarball
+ | # -> installs into /usr/share/hal/fdi/information/10freedesktop
+ |-- 20thirdparty # 3rd party projects and IHV's install here
+ | # -> installs into /usr/share/hal/fdi/information/20thirdparty
+ `-- 30user # Installed by the user/admin
+ # -> installs into /etc/hal/fdi/information
+
+
+3. Policy
+---------
+
+Contains device information files that describe policy for hardware
+such as what callouts and addons to run for a device.
+
+These files are processed AFTER the device have been been probed and
+also AFTER the information device files have been processed
+
+Subdirs are installed in $(sysconfdir)/hal/policy (e.g. /etc/hal/policy)
+
+ policy
+ |-- 10osvendor # From the hal tarball and/or supplied by the os vendor
+ | # -> installs into /usr/share/hal/fdi/policy/10freedesktop
+ |-- 20thirdparty # 3rd party projects and IHV's install here
+ | # -> installs into /usr/share/hal/fdi/policy/20thirdparty
+ `-- 30user # Installed by the user/admin
+ # -> installs into /etc/hal/fdi/policy
+
diff --git a/usr/src/cmd/hal/fdi/fdi.dtd.1 b/usr/src/cmd/hal/fdi/fdi.dtd.1
new file mode 100644
index 0000000000..bb3e3e18d9
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/fdi.dtd.1
@@ -0,0 +1,57 @@
+<!-- Document Type for FreeDesktop.org Device Information Files -->
+<!-- CVSID: $Id$ -->
+
+<!-- <deviceinfo> is the top-level element of an fdi file. -->
+<!ELEMENT deviceinfo (device*) >
+<!ATTLIST deviceinfo
+ version (0.1|0.2) #REQUIRED
+>
+
+<!ELEMENT device (match|merge)* >
+
+<!ELEMENT match (match|merge|prepend|append|remove|spawn)* >
+<!ATTLIST match
+ key CDATA #REQUIRED
+ string CDATA #IMPLIED
+ int CDATA #IMPLIED
+ bool (false|true) #IMPLIED
+ exists (false|true) #IMPLIED
+ empty (false|true) #IMPLIED
+ is_ascii (false|true) #IMPLIED
+ is_absolute_path (false|true) #IMPLIED
+ contains CDATA #IMPLIED
+ contains_ncase CDATA #IMPLIED
+ compare_lt CDATA #IMPLIED
+ compare_le CDATA #IMPLIED
+ compare_gt CDATA #IMPLIED
+ compare_ge CDATA #IMPLIED
+>
+
+<!ELEMENT merge (#PCDATA) >
+<!ATTLIST merge
+ key CDATA #REQUIRED
+ type (string|int|uint64|bool|double|strlist|copy_property) #REQUIRED
+>
+
+<!ELEMENT prepend (#PCDATA) >
+<!ATTLIST prepend
+ key CDATA #REQUIRED
+ type (string|strlist|int|bool|double|copy_property) #REQUIRED
+>
+
+<!ELEMENT append (#PCDATA) >
+<!ATTLIST append
+ key CDATA #REQUIRED
+ type (string|strlist|int|bool|double|copy_property) #REQUIRED
+>
+
+<!ELEMENT remove (#PCDATA) >
+<!ATTLIST remove
+ key CDATA #REQUIRED
+ type (strlist) #REQUIRED
+>
+
+<!ELEMENT spawn (#PCDATA) >
+<!ATTLIST spawn
+ udi CDATA #REQUIRED
+>
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-camera-ptp.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-camera-ptp.fdi
new file mode 100644
index 0000000000..9879725278
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-camera-ptp.fdi
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+ <device>
+ <match key="info.bus" string="usb">
+ <match key="usb.interface.class" int="0x06">
+ <match key="usb.interface.subclass" int="0x01">
+ <match key="usb.interface.protocol" int="0x01">
+ <merge key="info.category" type="string">camera</merge>
+ <append key="info.capabilities" type="strlist">camera</append>
+ <merge key="camera.access_method" type="string">ptp</merge>
+ </match>
+ </match>
+ </match>
+ </match>
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-cd-dvd-burner.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-cd-dvd-burner.fdi
new file mode 100644
index 0000000000..0cb920f37b
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-cd-dvd-burner.fdi
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <device>
+
+ <!-- Handle broken CD/DVD burner which reports from capabilities.
+ Taken from nautilus-cd-burner-2.12. (fd.o Bug #3036) -->
+ <match key="storage.model" string="IOMEGA - CDRW9602EXT-B">
+ <merge key="storage.cdrom.cdr" type="bool">true</merge>
+ <merge key="storage.cdrom.cdrw" type="bool">true</merge>
+ <merge key="storage.cdrom.dvdr" type="bool">false</merge>
+ <merge key="storage.cdrom.dvdram" type="bool">false</merge>
+ </match>
+ <match key="storage.model" string="SONY - CD-R CDU948S">
+ <merge key="storage.cdrom.cdr" type="bool">true</merge>
+ <merge key="storage.cdrom.cdrw" type="bool">false</merge>
+ <merge key="storage.cdrom.dvdr" type="bool">false</merge>
+ <merge key="storage.cdrom.dvdram" type="bool">false</merge>
+ </match>
+
+ <!-- Handle TEAC CD-R55S, taken from :
+ http://lists.freedesktop.org/archives/hal/2005-November/003925.html -->
+ <match key="storage.vendor" string="TEAC">
+ <match key="storage.model" string="CD-R55S">
+ <merge key="storage.cdrom.cdr" type="bool">true</merge>
+ </match>
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-card-readers.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-card-readers.fdi
new file mode 100644
index 0000000000..5802445390
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-card-readers.fdi
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- xml -*- -->
+
+<deviceinfo version="0.2">
+ <device>
+
+ <!-- Should probably move to separate file for pcmcia devices -->
+ <match key="storage.bus" string="pcmcia">
+ <match key="storage.model" contains="FLASH">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ </match>
+
+ <!-- Should probably move to separate file for firewire devices -->
+ <match key="storage.bus" string="ieee1394">
+ <match key="storage.model" string="FWIRE CF READER">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ </match>
+
+ <!-- Generic catch all -->
+ <match key="storage.bus" string="usb">
+ <match key="storage.model" contains="HS-CF">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ <match key="storage.model" contains="HS-MS">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ </match>
+ <match key="storage.model" contains="HS-SM">
+ <merge key="storage.drive_type" type="string">smart_media</merge>
+ </match>
+ <match key="storage.model" contains="HS-SD/MMC">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+
+ <!-- Another common theme -->
+ <match key="storage.model" contains="USB CF Reader">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ <match key="storage.model" contains="USB MS Reader">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ </match>
+ <match key="storage.model" contains="USB SM Reader">
+ <merge key="storage.drive_type" type="string">smart_media</merge>
+ </match>
+ <match key="storage.model" contains="USB SD Reader">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+
+ <!-- Yet another common theme -->
+ <match key="storage.model" contains="Reader-CF">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ <match key="storage.model" contains="Reader-MS">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ </match>
+ <match key="storage.model" contains="Reader-SM">
+ <merge key="storage.drive_type" type="string">smart_media</merge>
+ </match>
+ <match key="storage.model" contains="Reader-SD">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+
+ <!-- Yet another common theme -->
+ <match key="storage.model" contains="Storage-CFC">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ <match key="storage.model" contains="Storage-MSC">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ </match>
+ <match key="storage.model" contains="Storage-SMC">
+ <merge key="storage.drive_type" type="string">smart_media</merge>
+ </match>
+ <match key="storage.model" contains="Storage-MMC">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+ <match key="storage.model" contains="Storage-SDC">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+
+ <!-- Some noname USB2.0 Card Reader -->
+ <match key="storage.model" string="IC1210 CF">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ <match key="storage.model" string="IC1210 MS">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ </match>
+ <match key="storage.model" string="IC1210 SM">
+ <merge key="storage.drive_type" type="string">smart_media</merge>
+ </match>
+ <match key="storage.model" string="IC1210 MMC/SD">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+
+ <!-- Lexar CF Reader -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x05dc">
+ <match key="@storage.physical_device:usb.product_id" int="0x0002">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ </match>
+
+ <!-- SanDisk ImageMate II CF Reader -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x0781">
+ <match key="@storage.physical_device:usb.product_id" int="0x0002">
+ <merge key="storage.drive_type" type="string">compact_flash</merge>
+ </match>
+ </match>
+
+ <!-- Sony Ericsson Handys with Memory Stick (Duo) -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0xfce">
+ <!-- K750i -->
+ <match key="@storage.physical_device:usb.product_id" int="0xd016">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ <merge key="info.vendor" type="copy_property">@storage.physical_device:usb.vendor</merge>
+ <merge key="storage.vendor" type="copy_property">@storage.physical_device:usb.vendor</merge>
+ </match>
+ <!-- General match-->
+ <match key="storage.model" contains="Memory Stick">
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ <merge key="info.vendor" type="copy_property">@storage.physical_device:usb.vendor</merge>
+ <merge key="storage.vendor" type="copy_property">@storage.physical_device:usb.vendor</merge>
+ </match>
+ </match>
+
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-music-players.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-music-players.fdi
new file mode 100644
index 0000000000..519498272d
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-music-players.fdi
@@ -0,0 +1,1025 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+ <device>
+
+ <match key="info.category" string="storage">
+ <!-- Apple iPod - TODO: use USB ids to determine exact output formats -->
+ <match key="storage.vendor" contains="Apple">
+ <match key="storage.model" contains="iPod">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.type" type="string">ipod</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/aac</append>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ </match>
+ </match>
+
+ <!-- Sony PSP (PlayStation Portable) -->
+ <match key="storage.vendor" string="Sony">
+ <match key="storage.model" string="PSP">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.type" type="string">psp</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/vnd.sony.atrac3</append>
+ <merge key="storage.drive_type" type="string">memory_stick</merge>
+ </match>
+ </match>
+
+ <!-- USB Mass Storage devices that are music players -->
+
+ <match key="@storage.physical_device:info.bus" string="usb">
+ <!-- Creative -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x41e">
+ <!-- MuVo NX -->
+ <match key="@storage.physical_device:usb.product_id" int="0x4115">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- MuVo2 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x4116">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Creative MuVo TX -->
+ <match key="@storage.physical_device:usb.product_id" int="0x4117">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Zen Micro -->
+ <match key="@storage.physical_device:usb.product_id" int="0x411e">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- NOMAD Jukebox Zen Xtra -->
+ <match key="@storage.physical_device:usb.product_id" int="0x4128">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- MuVo V200 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x4129">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- MuVo N200 (MuVo Micro) -->
+ <match key="@storage.physical_device:usb.product_id" int="0x412b">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Zen Micro -->
+ <match key="@storage.physical_device:usb.product_id" int="0x4130">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- SONICblue -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x045a">
+ <!-- Rio Forge -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5042">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/audible</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <match key="storage.lun" int="1">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+ </match>
+ <!-- Rio Karma -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5210">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Rio Carbon -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5224">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!--Panasonic -->
+ <match key="@storage.physical_deviceusb.vendor_id" int="0x4da">
+ <!--Panasonic SV-MP31V-->
+ <match key="@storage.physical_deviceusb.product_id" int="0x3701">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">PLAYER/</append>
+ </match>
+ </match>
+
+ <!-- Samsung -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x04e8">
+ <!-- Samsung Yepp YP-35 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5010">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Samsung Yepp YP-ST5 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5021">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- YP-F1 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x502b">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- Samsung YP-U1 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x503b">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC/</append>
+ </match>
+ <!-- Samsung YP-Z5 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5041">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">Music/</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-scpls</append>
+ <append key="portable_audio_player.playlist_path" type="strlist">Playlists/</append>
+ </match>
+ <!-- Samsung YP-U2Z -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5050">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- Sony -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x54c">
+ <!-- Sony Network Walkman -->
+ <match key="@storage.physical_device:usb.product_id" int="0x1fb">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/vnd.sony.atrac3</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ </match>
+
+ <!-- Jetflash MP3 Player, AKA NAPA LCD-HD, AKA Medion, AKA Tevion -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x066f">
+ <match key="@storage.physical_device:usb.product_id" int="0x8000">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- EXATEL i-BEAD100 Player -->
+ <match key="@storage.physical_device:usb.product_id" int="0x8008">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Traxdata Digital Audio Player -->
+ <match key="@storage.physical_device:usb.product_id" int="0x8038">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <match key="storage.lun" int="1">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+ </match>
+ <!-- TrekStor i.Beat 115 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x829c">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Medion MD41512 / Tevion 41512 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x8206">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- Jens of Sweeden (JoS) MP-120 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x82d4">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ </match>
+
+ <!-- RCA -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x69b">
+ <!-- Lyra RD2212 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x718">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/audible</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- SanDisk -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x781">
+ <!-- Sansa e130 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x7301">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/audible</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- Peak Digital Audio Player -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0xd7d">
+ <match key="@storage.physical_device:usb.product_id" int="0x1651">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <match key="storage.lun" int="1">
+ <merge key="storage.drive_type" type="string">sd_mmc</merge>
+ </match>
+ </match>
+ </match>
+
+ <!-- Cowon -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0xe21">
+ <!-- iAudio M3 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x500">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/flac</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC/</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="strlist">PLAYLIST/%File</append>
+ </match>
+ <!-- iAudio X5 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x510">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/flac</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC/</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="strlist">PLAYLIST/%File</append>
+ </match>
+ <!-- iAudio M5 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x520">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/flac</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC/</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="strlist">PLAYLIST/%File</append>
+ </match>
+ <!-- iAudio G3 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x601">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.playlist_formats" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="string">PLAYLIST/%File</append>
+ </match>
+ <!-- iAudio 5 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x602">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/flac</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC/</append>
+ </match>
+ <!-- iAudio G2 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x604">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/flac</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC/</append>
+ </match>
+ <!-- iAudio U3 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x700">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/flac</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">VOICE</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">RECORD</append>
+ <append key="portable_audio_player.playlist_formats" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="string">PLAYLIST/%File</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">MUSIC</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">RECORDS/FM</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">RECORDS/LINEIN</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">RECORDS/VOICE</append>
+ </match>
+ </match>
+
+ <!-- Archos -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0xe79">
+ <!-- Archos GMini 400 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x1109">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">Music/</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="strlist">Playlist/</append>
+ </match>
+ <!-- Archos XS 100 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x1205">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- Sony Ericsson -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0xfce">
+ <!-- K750i mobile phone -->
+ <match key="@storage.physical_device:usb.product_id" int="0xd016">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+
+ <!-- W800 Walkman Phone -->
+ <!-- media files go in mp3/$ARTIST/$ALBUM/$TRACKNAME -->
+ <match key="@storage.physical_device:usb.product_id" int="0xd028">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/aac</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <match key="@storage.physical_device:usb.vendor_id" int="0x1006">
+ <!-- iGP 100 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x2001">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iHP-100,115 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x3001">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- HP-120,140 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x3002">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- H320, H340 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x3003">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ </match>
+
+ <!-- TouchStone/WaveX -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x10c7">
+ <!-- TS-300 -->
+ <match key="@storage.physical_device:usb.product_id" int="0xc000">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- Foston -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x10d6">
+ <!-- Foston 256MB -->
+ <match key="@storage.physical_device:usb.product_id" int="0x1100">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- Jens of Sweden -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x1332">
+ <!-- MP-130 -->
+ <match key="@storage.physical_device:usb.product_id" int="0x1325">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- MSI -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x1462">
+ <!-- MegaStick-1 Flash Stick -->
+ <match key="@storage.physical_device:usb.product_id" int="0x5512">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- Motorola -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x22b8">
+ <!-- ROKR e2 Memory Card mode -->
+ <match key="@storage.physical_device:usb.product_id" int="0x608d">
+ <merge key="storage.model" type="string">ROKR e2</merge>
+ <merge key="storage.vendor" type="string">Motorola</merge>
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/aac</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ </match>
+
+ <!-- iRiver -->
+ <match key="@storage.physical_device:usb.vendor_id" int="0x4102">
+ <!-- T30 UMS -->
+ <match key="@storage.physical_device:usb.product_id" int="0x1018">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 100 UMS (supports application/ogg only after firmware upgrade)-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1101">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 300 UMS (supports application/ogg only after firmware upgrade)-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1103">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 500 UMS (supports application/ogg only after firmware upgrade)-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1105">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 700 UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1107">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 800 UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1108">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 900 UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1109">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 1000 UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1110">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- N10 UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x1111">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- H10 20GB UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x2001">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- H10 5GB UMS-->
+ <match key="@storage.physical_device:usb.product_id" int="0x2002">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">storage</merge>
+ <merge key="portable_audio_player.storage_device" type="copy_property">info.udi</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+
+ </match>
+ </match>
+ </match>
+
+ <!-- USB devices that are music players but uses a user-space library -->
+
+ <match key="info.bus" string="usb">
+ <!-- Archos -->
+ <match key="usb.vendor_id" int="0xe79">
+ <!-- GMini 120 -->
+ <match key="usb.product_id" int="0x1201">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ </match>
+ <!-- GMini XS202 -->
+ <match key="usb.product_id" int="0x1206">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/x-wav</append>
+ <append key="portable_audio_player.audio_folders" type="strlist">Music/</append>
+ <append key="portable_audio_player.playlist_format" type="strlist">audio/x-mpegurl</append>
+ <append key="portable_audio_player.playlist_path" type="strlist">Playlists/%File</append>
+ </match>
+ </match>
+
+ <match key="usb.vendor_id" int="0x1006">
+ <!-- iDP 100 UMS-->
+ <match key="usb.product_id" int="0x0001">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ </match>
+ </match>
+ <match key="usb.vendor_id" int="0x4102">
+ <!-- iFP 100 IMM (supports application/ogg only after firmware upgrade)-->
+ <match key="usb.product_id" int="0x1001">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 300 IMM (supports application/ogg only after firmware upgrade)-->
+ <match key="usb.product_id" int="0x1003">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 500 IMM (supports application/ogg only after firmware upgrade)-->
+ <match key="usb.product_id" int="0x1005">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 700 IMM-->
+ <match key="usb.product_id" int="0x1007">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 800 IMM-->
+ <match key="usb.product_id" int="0x1008">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 900 IMM-->
+ <match key="usb.product_id" int="0x1009">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- iFP 1000 IMM-->
+ <match key="usb.product_id" int="0x1010">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- N10 IMM-->
+ <match key="usb.product_id" int="0x1011">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- H10 20GB MTP-->
+ <match key="usb.product_id" int="0x2101">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- H10 5GB MTP-->
+ <match key="usb.product_id" int="0x2102">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ <!-- H10 5,6GB MTP-->
+ <match key="usb.product_id" int="0x2105">
+ <append key="info.capabilities" type="strlist">portable_audio_player</append>
+ <merge key="info.category" type="string">portable_audio_player</merge>
+ <merge key="portable_audio_player.type" type="string">generic</merge>
+ <merge key="portable_audio_player.access_method" type="string">user</merge>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/mpeg</append>
+ <append key="portable_audio_player.output_formats" type="strlist">audio/x-ms-wma</append>
+ <append key="portable_audio_player.output_formats" type="strlist">application/ogg</append>
+ <append key="portable_audio_player.input_formats" type="strlist">audio/mpeg</append>
+ </match>
+ </match>
+
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-pda.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-pda.fdi
new file mode 100644
index 0000000000..1133f5e3dd
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-pda.fdi
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <!-- Pocket PC PDAs -->
+ <device>
+ <match key="info.capabilities" contains="serial">
+ <match key="@serial.physical_device:info.linux.driver" string="ipaq">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">pocketpc</merge>
+ <merge key="info.product" type="string">Pocket PC PDA</merge>
+ <merge key="pda.pocketpc.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ </device>
+
+ <!--
+ on Sony Clie 3.5 devices we need to mark port 0 instead of port 1. For
+ this reason, we mark the usb interface with port number to use (FIXME: is
+ there a better solution?). However, we should also do this for clies that
+ have been upgraded to a later version of OS, but I'm not sure if those have
+ the same product id - in that case this would not work for them. The driver
+ doumentation however advertises that the information about what port should
+ be used is written to syslog, perhaps we can somehow get that information
+ from the driver directly?)
+ -->
+ <device>
+ <match key="info.capabilities" contains="serial">
+ <match key="@serial.physical_device:info.linux.driver" string="visor">
+ <match key="@serial.physical_device:usb.vendor_id" int="0x054c">
+ <!-- Sony Clie 3.5 -->
+ <match key="@serial.physical_device:usb.product_id" int="0x0038">
+ <match key="serial.port" int="0">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ <!-- Sony Clie SJ-22 -->
+ <match key="@serial.physical_device:usb.product_id" int="0x0066">
+ <match key="serial.port" int="0">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ </match>
+ </match>
+ </match>
+ </device>
+
+ <!-- Handspring -->
+ <device>
+ <match key="info.capabilities" contains="serial">
+ <match key="@serial.physical_device:info.linux.driver" string="visor">
+ <match key="@serial.physical_device:usb.vendor_id" int="0x082d">
+ <!-- Visor -->
+ <match key="@serial.physical_device:usb.product_id" int="0x0100">
+ <match key="serial.port" int="1">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ </match>
+ </match>
+ </match>
+ </device>
+
+ <!-- Known Palm PDAs from Palm, Inc. -->
+ <device>
+ <match key="info.capabilities" contains="serial">
+ <match key="@serial.physical_device:info.linux.driver" string="visor">
+ <match key="@serial.physical_device:usb.vendor_id" int="0x0830">
+ <!-- Palm m130 -->
+ <match key="@serial.physical_device:usb.product_id" int="0x0050">
+ <match key="serial.port" int="0">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ <!-- Tungsten T5 -->
+ <match key="@serial.physical_device:usb.product_id" int="0x0061">
+ <match key="serial.port" int="1">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ </match>
+ </match>
+ </match>
+ </device>
+
+ <!-- All the other PalmOS PDAs as fallback -->
+ <device>
+ <match key="info.capabilities" contains="serial">
+ <match key="@serial.physical_device:info.linux.driver" string="visor">
+ <match key="pda.platform" exists="false">
+ <match key="serial.port" int="0">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ <match key="serial.port" int="1">
+ <append key="info.capabilities" type="strlist">pda</append>
+ <merge key="pda.platform" type="string">palm</merge>
+ <merge key="pda.palm.hotsync_interface" type="copy_property">serial.device</merge>
+ </match>
+ </match>
+ </match>
+ </match>
+ </device>
+
+</deviceinfo>
+
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-zip-drives.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-zip-drives.fdi
new file mode 100644
index 0000000000..bf2f64c80a
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-usb-zip-drives.fdi
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+ <device>
+
+ <!-- USB Zip Drives -->
+ <match key="storage.bus" string="usb">
+ <match key="storage.drive_type" string="disk">
+ <match key="storage.vendor" string="IOMEGA">
+ <match key="storage.model" contains_ncase="ZIP">
+ <merge key="storage.drive_type" type="string">zip</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ </match>
+ </match>
+ </match>
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/information/10freedesktop/10-wireless-mice.fdi b/usr/src/cmd/hal/fdi/information/10freedesktop/10-wireless-mice.fdi
new file mode 100644
index 0000000000..4a7f3ed57a
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/information/10freedesktop/10-wireless-mice.fdi
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deviceinfo version="0.2">
+ <device>
+ <match key="info.bus" string="usb_device">
+ <match key="usb_device.vendor_id" int="0x046d"> <!-- Logitech, Inc. -->
+
+ <!-- Receiver for MX1000 Laser -->
+ <match key="usb_device.product_id" int="0xc50e">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">MX1000 Laser Mouse</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Receiver for Cordless Click! -->
+ <match key="usb_device.product_id" int="0xc510">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Cordless Click Mouse</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Receiver for Cordless Keyboard + Mouse combo -->
+ <match key="usb_device.product_id" int="0xc512">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Cordless Keyboard+Mouse Receiver</merge>
+ <merge key="battery.type" type="string">keyboard</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Logitech, Inc. Cordless Mouse+Keyboard Receiver -->
+ <match key="usb_device.product_id" int="0xc505">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Cordless Mouse+Keyboard Receiver</merge>
+ <merge key="battery.type" type="string">keyboard</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Mouse Receiver -->
+ <match key="usb_device.product_id" int="0xc501">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Mouse Receiver</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Dual Receiver -->
+ <match key="usb_device.product_id" int="0xc502">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Logitech Dual Receiver</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">true</merge>
+ </match>
+
+ <!-- Receiver for Cordless Freedom Optical -->
+ <match key="usb_device.product_id" int="0xc504">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Cordless Freedom Optical Mouse</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">true</merge>
+ </match>
+
+ <!-- Receiver for MX700 Optical Mouse -->
+ <match key="usb_device.product_id" int="0xc506">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">MX700 Optical Mouse</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">true</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Receiver for Cordless Optical TrackMan -->
+ <match key="usb_device.product_id" int="0xc508">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Cordless Optical TrackMan</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">true</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ <!-- Receiver for Cordless Presenter -->
+ <match key="usb_device.product_id" int="0xc702">
+ <append key="info.addons" type="strlist">hald-addon-usb-csr</append>
+ <merge key="info.product" type="string">Cordless Presenter</merge>
+ <merge key="battery.type" type="string">mouse</merge>
+ <merge key="battery.is_rechargeable" type="bool">true</merge>
+ <!-- proprietary properties defining the behavior -->
+ <merge key="battery.csr.has_res" type="bool">false</merge>
+ <merge key="battery.csr.has_sms" type="bool">false</merge>
+ <merge key="battery.csr.is_dual" type="bool">false</merge>
+ </match>
+
+ </match>
+ </match>
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/10-keyboard-policy.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/10-keyboard-policy.fdi
new file mode 100644
index 0000000000..4bae7c6d98
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/10-keyboard-policy.fdi
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <device>
+ <match key="info.capabilities" contains="input.keyboard">
+ <append key="info.addons" type="strlist">hald-addon-keyboard</append>
+ <append key="info.capabilities" type="strlist">button</append>
+ <merge key="button.type" type="string"></merge>
+ <merge key="button.has_state" type="bool">false</merge>
+ </match>
+ </device>
+
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi
new file mode 100644
index 0000000000..f59fbdd069
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <device>
+ <match key="info.category" string="laptop_panel">
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.LaptopPanel</append>
+
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_names" type="strlist">SetBrightness</append>
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_signatures" type="strlist">i</append>
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_argnames" type="strlist">brightness_value</append>
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_execpaths" type="strlist">hal-system-lcd-set-brightness</append>
+
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_names" type="strlist">GetBrightness</append>
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.LaptopPanel.method_execpaths" type="strlist">hal-system-lcd-get-brightness</append>
+ </match>
+ </device>
+
+ <!-- On some borken laptops, the brightness control is all done in hardware
+ but the hardware also synthesizes keypresses when the brightness is
+ changed. This gives power manager software problems as the brightness
+ can get into a feedback state so the panel flashes uncontrollably.
+ This is a hardware "feature" seen on IBM x31 laptops. -->
+ <device>
+ <match key="info.category" string="laptop_panel">
+ <match key="/org/freedesktop/Hal/devices/computer:smbios.system.manufacturer" string="IBM">
+ <match key="/org/freedesktop/Hal/devices/computer:smbios.system.version" string="ThinkPad X31">
+ <merge key="laptop_panel.brightness_in_hardware" type="bool">true</merge>
+ </match>
+ </match>
+ </match>
+ </device>
+
+ <!-- this is for Macbook Pro (LCD panel, light sensor, keyboard backlight) -->
+ <device>
+ <match key="system.kernel.name" string="Linux">
+ <match key="smbios.system.manufacturer" string="Apple Computer, Inc.">
+ <match key="smbios.system.product" string="MacBookPro1,1">
+ <spawn udi="/org/freedesktop/Hal/devices/macbook_pro_light_sensor"/>
+ <spawn udi="/org/freedesktop/Hal/devices/macbook_pro_keyboard_backlight"/>
+ <spawn udi="/org/freedesktop/Hal/devices/macbook_pro_lcd_panel"/>
+ </match>
+ </match>
+ </match>
+ </device>
+ <device>
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/macbook_pro_lcd_panel">
+ <append key="info.capabilities" type="strlist">laptop_panel</append>
+ <merge key="info.product" type="string">MacBook Pro Laptop Panel</merge>
+ <merge key="laptop_panel.access_method" type="string">custom</merge>
+ <merge key="laptop_panel.num_levels" type="int">229</merge>
+ <append key="info.addons" type="strlist">hald-addon-macbookpro-backlight</append>
+ </match>
+ </device>
+ <device>
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/macbook_pro_light_sensor">
+ <append key="info.capabilities" type="strlist">light_sensor</append>
+ <merge key="info.product" type="string">MacBook Pro Light Sensor</merge>
+ <merge key="light_sensor.num_sensors" type="int">2</merge>
+ <merge key="light_sensor.num_levels" type="int">256</merge>
+ <append key="light_sensor.sensor_locations" type="strlist">right</append>
+ <append key="light_sensor.sensor_locations" type="strlist">left</append>
+ </match>
+ </device>
+ <device>
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/macbook_pro_keyboard_backlight">
+ <append key="info.capabilities" type="strlist">keyboard_backlight</append>
+ <merge key="info.product" type="string">MacBook Pro Keyboard Backlight</merge>
+ <merge key="keyboard_backlight.num_levels" type="int">256</merge>
+ </match>
+ </device>
+
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi
new file mode 100644
index 0000000000..2c2705ab4d
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <device>
+ <match key="hiddev.application_pages" contains="Power Device Page">
+ <append key="info.addons" type="strlist">hald-addon-hid-ups</append>
+ </match>
+ </device>
+
+ <device>
+ <match key="power_management.type" string="acpi">
+ <append key="info.addons" type="strlist">hald-addon-acpi</append>
+ </match>
+ </device>
+
+ <device>
+ <match key="button.type" string="lid">
+ <match key="linux.pmu_type" exists="true">
+ <append key="info.addons" type="strlist">hald-addon-pmu</append>
+ </match>
+ </match>
+ </device>
+
+ <device>
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.SystemPowerManagement</append>
+
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_names" type="strlist">Suspend</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_signatures" type="strlist">i</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_argnames" type="strlist">num_seconds_to_sleep</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_execpaths" type="strlist">hal-system-power-suspend</append>
+
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_names" type="strlist">Hibernate</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_execpaths" type="strlist">hal-system-power-hibernate</append>
+
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_names" type="strlist">Shutdown</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_execpaths" type="strlist">hal-system-power-shutdown</append>
+
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_names" type="strlist">Reboot</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_execpaths" type="strlist">hal-system-power-reboot</append>
+
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_names" type="strlist">SetPowerSave</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_signatures" type="strlist">b</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_argnames" type="strlist">enable_power_save</append>
+ <append key="org.freedesktop.Hal.Device.SystemPowerManagement.method_execpaths" type="strlist">hal-system-power-set-power-save</append>
+ </match>
+ </device>
+
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi
new file mode 100644
index 0000000000..b2e83d7e51
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <!-- Only launch the addon for Toshiba laptops. -->
+ <device>
+ <match key="smbios.system.manufacturer" string="TOSHIBA">
+ <match key="system.formfactor" string="laptop">
+ <append key="info.addons" type="strlist">hald-addon-acpi-buttons-toshiba</append>
+ <append key="info.capabilities" type="strlist">button</append>
+ </match>
+ </match>
+ </device>
+
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/20-storage-methods.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/20-storage-methods.fdi
new file mode 100644
index 0000000000..bd85ed7fba
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/20-storage-methods.fdi
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+ <device>
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
+ <append key="info.callouts.add" type="strlist">hal-storage-cleanup-all-mountpoints</append>
+ </match>
+
+ <match key="storage.media_check_enabled" bool="true">
+ <append key="info.addons" type="strlist">hald-addon-storage</append>
+ </match>
+
+ <match key="volume.is_disc" bool="true">
+ <match key="volume.disc.has_audio" bool="true">
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Volume</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Eject</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-eject</append>
+ </match>
+ <match key="volume.disc.is_blank" bool="true">
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Volume</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Eject</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-eject</append>
+ </match>
+ </match>
+
+ <!-- this is to be able to mount media in drives we cannot poll, e.g. IDE Zip Drives and PC style floppy drives -->
+ <match key="storage.media_check_enabled" bool="false">
+ <match key="storage.no_partitions_hint" bool="true">
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Volume</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Mount</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">ssas</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">mount_point fstype extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-mount</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Unmount</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-unmount</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Eject</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-eject</append>
+
+ <!-- allow these mount options for all file systems -->
+ <append key="volume.mount.valid_options" type="strlist">ro</append>
+ <append key="volume.mount.valid_options" type="strlist">sync</append>
+ <append key="volume.mount.valid_options" type="strlist">dirsync</append>
+ <append key="volume.mount.valid_options" type="strlist">noatime</append>
+ <append key="volume.mount.valid_options" type="strlist">nodiratime</append>
+ <append key="volume.mount.valid_options" type="strlist">noexec</append>
+ <append key="volume.mount.valid_options" type="strlist">quiet</append>
+ <append key="volume.mount.valid_options" type="strlist">remount</append>
+ <append key="volume.mount.valid_options" type="strlist">exec</append>
+ <!-- As this is removable media give some leeway -->
+ <append key="volume.mount.valid_options" type="strlist">utf8</append>
+ <append key="volume.mount.valid_options" type="strlist">shortname=</append>
+ <append key="volume.mount.valid_options" type="strlist">codepage=</append>
+ <append key="volume.mount.valid_options" type="strlist">iocharset=</append>
+ <append key="volume.mount.valid_options" type="strlist">umask=</append>
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+
+ </match>
+ </match>
+
+
+ <match key="volume.fsusage" string="filesystem">
+
+ <!-- Here follow volumes we specifically want to ignore - it is the -->
+ <!-- responsibility of software higher in the stack (e.g. gnome-vfs) -->
+ <!-- amd mount programs (e.g. Mount() on HAL) to respect volume.ignore -->
+ <merge key="volume.ignore" type="bool">false</merge>
+
+ <match key="@block.storage_device:storage.removable" bool="false">
+
+ <!-- Should always ignore Apple Bootstrap partitions (it would be -->
+ <!-- a security hole to mount it) - TODO: should use the bootable -->
+ <!-- flag from the Mac partition table instead -->
+ <match key="volume.fstype" string="hfs">
+ <match key="volume.label" string="bootstrap">
+ <merge key="volume.ignore" type="bool">true</merge>
+ </match>
+ </match>
+
+ <!-- HP ships desktops with a recovery partition -->
+ <match key="volume.fstype" string="vfat">
+ <match key="volume.label" string="HP_RECOVERY">
+ <merge key="volume.ignore" type="bool">true</merge>
+ </match>
+ </match>
+
+ <!-- EFI firmware partitions -->
+ <match key="volume.fstype" string="vfat">
+ <match key="volume.label" string="EFI">
+ <merge key="volume.ignore" type="bool">true</merge>
+ </match>
+ </match>
+
+ </match>
+
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Volume</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Mount</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">ssas</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">mount_point fstype extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-mount</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Unmount</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-unmount</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">Eject</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-eject</append>
+
+ <!-- allow these mount options for all file systems -->
+ <append key="volume.mount.valid_options" type="strlist">ro</append>
+ <append key="volume.mount.valid_options" type="strlist">sync</append>
+ <append key="volume.mount.valid_options" type="strlist">dirsync</append>
+ <append key="volume.mount.valid_options" type="strlist">noatime</append>
+ <append key="volume.mount.valid_options" type="strlist">nodiratime</append>
+ <append key="volume.mount.valid_options" type="strlist">noexec</append>
+ <append key="volume.mount.valid_options" type="strlist">quiet</append>
+ <append key="volume.mount.valid_options" type="strlist">remount</append>
+ <append key="volume.mount.valid_options" type="strlist">exec</append>
+
+ <!-- allow these mount options for vfat -->
+ <match key="volume.fstype" string="vfat">
+ <append key="volume.mount.valid_options" type="strlist">utf8</append>
+ <append key="volume.mount.valid_options" type="strlist">shortname=</append>
+ <append key="volume.mount.valid_options" type="strlist">codepage=</append>
+ <append key="volume.mount.valid_options" type="strlist">iocharset=</append>
+ <append key="volume.mount.valid_options" type="strlist">umask=</append>
+ <append key="volume.mount.valid_options" type="strlist">dmask=</append>
+ <append key="volume.mount.valid_options" type="strlist">fmask=</append>
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+ </match>
+
+
+ <!-- allow these mount options for hfs -->
+ <match key="volume.fstype" string="hfs">
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+ <append key="volume.mount.valid_options" type="strlist">force</append>
+ </match>
+
+ <!-- allow these mount options for hfsplus -->
+ <match key="volume.fstype" string="hfsplus">
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+ <append key="volume.mount.valid_options" type="strlist">force</append>
+ </match>
+
+ <!-- allow these mount options for ntfs -->
+ <match key="volume.fstype" string="ntfs">
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+ <append key="volume.mount.valid_options" type="strlist">gid=</append>
+ <append key="volume.mount.valid_options" type="strlist">umask=</append>
+ </match>
+
+ <!-- allow these mount options for ext3 -->
+ <match key="volume.fstype" string="ext3">
+ <append key="volume.mount.valid_options" type="strlist">data=</append>
+ </match>
+
+ <!-- udf -->
+ <match key="volume.fstype" string="udf">
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+ <append key="volume.mount.valid_options" type="strlist">umask=</append>
+ </match>
+
+ <!-- iso9660 -->
+ <match key="volume.fstype" string="iso9660">
+ <append key="volume.mount.valid_options" type="strlist">utf8</append>
+ <append key="volume.mount.valid_options" type="strlist">uid=</append>
+ <append key="volume.mount.valid_options" type="strlist">mode=</append>
+ <append key="volume.mount.valid_options" type="strlist">iocharset=</append>
+ </match>
+
+ <!-- allow these unmount options -->
+ <append key="volume.unmount.valid_options" type="strlist">lazy</append>
+
+ </match>
+
+ <match key="storage.requires_eject" bool="true">
+ <!-- storage Eject causes eject on each volume on this storage -->
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Storage</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_names" type="strlist">Eject</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_execpaths" type="strlist">hal-storage-eject</append>
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Storage</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_names" type="strlist">CloseTray</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_execpaths" type="strlist">hal-storage-closetray</append>
+ </match>
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/20-zfs-methods.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/20-zfs-methods.fdi
new file mode 100644
index 0000000000..7af7e475b8
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/20-zfs-methods.fdi
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+ <device>
+ <match key="volume.fstype" string="zfs">
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Volume</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">ZpoolExport</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-zpool-export</append>
+
+ <append key="org.freedesktop.Hal.Device.Volume.method_names" type="strlist">ZpoolImport</append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_signatures" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_argnames" type="strlist"></append>
+ <append key="org.freedesktop.Hal.Device.Volume.method_execpaths" type="strlist">hal-storage-zpool-import</append>
+
+ </match>
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/preprobe/10osvendor/10-ide-drives.fdi b/usr/src/cmd/hal/fdi/preprobe/10osvendor/10-ide-drives.fdi
new file mode 100644
index 0000000000..61fa1ff8fc
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/preprobe/10osvendor/10-ide-drives.fdi
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <device>
+ <!-- Handle weird IDE drives (Jaz and Zip) by matching on the IDE model -->
+ <match key="storage.bus" string="ide">
+ <match key="storage.drive_type" string="disk">
+ <!-- IOMEGA Zip Drive -->
+ <match key="storage.model" contains_ncase="ZIP">
+ <merge key="storage.drive_type" type="string">zip</merge>
+ <merge key="storage.no_partitions_hint" type="bool">true</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ <!-- treat as floppy and data at partition 4; adjust device file -->
+ <append key="block.device" type="string">4</append>
+ </match>
+
+ <!-- IOMEGA CLIK! Drive -->
+ <match key="storage.model" contains_ncase="CLIK">
+ <merge key="storage.drive_type" type="string">zip</merge>
+ <merge key="storage.no_partitions_hint" type="bool">true</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ <!-- treat as floppy and data at partition 4; adjust device file -->
+ <append key="block.device" type="string">4</append>
+ </match>
+
+ <!-- Jaz -->
+ <match key="storage.model" contains_ncase="JAZ">
+ <merge key="storage.drive_type" type="string">jaz</merge>
+ <merge key="storage.no_partitions_hint" type="bool">true</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ <!-- treat as floppy and data at partition 4; adjust device file -->
+ <append key="block.device" type="string">4</append>
+ </match>
+ </match>
+ </match>
+
+ <match key="storage.bus" string="ide">
+ <match key="storage.drive_type" string="floppy">
+ <!-- IOMEGA Zip Drive -->
+ <match key="storage.model" contains_ncase="ZIP">
+ <merge key="storage.drive_type" type="string">zip</merge>
+ <merge key="storage.no_partitions_hint" type="bool">true</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ <!-- treat as floppy and data at partition 4; adjust device file -->
+ <append key="block.device" type="string">4</append>
+ </match>
+
+ <!-- IOMEGA CLIK! Drive -->
+ <match key="storage.model" contains_ncase="CLIK">
+ <merge key="storage.drive_type" type="string">zip</merge>
+ <merge key="storage.no_partitions_hint" type="bool">true</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ <!-- treat as floppy and data at partition 4; adjust device file -->
+ <append key="block.device" type="string">4</append>
+ </match>
+
+ <!-- Jaz -->
+ <match key="storage.model" contains_ncase="JAZ">
+ <merge key="storage.drive_type" type="string">jaz</merge>
+ <merge key="storage.no_partitions_hint" type="bool">true</merge>
+ <merge key="storage.requires_eject" type="bool">true</merge>
+ <!-- treat as floppy and data at partition 4; adjust device file -->
+ <append key="block.device" type="string">4</append>
+ </match>
+ </match>
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-fixed-storage.fdi b/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-fixed-storage.fdi
new file mode 100644
index 0000000000..0d65acc796
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-fixed-storage.fdi
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deviceinfo version="0.2">
+ <device>
+ <!-- To reduce HAL's probing effect on systems with massive fixed storage -->
+ <!-- we ignore fixed storage devices altogether -->
+ <match key="storage.removable" bool="false">
+ <match key="storage.hotpluggable" bool="false">
+ <merge key="info.ignore" type="bool">true</merge>
+ </match>
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-lofi.fdi b/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-lofi.fdi
new file mode 100644
index 0000000000..690d1829c7
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-ignore-lofi.fdi
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deviceinfo version="0.2">
+ <device>
+ <!-- lofi is only used for testing -->
+ <match key="info.solaris.driver" string="lofi">
+ <merge key="info.ignore" type="bool">true</merge>
+ </match>
+ </device>
+</deviceinfo>
diff --git a/usr/src/cmd/hal/hal.conf.in b/usr/src/cmd/hal/hal.conf.in
new file mode 100644
index 0000000000..747e1082fc
--- /dev/null
+++ b/usr/src/cmd/hal/hal.conf.in
@@ -0,0 +1,67 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- This configuration file specifies the required security policies
+ for the HAL to work. -->
+
+ <!-- Only root or user @HAL_USER@ can own the HAL service -->
+ <policy user="@HAL_USER@">
+ <allow own="org.freedesktop.Hal"/>
+ </policy>
+ <policy user="root">
+ <allow own="org.freedesktop.Hal"/>
+ </policy>
+
+ <!-- Allow anyone to invoke methods on the Manager and Device interfaces -->
+ <policy context="default">
+ <allow send_interface="org.freedesktop.Hal.Manager"/>
+ <allow send_interface="org.freedesktop.Hal.Device"/>
+ <allow receive_interface="org.freedesktop.Hal.Manager"
+ receive_sender="org.freedesktop.Hal"/>
+ <allow receive_interface="org.freedesktop.Hal.Device"
+ receive_sender="org.freedesktop.Hal"/>
+
+ <allow send_interface="org.freedesktop.Hal.Device.SystemPowerManagement"/>
+ <allow send_interface="org.freedesktop.Hal.Device.LaptopPanel"/>
+ <allow send_interface="org.freedesktop.Hal.Device.Volume"/>
+ <allow send_interface="org.freedesktop.Hal.Device.Volume.Crypto"/>
+ <allow receive_interface="org.freedesktop.Hal.Device.SystemPowerManagement"
+ receive_sender="org.freedesktop.Hal"/>
+ <allow receive_interface="org.freedesktop.Hal.Device.LaptopPanel"
+ receive_sender="org.freedesktop.Hal"/>
+ <allow receive_interface="org.freedesktop.Hal.Device.Volume"
+ receive_sender="org.freedesktop.Hal"/>
+ <allow receive_interface="org.freedesktop.Hal.Device.Volume.Crypto"
+ receive_sender="org.freedesktop.Hal"/>
+ </policy>
+
+ <!-- Default policy for the exported interfaces -->
+ <policy context="default">
+ <deny send_interface="org.freedesktop.Hal.Device.SystemPowerManagement"/>
+ <deny send_interface="org.freedesktop.Hal.Device.VideoAdapterPM"/>
+ <deny send_interface="org.freedesktop.Hal.Device.LaptopPanel"/>
+ <deny send_interface="org.freedesktop.Hal.Device.Volume"/>
+ <deny send_interface="org.freedesktop.Hal.Device.Volume.Crypto"/>
+ </policy>
+
+ <!-- This will not work if pam_console support is not enabled -->
+ <policy at_console="true">
+ <allow send_interface="org.freedesktop.Hal.Device.SystemPowerManagement"/>
+ <allow send_interface="org.freedesktop.Hal.Device.LaptopPanel"/>
+ <allow send_interface="org.freedesktop.Hal.Device.Volume"/>
+ <allow send_interface="org.freedesktop.Hal.Device.Volume.Crypto"/>
+ </policy>
+
+ <!-- You can change this to a more suitable user, or make per-group -->
+ <policy user="0">
+ <allow send_interface="org.freedesktop.Hal.Device.SystemPowerManagement"/>
+ <allow send_interface="org.freedesktop.Hal.Device.VideoAdapterPM"/>
+ <allow send_interface="org.freedesktop.Hal.Device.LaptopPanel"/>
+ <allow send_interface="org.freedesktop.Hal.Device.Volume"/>
+ <allow send_interface="org.freedesktop.Hal.Device.Volume.Crypto"/>
+ </policy>
+
+</busconfig>
+
diff --git a/usr/src/cmd/hal/hald-runner/Makefile b/usr/src/cmd/hal/hald-runner/Makefile
new file mode 100644
index 0000000000..f52bb65346
--- /dev/null
+++ b/usr/src/cmd/hal/hald-runner/Makefile
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = hald-runner
+OBJS = main.o runner.o utils.o
+SRCS = $(OBJS:%.o=%.c)
+
+include ../../Makefile.cmd
+include ../Makefile.hal
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -ldbus-1 -ldbus-glib-1 -lglib-2.0
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -UDBUS_API_SUBJECT_TO_CHANGE
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD)
+
+clean:
+ $(RM) $(OBJS)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/hal/hald-runner/main.c b/usr/src/cmd/hal/hald-runner/main.c
new file mode 100644
index 0000000000..fbb7a63369
--- /dev/null
+++ b/usr/src/cmd/hal/hald-runner/main.c
@@ -0,0 +1,224 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * main.c - Main dbus interface of the hald runner
+ *
+ * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <glib.h>
+#include "utils.h"
+#include "runner.h"
+
+static gboolean
+parse_first_part(run_request *r, DBusMessage *msg, DBusMessageIter *iter)
+{
+ DBusMessageIter sub_iter;
+ char *tmpstr;
+
+ /* First should be the device UDI */
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
+ goto malformed;
+ dbus_message_iter_get_basic(iter, &tmpstr);
+ r->udi = g_strdup(tmpstr);
+
+ /* Then the environment array */
+ if (!dbus_message_iter_next(iter) || dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ goto malformed;
+ dbus_message_iter_recurse(iter, &sub_iter);
+ /* Add default path for the programs we start */
+ tmpstr = g_strdup_printf("PATH=/sbin:/usr/sbin:/bin:/usr/bin:%s", getenv("PATH"));
+ r->environment = get_string_array(&sub_iter, tmpstr);
+
+ /* Then argv */
+ if (!dbus_message_iter_next(iter) || dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ goto malformed;
+ dbus_message_iter_recurse(iter, &sub_iter);
+ r->argv = get_string_array(&sub_iter, NULL);
+
+ return TRUE;
+
+malformed:
+ return FALSE;
+}
+
+static void
+handle_run(DBusConnection *con, DBusMessage *msg)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ run_request *r;
+ char *tmpstr;
+
+ r = new_run_request();
+ g_assert(dbus_message_iter_init(msg, &iter));
+
+ if (!parse_first_part(r, msg, &iter))
+ goto malformed;
+
+ /* Next a string of what should be written to stdin */
+ if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ goto malformed;
+ dbus_message_iter_get_basic(&iter, &tmpstr);
+ r->input = g_strdup(tmpstr);
+
+ /* Then an bool to indicate if we should grab stderr */
+ if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
+ goto malformed;
+ dbus_message_iter_get_basic(&iter, &(r->error_on_stderr));
+
+ /* Then an uint32 timeout for it */
+ if (!dbus_message_iter_next(&iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
+ goto malformed;
+ dbus_message_iter_get_basic(&iter, &(r->timeout));
+
+ /* let run_request_run handle the reply */
+ run_request_run(r, con, msg, NULL);
+ return;
+
+malformed:
+ del_run_request(r);
+ reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Malformed",
+ "Malformed run request");
+ dbus_connection_send(con, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static void
+handle_start(DBusConnection *con, DBusMessage *msg)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ run_request *r;
+ GPid pid;
+
+ r = new_run_request();
+ g_assert(dbus_message_iter_init(msg, &iter));
+
+ if (!dbus_message_iter_init(msg, &iter) || !parse_first_part(r, msg, &iter))
+ goto malformed;
+
+ if (run_request_run(r, con, NULL, &pid)) {
+ reply = dbus_message_new_method_return(msg);
+ dbus_message_append_args (reply,
+ DBUS_TYPE_INT64, &pid,
+ DBUS_TYPE_INVALID);
+
+ } else {
+ reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Failed",
+ "Start request failed");
+ }
+ dbus_connection_send(con, reply, NULL);
+ dbus_message_unref(reply);
+ return ;
+malformed:
+ del_run_request(r);
+ reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Malformed",
+ "Malformed start request");
+ dbus_connection_send(con, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static void
+handle_kill(DBusConnection *con, DBusMessage *msg)
+{
+ DBusError error;
+ DBusMessage *reply = NULL;
+ char *udi;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args(msg, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_INVALID)) {
+ reply = dbus_message_new_error (msg, "org.freedesktop.HalRunner.Malformed",
+ "Malformed kill message");
+ g_assert(reply);
+ dbus_connection_send (con, reply, NULL);
+ dbus_message_unref(reply);
+ return;
+ }
+ run_kill_udi(udi);
+
+ /* always successfull */
+ reply = dbus_message_new_method_return(msg);
+ dbus_connection_send(con, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static DBusHandlerResult
+filter(DBusConnection *con, DBusMessage *msg, void *user_data)
+{
+ DBusMessage *reply;
+
+ if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Run")) {
+ handle_run(con, msg);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Start")) {
+ handle_start(con, msg);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Kill")) {
+ handle_kill(con, msg);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "KillAll")) {
+ run_kill_all();
+ /* alwasy successfull */
+ reply = dbus_message_new_method_return(msg);
+ dbus_connection_send(con, reply, NULL);
+ dbus_message_unref(reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+int
+main(int argc, char **argv)
+{
+ DBusConnection *c;
+ DBusError error;
+ GMainLoop *loop;
+ char *dbus_address;
+
+ run_init();
+ dbus_error_init(&error);
+ dbus_address = getenv("HALD_RUNNER_DBUS_ADDRESS");
+ g_assert(dbus_address != NULL);
+
+ fprintf(stderr, "Runner started - allowed paths are '%s'\n", getenv("PATH"));
+
+ c = dbus_connection_open(dbus_address, &error);
+ if (c == NULL)
+ goto error;
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ dbus_connection_setup_with_g_main(c, NULL);
+ dbus_connection_set_exit_on_disconnect(c, TRUE);
+ dbus_connection_add_filter(c, filter, NULL, NULL);
+
+ g_main_loop_run(loop);
+
+error:
+ fprintf(stderr,"An error has occured: %s\n", error.message);
+ return -1;
+}
diff --git a/usr/src/cmd/hal/hald-runner/runner.c b/usr/src/cmd/hal/hald-runner/runner.c
new file mode 100644
index 0000000000..3fb1fb25d8
--- /dev/null
+++ b/usr/src/cmd/hal/hald-runner/runner.c
@@ -0,0 +1,372 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * runner.c - Process running code
+ *
+ * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <string.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <glib.h>
+#include "utils.h"
+#include "runner.h"
+
+/* Successful run of the program */
+#define HALD_RUN_SUCCESS 0x0
+/* Process was killed because of running too long */
+#define HALD_RUN_TIMEOUT 0x1
+/* Failed to start for some reason */
+#define HALD_RUN_FAILED 0x2
+/* Killed on purpose, e.g. hal_util_kill_device_helpers */
+#define HALD_RUN_KILLED 0x4
+
+GHashTable *udi_hash = NULL;
+
+typedef struct {
+ run_request *r;
+ DBusMessage *msg;
+ DBusConnection *con;
+ GPid pid;
+ gint stderr_v;
+ guint watch;
+ guint timeout;
+ gboolean sent_kill;
+ gboolean emit_pid_exited;
+} run_data;
+
+static void
+del_run_data(run_data *rd)
+{
+ if (rd == NULL)
+ return;
+
+ del_run_request(rd->r);
+ if (rd->msg)
+ dbus_message_unref(rd->msg);
+
+ g_spawn_close_pid(rd->pid);
+
+ if (rd->stderr_v >= 0)
+ close(rd->stderr_v);
+
+ if (rd->timeout != 0)
+ g_source_remove(rd->timeout);
+
+ g_free(rd);
+}
+
+run_request *
+new_run_request(void)
+{
+ run_request *result;
+ result = g_new0(run_request, 1);
+ g_assert(result != NULL);
+ return result;
+}
+
+void
+del_run_request(run_request *r)
+{
+ if (r == NULL)
+ return;
+ g_free(r->udi);
+ free_string_array(r->environment);
+ free_string_array(r->argv);
+ g_free(r->input);
+ g_free(r);
+}
+
+static void
+send_reply(DBusConnection *con, DBusMessage *msg, guint32 exit_type, gint32 return_code, gchar **error)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ int i;
+
+ if (con == NULL || msg == NULL)
+ return;
+
+ reply = dbus_message_new_method_return(msg);
+ g_assert(reply != NULL);
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &exit_type);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &return_code);
+ if (error != NULL) for (i = 0; error[i] != NULL; i++) {
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &error[i]);
+ }
+
+ dbus_connection_send(con, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static void
+remove_from_hash_table(run_data *rd)
+{
+ GList *list;
+
+ /* Remove to the hashtable */
+ list = (GList *)g_hash_table_lookup(udi_hash, rd->r->udi);
+ list = g_list_remove(list, rd);
+ /* The hash table will take care to not leak the dupped string */
+ g_hash_table_insert(udi_hash, g_strdup(rd->r->udi), list);
+}
+
+static void
+run_exited(GPid pid, gint status, gpointer data)
+{
+ run_data *rd = (run_data *)data;
+ char **error = NULL;
+
+ printf("%s exited\n", rd->r->argv[0]);
+ rd->watch = 0;
+ if (rd->sent_kill == TRUE) {
+ /* We send it a kill, so ignore */
+ del_run_data(rd);
+ return;
+ }
+ /* Check if it was a normal exit */
+ if (!WIFEXITED(status)) {
+ /* No not normal termination ? crash ? */
+ send_reply(rd->con, rd->msg, HALD_RUN_FAILED, 0, NULL);
+ goto out;
+ }
+ /* normal exit */
+ if (rd->stderr_v >= 0) {
+ /* Need to read stderr */
+ error = get_string_array_from_fd(rd->stderr_v);
+ close(rd->stderr_v);
+ rd->stderr_v = -1;
+ }
+ if (rd->msg != NULL)
+ send_reply(rd->con, rd->msg, HALD_RUN_SUCCESS, WEXITSTATUS(status), error);
+ free_string_array(error);
+
+out:
+ remove_from_hash_table(rd);
+
+ /* emit a signal that this PID exited */
+ if(rd->con != NULL && rd->emit_pid_exited) {
+ DBusMessage *signal;
+ signal = dbus_message_new_signal ("/org/freedesktop/HalRunner",
+ "org.freedesktop.HalRunner",
+ "StartedProcessExited");
+ dbus_message_append_args (signal,
+ DBUS_TYPE_INT64, &(rd->pid),
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(rd->con, signal, NULL);
+ }
+
+ del_run_data(rd);
+}
+
+static gboolean
+run_timedout(gpointer data) {
+ run_data *rd = (run_data *)data;
+ /* Time is up, kill the process, send reply that it was killed!
+ * Don't wait for exit, because it could hang in state D
+ */
+ kill(rd->pid, SIGTERM);
+ /* Ensure the timeout is not removed in the delete */
+ rd->timeout = 0;
+ /* So the exit watch will know it's killed in case it runs*/
+ rd->sent_kill = TRUE;
+
+ send_reply(rd->con, rd->msg, HALD_RUN_TIMEOUT, 0, NULL);
+ remove_from_hash_table(rd);
+ return FALSE;
+}
+
+static gboolean
+find_program(char **argv)
+{
+ /* Search for the program in the dirs where it's allowed to be */
+ char *program;
+ char *path = NULL;
+
+ if (argv[0] == NULL)
+ return FALSE;
+
+ program = g_path_get_basename(argv[0]);
+
+ /* first search $PATH to make e.g. run-hald.sh work */
+ path = g_find_program_in_path (program);
+ g_free(program);
+ if (path == NULL)
+ return FALSE;
+ else {
+ /* Replace program in argv[0] with the full path */
+ g_free(argv[0]);
+ argv[0] = path;
+ }
+ return TRUE;
+}
+
+/* Run the given request and reply it's result on msg */
+gboolean
+run_request_run (run_request *r, DBusConnection *con, DBusMessage *msg, GPid *out_pid)
+{
+ GPid pid;
+ GError *error = NULL;
+ gint *stdin_p = NULL;
+ gint *stderr_p = NULL;
+ gint stdin_v;
+ gint stderr_v = -1;
+ run_data *rd = NULL;
+ gboolean program_exists = FALSE;
+ char *program_dir = NULL;
+ GList *list;
+
+ printf("Run started %s (%d) (%d) \n!", r->argv[0], r->timeout,
+ r->error_on_stderr);
+ if (r->input != NULL) {
+ stdin_p = &stdin_v;
+ }
+ if (r->error_on_stderr) {
+ stderr_p = &stderr_v;
+ }
+
+ program_exists = find_program(r->argv);
+
+ if (program_exists)
+ program_dir = g_path_get_dirname (r->argv[0]);
+
+ printf(" full path is '%s', program_dir is '%s'\n", r->argv[0], program_dir);
+
+ if (!program_exists ||
+ !g_spawn_async_with_pipes(program_dir, r->argv, r->environment,
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid,
+ stdin_p, NULL, stderr_p, &error)) {
+ g_free (program_dir);
+ del_run_request(r);
+ if (con && msg)
+ send_reply(con, msg, HALD_RUN_FAILED, 0, NULL);
+ return FALSE;
+ }
+ g_free (program_dir);
+
+ if (r->input) {
+ if (write(stdin_v, r->input, strlen(r->input)) != (ssize_t) strlen(r->input));
+ printf("Warning: Error while wite r->input (%s) to stdin_v.\n", r->input);
+ close(stdin_v);
+ }
+
+ rd = g_new0(run_data,1);
+ g_assert(rd != NULL);
+ rd->r = r;
+ rd->msg = msg;
+ if (msg != NULL)
+ dbus_message_ref(msg);
+
+ rd->con = con;
+ rd->pid = pid;
+ rd->stderr_v = stderr_v;
+ rd->sent_kill = FALSE;
+
+ /* Add watch for exit of the program */
+ rd->watch = g_child_watch_add(pid, run_exited, rd);
+
+ /* Add timeout if needed */
+ if (r->timeout > 0)
+ rd->timeout = g_timeout_add(r->timeout, run_timedout, rd);
+ else
+ rd->timeout = 0;
+
+ /* Add to the hashtable */
+ list = (GList *)g_hash_table_lookup(udi_hash, r->udi);
+ list = g_list_prepend(list, rd);
+
+ /* The hash table will take care to not leak the dupped string */
+ g_hash_table_insert(udi_hash, g_strdup(r->udi), list);
+
+ /* send back PID if requested.. and only emit StartedProcessExited in this case */
+ if (out_pid != NULL) {
+ *out_pid = pid;
+ rd->emit_pid_exited = TRUE;
+ }
+ return TRUE;
+}
+
+static void
+kill_rd(gpointer data, gpointer user_data)
+{
+ run_data *rd = (run_data *)data;
+
+ kill(rd->pid, SIGTERM);
+ printf("Sent kill to %d\n", rd->pid);
+ if (rd->timeout != 0) {
+ /* Remove the timeout watch */
+ g_source_remove(rd->timeout);
+ rd->timeout = 0;
+ }
+
+ /* So the exit watch will know it's killed in case it runs */
+ rd->sent_kill = TRUE;
+
+ if (rd->msg != NULL)
+ send_reply(rd->con, rd->msg, HALD_RUN_KILLED, 0, NULL);
+}
+
+static void
+do_kill_udi(gchar *udi)
+{
+ GList *list;
+ list = (GList *)g_hash_table_lookup(udi_hash, udi);
+ g_list_foreach(list, kill_rd, NULL);
+ g_list_free(list);
+}
+
+/* Kill all running request for a udi */
+void
+run_kill_udi(gchar *udi)
+{
+ do_kill_udi(udi);
+ g_hash_table_remove(udi_hash, udi);
+}
+
+static gboolean
+hash_kill_udi(gpointer key, gpointer value, gpointer user_data) {
+ do_kill_udi(key);
+ return TRUE;
+}
+
+/* Kill all running request*/
+void
+run_kill_all()
+{
+ g_hash_table_foreach_remove(udi_hash, hash_kill_udi, NULL);
+}
+
+void
+run_init()
+{
+ udi_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+}
diff --git a/usr/src/cmd/hal/hald-runner/runner.h b/usr/src/cmd/hal/hald-runner/runner.h
new file mode 100644
index 0000000000..2a18f941e3
--- /dev/null
+++ b/usr/src/cmd/hal/hald-runner/runner.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * runner.h - Process running interface
+ *
+ * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+#ifndef RUNNER_H
+#define RUNNER_H
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <glib.h>
+
+typedef struct {
+ gchar *udi;
+ gchar **environment;
+ gchar **argv;
+ gchar *input;
+ gboolean error_on_stderr;
+ guint32 timeout;
+} run_request;
+
+run_request *new_run_request(void);
+void del_run_request(run_request *r);
+
+/* Run the given request and reply it's result on msg */
+gboolean run_request_run(run_request *r, DBusConnection *con, DBusMessage *msg, GPid *out_pid);
+
+/* Kill all running request for a udi */
+void run_kill_udi(gchar *udi);
+
+/* Kill all running request*/
+void run_kill_all();
+
+/* initialise the actual runner data */
+void run_init();
+
+#endif /* RUNNER_H */
diff --git a/usr/src/cmd/hal/hald-runner/utils.c b/usr/src/cmd/hal/hald-runner/utils.c
new file mode 100644
index 0000000000..2a569c4b5a
--- /dev/null
+++ b/usr/src/cmd/hal/hald-runner/utils.c
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * utils.c - Some utils for the hald runner
+ *
+ * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib-lowlevel.h>
+#include <glib.h>
+
+#include "utils.h"
+
+char **
+get_string_array(DBusMessageIter *iter, char *extra)
+{
+ GArray *array;
+ char **result;
+ array = g_array_new(TRUE, FALSE, sizeof(char *));
+
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
+ const char *value;
+ char *t;
+ dbus_message_iter_get_basic(iter, &value);
+ t = g_strdup(value);
+ g_array_append_vals(array, &t, 1);
+ dbus_message_iter_next(iter);
+ }
+ if (extra != NULL)
+ g_array_append_vals(array, &extra, 1);
+ result = (char **) array->data;
+ g_array_free(array, FALSE);
+ return result;
+}
+
+char **
+get_string_array_from_fd(int fd)
+{
+ GArray *array;
+ char **result;
+ GString *str;
+ gsize pos;
+ GIOChannel *io;
+ int i = 0;
+
+ array = g_array_new(TRUE, FALSE, sizeof(char *));
+ str = g_string_new("");
+ io = g_io_channel_unix_new(fd);
+ while (g_io_channel_read_line_string(io, str, &pos, NULL) == G_IO_STATUS_NORMAL && (i++ < 128)) {
+ char *t;
+
+ /* Remove the terminting char aka \n */
+ g_string_erase(str, pos, 1);
+ t = g_strdup(str->str);
+ g_array_append_vals(array, &t, 1);
+ }
+ g_string_free(str, TRUE);
+ g_io_channel_unref(io);
+ result = (char **) array->data;
+ g_array_free(array, FALSE);
+ return result;
+}
+
+void
+free_string_array(char **array)
+{
+ char **p;
+
+ for (p = array; p != NULL && *p != NULL; p++)
+ g_free(*p);
+ g_free(array);
+}
diff --git a/usr/src/cmd/hal/hald-runner/utils.h b/usr/src/cmd/hal/hald-runner/utils.h
new file mode 100644
index 0000000000..7f6cb75aa1
--- /dev/null
+++ b/usr/src/cmd/hal/hald-runner/utils.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * utils.h - Some utils for the hald runner
+ *
+ * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+#ifndef UTILS_H
+#define UTILS_H
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib-lowlevel.h>
+
+char **get_string_array(DBusMessageIter *iter, gchar *extra);
+char **get_string_array_from_fd(int fd);
+void free_string_array(char **array);
+
+#endif /* UTILS_H */
diff --git a/usr/src/cmd/hal/hald/Makefile b/usr/src/cmd/hal/hald/Makefile
new file mode 100644
index 0000000000..f5f25f1562
--- /dev/null
+++ b/usr/src/cmd/hal/hald/Makefile
@@ -0,0 +1,91 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUBDIRS = solaris
+
+PROG = hald
+OBJS = hald_marshal.o device.o device_info.o device_store.o hald.o \
+ hald_dbus.o hald_runner.o ids.o logger.o property.o util.o \
+ util_helper.o util_pm.o
+OBJS_SOL = devinfo.o devinfo_ieee1394.o devinfo_misc.o devinfo_pci.o devinfo_storage.o \
+ devinfo_usb.o hotplug.o osspec.o sysevent.o
+OBJS_ALL = $(OBJS) $(OBJS_SOL:%=solaris/%)
+SRCS = $(OBJS:%.o=%.c)
+
+include ../../Makefile.cmd
+include ../Makefile.hal
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -lm -ldbus-1 -ldbus-glib-1 -lglib-2.0 -lgobject-2.0 \
+ -ldevinfo -lsysevent -lnvpair
+
+LDFLAGS += -L$(SFW_ROOT)/lib -R$(SFW_ROOT)/lib
+
+all install $(PROG) := LDLIBS += -lexpat
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I/usr/sfw/include
+C99MODE = $(C99_ENABLE)
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+$(PROG) := TARGET= all
+
+.KEEP_STATE:
+
+all: $(SUBDIRS) .WAIT $(PROG)
+
+hald_marshal.o: hald_marshal.h hald_marshal.c
+
+hald_marshal.h: hald_marshal.list
+ glib-genmarshal --prefix=hald_marshal hald_marshal.list --header >> xgen-gmh \
+ && (cmp -s xgen-gmh hald_marshal.h || cp xgen-gmh hald_marshal.h) \
+ && rm -f xgen-gmh xgen-gmh~
+
+hald_marshal.c: hald_marshal.list
+ glib-genmarshal --prefix=hald_marshal hald_marshal.list --body >> xgen-gmc \
+ && (cmp -s xgen-gmc hald_marshal.c || cp xgen-gmc hald_marshal.c) \
+ && rm -f xgen-gmc xgen-gmc~
+
+$(PROG): $(SUBDIRS) .WAIT $(OBJS_ALL)
+ $(LINK.c) -o $@ $(OBJS_ALL) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD) $(SUBDIRS)
+
+clean: $(SUBDIRS)
+ $(RM) $(OBJS) hald_marshal.c hald_marshal.h
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/hal/hald/device.c b/usr/src/cmd/hal/hald/device.c
new file mode 100644
index 0000000000..f54401f7aa
--- /dev/null
+++ b/usr/src/cmd/hal/hald/device.c
@@ -0,0 +1,1350 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device.c : HalDevice methods
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2004 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "hald.h"
+#include "device.h"
+#include "hald_marshal.h"
+#include "logger.h"
+#include "hald_runner.h"
+
+static GObjectClass *parent_class;
+
+enum {
+ PROPERTY_CHANGED,
+ CAPABILITY_ADDED,
+ CALLOUTS_FINISHED,
+ CANCELLED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#ifdef HALD_MEMLEAK_DBG
+int dbg_hal_device_object_delta = 0;
+#endif
+
+static void
+hal_device_finalize (GObject *obj)
+{
+ HalDevice *device = HAL_DEVICE (obj);
+
+ runner_device_finalized (device);
+
+#ifdef HALD_MEMLEAK_DBG
+ dbg_hal_device_object_delta--;
+ printf ("************* in finalize for udi=%s\n", device->udi);
+#endif
+
+
+ g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL);
+
+ g_free (device->udi);
+
+ if (parent_class->finalize)
+ parent_class->finalize (obj);
+
+}
+
+static void
+hal_device_class_init (HalDeviceClass *klass)
+{
+ GObjectClass *obj_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ obj_class->finalize = hal_device_finalize;
+
+ signals[PROPERTY_CHANGED] =
+ g_signal_new ("property_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceClass,
+ property_changed),
+ NULL, NULL,
+ hald_marshal_VOID__STRING_BOOL_BOOL,
+ G_TYPE_NONE, 3,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+
+ signals[CAPABILITY_ADDED] =
+ g_signal_new ("capability_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceClass,
+ capability_added),
+ NULL, NULL,
+ hald_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[CALLOUTS_FINISHED] =
+ g_signal_new ("callouts_finished",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceClass,
+ callouts_finished),
+ NULL, NULL,
+ hald_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CANCELLED] =
+ g_signal_new ("cancelled",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceClass,
+ cancelled),
+ NULL, NULL,
+ hald_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+hal_device_init (HalDevice *device)
+{
+ static int temp_device_counter = 0;
+
+ device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
+ temp_device_counter++);
+ device->num_addons = 0;
+ device->num_addons_ready = 0;
+}
+
+GType
+hal_device_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo type_info = {
+ sizeof (HalDeviceClass),
+ NULL, NULL,
+ (GClassInitFunc) hal_device_class_init,
+ NULL, NULL,
+ sizeof (HalDevice),
+ 0,
+ (GInstanceInitFunc) hal_device_init,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "HalDevice",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+HalDevice *
+hal_device_new (void)
+{
+ HalDevice *device;
+
+ device = g_object_new (HAL_TYPE_DEVICE, NULL, NULL);
+
+#ifdef HALD_MEMLEAK_DBG
+ dbg_hal_device_object_delta++;
+#endif
+ return device;
+}
+
+/** Merge all properties from source where the key starts with
+ * source_namespace and put them onto target replacing source_namespace
+ * with target_namespace
+ *
+ * @param target Device to put properties onto
+ * @param source Device to retrieve properties from
+ * @param target_namespace Replace source namespace with this namespace
+ * @param source_namespace Source namespace that property keys must match
+ */
+void
+hal_device_merge_with_rewrite (HalDevice *target,
+ HalDevice *source,
+ const char *target_namespace,
+ const char *source_namespace)
+{
+ GSList *iter;
+ size_t source_ns_len;
+
+ source_ns_len = strlen (source_namespace);
+
+ /* doesn't handle info.capabilities */
+
+ /* device_property_atomic_update_begin (); */
+
+ for (iter = source->properties; iter != NULL; iter = iter->next) {
+ HalProperty *p = iter->data;
+ int type;
+ const char *key;
+ int target_type;
+ gchar *target_key;
+
+ key = hal_property_get_key (p);
+
+ /* only care about properties that match source namespace */
+ if (strncmp(key, source_namespace, source_ns_len) != 0)
+ continue;
+
+ target_key = g_strdup_printf("%s%s", target_namespace,
+ key+source_ns_len);
+
+ type = hal_property_get_type (p);
+
+ /* only remove target if it exists with a different type */
+ target_type = hal_device_property_get_type (target, key);
+ if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
+ hal_device_property_remove (target, key);
+
+ switch (type) {
+
+ case HAL_PROPERTY_TYPE_STRING:
+ hal_device_property_set_string (
+ target, target_key,
+ hal_property_get_string (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_INT32:
+ hal_device_property_set_int (
+ target, target_key,
+ hal_property_get_int (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_UINT64:
+ hal_device_property_set_uint64 (
+ target, target_key,
+ hal_property_get_uint64 (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ hal_device_property_set_bool (
+ target, target_key,
+ hal_property_get_bool (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ hal_device_property_set_double (
+ target, target_key,
+ hal_property_get_double (p));
+ break;
+
+ default:
+ HAL_WARNING (("Unknown property type %d", type));
+ break;
+ }
+
+ g_free (target_key);
+ }
+
+ /* device_property_atomic_update_end (); */
+
+}
+
+void
+hal_device_merge (HalDevice *target, HalDevice *source)
+{
+ GSList *iter;
+ GSList *caps;
+
+ /* device_property_atomic_update_begin (); */
+
+ for (iter = source->properties; iter != NULL; iter = iter->next) {
+ HalProperty *p = iter->data;
+ int type;
+ const char *key;
+ int target_type;
+
+ key = hal_property_get_key (p);
+ type = hal_property_get_type (p);
+
+ /* handle info.capabilities in a special way */
+ if (strcmp (key, "info.capabilities") == 0)
+ continue;
+
+ /* only remove target if it exists with a different type */
+ target_type = hal_device_property_get_type (target, key);
+ if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
+ hal_device_property_remove (target, key);
+
+ switch (type) {
+
+ case HAL_PROPERTY_TYPE_STRING:
+ hal_device_property_set_string (
+ target, key,
+ hal_property_get_string (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_INT32:
+ hal_device_property_set_int (
+ target, key,
+ hal_property_get_int (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_UINT64:
+ hal_device_property_set_uint64 (
+ target, key,
+ hal_property_get_uint64 (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ hal_device_property_set_bool (
+ target, key,
+ hal_property_get_bool (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ hal_device_property_set_double (
+ target, key,
+ hal_property_get_double (p));
+ break;
+
+ default:
+ HAL_WARNING (("Unknown property type %d", type));
+ break;
+ }
+ }
+
+ /* device_property_atomic_update_end (); */
+
+ caps = hal_device_property_get_strlist (source, "info.capabilities");
+ for (iter = caps; iter != NULL; iter = iter->next) {
+ if (!hal_device_has_capability (target, iter->data))
+ hal_device_add_capability (target, iter->data);
+ }
+}
+
+gboolean
+hal_device_matches (HalDevice *device1, HalDevice *device2,
+ const char *namespace)
+{
+ int len;
+ GSList *iter;
+
+ len = strlen (namespace);
+
+ for (iter = device1->properties; iter != NULL; iter = iter->next) {
+ HalProperty *p;
+ const char *key;
+ int type;
+
+ p = (HalProperty *) iter->data;
+ key = hal_property_get_key (p);
+ type = hal_property_get_type (p);
+
+ if (strncmp (key, namespace, len) != 0)
+ continue;
+
+ if (!hal_device_has_property (device2, key))
+ return FALSE;
+
+ switch (type) {
+
+ case HAL_PROPERTY_TYPE_STRING:
+ if (strcmp (hal_property_get_string (p),
+ hal_device_property_get_string (device2,
+ key)) != 0)
+ return FALSE;
+ break;
+
+ case HAL_PROPERTY_TYPE_INT32:
+ if (hal_property_get_int (p) !=
+ hal_device_property_get_int (device2, key))
+ return FALSE;
+ break;
+
+ case HAL_PROPERTY_TYPE_UINT64:
+ if (hal_property_get_uint64 (p) !=
+ hal_device_property_get_uint64 (device2, key))
+ return FALSE;
+ break;
+
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ if (hal_property_get_bool (p) !=
+ hal_device_property_get_bool (device2, key))
+ return FALSE;
+ break;
+
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ if (hal_property_get_double (p) !=
+ hal_device_property_get_double (device2, key))
+ return FALSE;
+ break;
+
+ default:
+ HAL_WARNING (("Unknown property type %d", type));
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+const char *
+hal_device_get_udi (HalDevice *device)
+{
+ return device->udi;
+}
+
+void
+hal_device_set_udi (HalDevice *device, const char *udi)
+{
+ if (device->udi != NULL)
+ g_free (device->udi);
+ device->udi = g_strdup (udi);
+}
+
+void
+hal_device_add_capability (HalDevice *device, const char *capability)
+{
+ if (hal_device_property_strlist_add (device, "info.capabilities", capability))
+ g_signal_emit (device, signals[CAPABILITY_ADDED], 0, capability);
+}
+
+gboolean
+hal_device_has_capability (HalDevice *device, const char *capability)
+{
+ GSList *caps;
+ GSList *iter;
+ gboolean matched = FALSE;
+
+ caps = hal_device_property_get_strlist (device, "info.capabilities");
+
+ if (caps == NULL)
+ return FALSE;
+
+ for (iter = caps; iter != NULL; iter = iter->next) {
+ if (strcmp (iter->data, capability) == 0) {
+ matched = TRUE;
+ break;
+ }
+ }
+
+ return matched;
+}
+
+gboolean
+hal_device_has_property (HalDevice *device, const char *key)
+{
+ g_return_val_if_fail (device != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ return hal_device_property_find (device, key) != NULL;
+}
+
+int
+hal_device_num_properties (HalDevice *device)
+{
+ g_return_val_if_fail (device != NULL, -1);
+
+ return g_slist_length (device->properties);
+}
+
+HalProperty *
+hal_device_property_find (HalDevice *device, const char *key)
+{
+ GSList *iter;
+
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ for (iter = device->properties; iter != NULL; iter = iter->next) {
+ HalProperty *p = iter->data;
+
+ if (strcmp (hal_property_get_key (p), key) == 0)
+ return p;
+ }
+
+ return NULL;
+}
+
+char *
+hal_device_property_to_string (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ prop = hal_device_property_find (device, key);
+ if (!prop)
+ return NULL;
+
+ return hal_property_to_string (prop);
+}
+
+void
+hal_device_property_foreach (HalDevice *device,
+ HalDevicePropertyForeachFn callback,
+ gpointer user_data)
+{
+ GSList *iter;
+
+ g_return_if_fail (device != NULL);
+ g_return_if_fail (callback != NULL);
+
+ for (iter = device->properties; iter != NULL; iter = iter->next) {
+ HalProperty *p = iter->data;
+ gboolean cont;
+
+ cont = callback (device, p, user_data);
+
+ if (cont == FALSE)
+ return;
+ }
+}
+
+int
+hal_device_property_get_type (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, HAL_PROPERTY_TYPE_INVALID);
+ g_return_val_if_fail (key != NULL, HAL_PROPERTY_TYPE_INVALID);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_type (prop);
+ else
+ return HAL_PROPERTY_TYPE_INVALID;
+}
+
+const char *
+hal_device_property_get_string (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_string (prop);
+ else
+ return NULL;
+}
+
+const char *
+hal_device_property_get_as_string (HalDevice *device, const char *key, char *buf, size_t bufsize)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ switch (hal_property_get_type (prop)) {
+ case HAL_PROPERTY_TYPE_STRING:
+ strncpy (buf, hal_property_get_string (prop), bufsize);
+ break;
+ case HAL_PROPERTY_TYPE_INT32:
+ snprintf (buf, bufsize, "%d", hal_property_get_int (prop));
+ break;
+ case HAL_PROPERTY_TYPE_UINT64:
+ snprintf (buf, bufsize, "%llu", (long long unsigned int) hal_property_get_uint64 (prop));
+ break;
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ snprintf (buf, bufsize, "%f", hal_property_get_double (prop));
+ break;
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ strncpy (buf, hal_property_get_bool (prop) ? "true" : "false", bufsize);
+ break;
+
+ case HAL_PROPERTY_TYPE_STRLIST:
+ /* print out as "\tval1\tval2\val3\t" */
+ {
+ GSList *iter;
+ guint i;
+
+ if (bufsize > 0)
+ buf[0] = '\t';
+ i = 1;
+ for (iter = hal_property_get_strlist (prop);
+ iter != NULL && i < bufsize;
+ iter = g_slist_next (iter)) {
+ guint len;
+ const char *str;
+
+ str = (const char *) iter->data;
+ len = strlen (str);
+ strncpy (buf + i, str, bufsize - i);
+ i += len;
+
+ if (i < bufsize) {
+ buf[i] = '\t';
+ i++;
+ }
+ }
+ }
+ break;
+ }
+ return buf;
+ } else {
+ buf[0] = '\0';
+ return NULL;
+ }
+}
+
+dbus_int32_t
+hal_device_property_get_int (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, -1);
+ g_return_val_if_fail (key != NULL, -1);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_int (prop);
+ else
+ return -1;
+}
+
+dbus_uint64_t
+hal_device_property_get_uint64 (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, -1);
+ g_return_val_if_fail (key != NULL, -1);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_uint64 (prop);
+ else
+ return -1;
+}
+
+dbus_bool_t
+hal_device_property_get_bool (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_bool (prop);
+ else
+ return FALSE;
+}
+
+double
+hal_device_property_get_double (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, -1.0);
+ g_return_val_if_fail (key != NULL, -1.0);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_double (prop);
+ else
+ return -1.0;
+}
+
+gboolean
+hal_device_property_set_string (HalDevice *device, const char *key,
+ const char *value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRING)
+ return FALSE;
+
+ /* don't bother setting the same value */
+ if (value != NULL &&
+ strcmp (hal_property_get_string (prop), value) == 0)
+ return TRUE;
+
+ hal_property_set_string (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+
+ prop = hal_property_new_string (key, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_set_int (HalDevice *device, const char *key,
+ dbus_int32_t value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_INT32)
+ return FALSE;
+
+ /* don't bother setting the same value */
+ if (hal_property_get_int (prop) == value)
+ return TRUE;
+
+ hal_property_set_int (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+ prop = hal_property_new_int (key, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_set_uint64 (HalDevice *device, const char *key,
+ dbus_uint64_t value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_UINT64)
+ return FALSE;
+
+ /* don't bother setting the same value */
+ if (hal_property_get_uint64 (prop) == value)
+ return TRUE;
+
+ hal_property_set_uint64 (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+ prop = hal_property_new_uint64 (key, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_set_bool (HalDevice *device, const char *key,
+ dbus_bool_t value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_BOOLEAN)
+ return FALSE;
+
+ /* don't bother setting the same value */
+ if (hal_property_get_bool (prop) == value)
+ return TRUE;
+
+ hal_property_set_bool (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+ prop = hal_property_new_bool (key, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_set_double (HalDevice *device, const char *key,
+ double value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_DOUBLE)
+ return FALSE;
+
+ /* don't bother setting the same value */
+ if (hal_property_get_double (prop) == value)
+ return TRUE;
+
+ hal_property_set_double (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+ prop = hal_property_new_double (key, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_copy_property (HalDevice *from_device, const char *from, HalDevice *to_device, const char *to)
+{
+ gboolean rc;
+
+ rc = FALSE;
+
+ if (hal_device_has_property (from_device, from)) {
+ switch (hal_device_property_get_type (from_device, from)) {
+ case HAL_PROPERTY_TYPE_STRING:
+ rc = hal_device_property_set_string (
+ to_device, to, hal_device_property_get_string (from_device, from));
+ break;
+ case HAL_PROPERTY_TYPE_INT32:
+ rc = hal_device_property_set_int (
+ to_device, to, hal_device_property_get_int (from_device, from));
+ break;
+ case HAL_PROPERTY_TYPE_UINT64:
+ rc = hal_device_property_set_uint64 (
+ to_device, to, hal_device_property_get_uint64 (from_device, from));
+ break;
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ rc = hal_device_property_set_bool (
+ to_device, to, hal_device_property_get_bool (from_device, from));
+ break;
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ rc = hal_device_property_set_double (
+ to_device, to, hal_device_property_get_double (from_device, from));
+ break;
+ }
+ }
+
+ return rc;
+}
+
+gboolean
+hal_device_property_remove (HalDevice *device, const char *key)
+{
+ HalProperty *prop;
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop == NULL)
+ return FALSE;
+
+ device->properties = g_slist_remove (device->properties, prop);
+
+ hal_property_free (prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, TRUE, FALSE);
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_set_attribute (HalDevice *device,
+ const char *key,
+ enum PropertyAttribute attr,
+ gboolean val)
+{
+ HalProperty *prop;
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+hal_device_print (HalDevice *device)
+{
+ GSList *iter;
+
+ fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
+
+ for (iter = device->properties; iter != NULL; iter = iter->next) {
+ HalProperty *p = iter->data;
+ int type;
+ const char *key;
+
+ key = hal_property_get_key (p);
+ type = hal_property_get_type (p);
+
+ switch (type) {
+ case HAL_PROPERTY_TYPE_STRING:
+ fprintf (stderr, " %s = '%s' (string)\n", key,
+ hal_property_get_string (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_INT32:
+ fprintf (stderr, " %s = %d 0x%x (int)\n", key,
+ hal_property_get_int (p),
+ hal_property_get_int (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_UINT64:
+ fprintf (stderr, " %s = %llu 0x%llx (uint64)\n", key,
+ (long long unsigned int) hal_property_get_uint64 (p),
+ (long long unsigned int) hal_property_get_uint64 (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ fprintf (stderr, " %s = %g (double)\n", key,
+ hal_property_get_double (p));
+ break;
+
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ fprintf (stderr, " %s = %s (bool)\n", key,
+ (hal_property_get_bool (p) ? "true" :
+ "false"));
+ break;
+
+ default:
+ HAL_WARNING (("Unknown property type %d", type));
+ break;
+ }
+ }
+ fprintf (stderr, "\n");
+}
+
+
+typedef struct {
+ char *key;
+ HalDevice *device;
+ HalDeviceAsyncCallback callback;
+ gpointer user_data;
+
+ guint prop_signal_id;
+ guint timeout_id;
+} AsyncMatchInfo;
+
+static void
+destroy_async_match_info (AsyncMatchInfo *ai)
+{
+ g_free (ai->key);
+ g_signal_handler_disconnect (ai->device, ai->prop_signal_id);
+ g_source_remove (ai->timeout_id);
+ g_object_unref (ai->device);
+ g_free (ai);
+}
+
+static void
+prop_changed_cb (HalDevice *device, const char *key,
+ gboolean removed, gboolean added, gpointer user_data)
+{
+ AsyncMatchInfo *ai = user_data;
+
+ if (strcmp (key, ai->key) != 0)
+ return;
+
+ /* the property is no longer there */
+ if (removed)
+ goto cleanup;
+
+
+ ai->callback (ai->device, ai->user_data, TRUE);
+
+cleanup:
+ destroy_async_match_info (ai);
+}
+
+
+static gboolean
+async_wait_timeout (gpointer user_data)
+{
+ AsyncMatchInfo *ai = (AsyncMatchInfo *) user_data;
+
+ ai->callback (ai->device, ai->user_data, FALSE);
+
+ destroy_async_match_info (ai);
+
+ return FALSE;
+}
+
+void
+hal_device_async_wait_property (HalDevice *device,
+ const char *key,
+ HalDeviceAsyncCallback callback,
+ gpointer user_data,
+ int timeout)
+{
+ HalProperty *prop;
+ AsyncMatchInfo *ai;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL || timeout==0) {
+ callback (device, user_data, prop != NULL);
+ return;
+ }
+
+ ai = g_new0 (AsyncMatchInfo, 1);
+
+ ai->device = g_object_ref (device);
+ ai->key = g_strdup (key);
+ ai->callback = callback;
+ ai->user_data = user_data;
+
+ ai->prop_signal_id = g_signal_connect (device, "property_changed",
+ G_CALLBACK (prop_changed_cb),
+ ai);
+
+ ai->timeout_id = g_timeout_add (timeout, async_wait_timeout, ai);
+}
+
+void
+hal_device_callouts_finished (HalDevice *device)
+{
+ g_signal_emit (device, signals[CALLOUTS_FINISHED], 0);
+}
+
+/** Used when giving up on a device, e.g. if no device file appeared
+ */
+void
+hal_device_cancel (HalDevice *device)
+{
+ HAL_INFO (("udi=%s", device->udi));
+ g_signal_emit (device, signals[CANCELLED], 0);
+}
+
+
+
+
+GSList *
+hal_device_property_get_strlist (HalDevice *device,
+ const char *key)
+{
+ HalProperty *prop;
+
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL)
+ return hal_property_get_strlist (prop);
+ else
+ return NULL;
+}
+
+const char *
+hal_device_property_get_strlist_elem (HalDevice *device,
+ const char *key,
+ guint index)
+{
+ GSList *strlist;
+ GSList *i;
+
+ strlist = hal_device_property_get_strlist (device, key);
+ if (strlist == NULL)
+ return NULL;
+
+ i = g_slist_nth (strlist, index);
+ if (i == NULL)
+ return NULL;
+
+ return (const char *) i->data;
+}
+
+gboolean
+hal_device_property_strlist_append (HalDevice *device,
+ const char *key,
+ const char *value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+ return FALSE;
+
+ hal_property_strlist_append (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+ prop = hal_property_new_strlist (key);
+ hal_property_strlist_append (prop, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_strlist_prepend (HalDevice *device,
+ const char *key,
+ const char *value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+ return FALSE;
+
+ hal_property_strlist_prepend (prop, value);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+
+ } else {
+ prop = hal_property_new_strlist (key);
+ hal_property_strlist_prepend (prop, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_strlist_remove_elem (HalDevice *device,
+ const char *key,
+ guint index)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop == NULL)
+ return FALSE;
+
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+ return FALSE;
+
+ if (hal_property_strlist_remove_elem (prop, index)) {
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+hal_device_property_strlist_clear (HalDevice *device,
+ const char *key)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop == NULL) {
+ prop = hal_property_new_strlist (key);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+
+ return TRUE;
+ }
+
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+ return FALSE;
+
+ if (hal_property_strlist_clear (prop)) {
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+gboolean
+hal_device_property_strlist_add (HalDevice *device,
+ const char *key,
+ const char *value)
+{
+ HalProperty *prop;
+ gboolean res;
+
+ res = FALSE;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop != NULL) {
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+ goto out;
+
+ res = hal_property_strlist_add (prop, value);
+ if (res) {
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+ }
+
+ } else {
+ prop = hal_property_new_strlist (key);
+ hal_property_strlist_prepend (prop, value);
+
+ device->properties = g_slist_prepend (device->properties, prop);
+
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, TRUE);
+
+ res = TRUE;
+ }
+
+out:
+ return res;
+}
+
+gboolean
+hal_device_property_strlist_remove (HalDevice *device,
+ const char *key,
+ const char *value)
+{
+ HalProperty *prop;
+
+ /* check if property already exists */
+ prop = hal_device_property_find (device, key);
+
+ if (prop == NULL)
+ return FALSE;
+
+ if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
+ return FALSE;
+
+ if (hal_property_strlist_remove (prop, value)) {
+ g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+ key, FALSE, FALSE);
+ }
+
+ return TRUE;
+}
+
+gboolean
+hal_device_property_strlist_is_empty (HalDevice *device,
+ const char *key)
+{
+ GSList *strlist;
+
+ if ( hal_device_has_property (device, key)) {
+ strlist = hal_device_property_get_strlist (device, key);
+ if (strlist == NULL )
+ return TRUE;
+
+ if (g_slist_length (strlist) > 0)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+hal_device_inc_num_addons (HalDevice *device)
+{
+ device->num_addons++;
+}
+
+gboolean
+hal_device_inc_num_ready_addons (HalDevice *device)
+{
+ if (hal_device_are_all_addons_ready (device)) {
+ HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!",
+ device->udi));
+ return FALSE;
+ }
+
+ device->num_addons_ready++;
+ return TRUE;
+}
+
+gboolean
+hal_device_are_all_addons_ready (HalDevice *device)
+{
+ if (device->num_addons_ready == device->num_addons) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/usr/src/cmd/hal/hald/device.h b/usr/src/cmd/hal/hald/device.h
new file mode 100644
index 0000000000..a9531baf33
--- /dev/null
+++ b/usr/src/cmd/hal/hald/device.h
@@ -0,0 +1,215 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device.c : HalDevice methods
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2004 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef DEVICE_H
+#define DEVICE_H
+
+#include <glib-object.h>
+#include <dbus/dbus.h>
+
+#include "property.h"
+
+typedef struct _HalDevice HalDevice;
+typedef struct _HalDeviceClass HalDeviceClass;
+
+struct _HalDevice {
+ GObject parent;
+
+ char *udi;
+
+ GSList *properties;
+
+ int num_addons;
+ int num_addons_ready;
+};
+
+struct _HalDeviceClass {
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*property_changed) (HalDevice *device,
+ const char *key,
+ gboolean removed,
+ gboolean added);
+
+ void (*capability_added) (HalDevice *device,
+ const char *capability);
+
+ void (*callouts_finished) (HalDevice *device);
+
+ void (*cancelled) (HalDevice *device);
+};
+
+#define HAL_TYPE_DEVICE (hal_device_get_type ())
+#define HAL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ HAL_TYPE_DEVICE, HalDevice))
+#define HAL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ HAL_TYPE_DEVICE, HalDeviceClass))
+#define HAL_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ HAL_TYPE_DEVICE))
+#define HAL_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ HAL_TYPE_DEVICE))
+
+typedef void (*HalDeviceAsyncCallback) (HalDevice *device,
+ gpointer user_data,
+ gboolean prop_exists);
+
+/* Return value of FALSE means that the foreach should be short-circuited */
+typedef gboolean (*HalDevicePropertyForeachFn) (HalDevice *device,
+ HalProperty *property,
+ gpointer user_data);
+
+GType hal_device_get_type (void);
+
+HalDevice *hal_device_new (void);
+
+void hal_device_merge (HalDevice *target,
+ HalDevice *source);
+
+void hal_device_merge_with_rewrite (HalDevice *target,
+ HalDevice *source,
+ const char *target_namespace,
+ const char *source_namespace);
+
+gboolean hal_device_matches (HalDevice *device1,
+ HalDevice *device2,
+ const char *namespace);
+
+const char *hal_device_get_udi (HalDevice *device);
+void hal_device_set_udi (HalDevice *device,
+ const char *udi);
+
+void hal_device_add_capability (HalDevice *device,
+ const char *capability);
+gboolean hal_device_has_capability (HalDevice *device,
+ const char *capability);
+
+gboolean hal_device_has_property (HalDevice *device,
+ const char *key);
+HalProperty *hal_device_property_find (HalDevice *device,
+ const char *key);
+int hal_device_num_properties (HalDevice *device);
+char * hal_device_property_to_string (HalDevice *device,
+ const char *key);
+void hal_device_property_foreach (HalDevice *device,
+ HalDevicePropertyForeachFn callback,
+ gpointer user_data);
+
+int hal_device_property_get_type (HalDevice *device,
+ const char *key);
+const char *hal_device_property_get_as_string (HalDevice *device,
+ const char *key,
+ char *buf,
+ size_t bufsize);
+
+
+const char *hal_device_property_get_string (HalDevice *device,
+ const char *key);
+dbus_int32_t hal_device_property_get_int (HalDevice *device,
+ const char *key);
+dbus_uint64_t hal_device_property_get_uint64 (HalDevice *device,
+ const char *key);
+dbus_bool_t hal_device_property_get_bool (HalDevice *device,
+ const char *key);
+double hal_device_property_get_double (HalDevice *device,
+ const char *key);
+GSList *hal_device_property_get_strlist (HalDevice *device,
+ const char *key);
+const char *hal_device_property_get_strlist_elem (HalDevice *device,
+ const char *key,
+ guint index);
+
+
+
+gboolean hal_device_property_set_string (HalDevice *device,
+ const char *key,
+ const char *value);
+gboolean hal_device_property_set_int (HalDevice *device,
+ const char *key,
+ dbus_int32_t value);
+gboolean hal_device_property_set_uint64 (HalDevice *device,
+ const char *key,
+ dbus_uint64_t value);
+gboolean hal_device_property_set_bool (HalDevice *device,
+ const char *key,
+ dbus_bool_t value);
+gboolean hal_device_property_set_double (HalDevice *device,
+ const char *key,
+ double value);
+gboolean hal_device_property_strlist_append (HalDevice *device,
+ const char *key,
+ const char *value);
+gboolean hal_device_property_strlist_prepend (HalDevice *device,
+ const char *key,
+ const char *value);
+gboolean hal_device_property_strlist_remove_elem (HalDevice *device,
+ const char *key,
+ guint index);
+gboolean hal_device_property_strlist_clear (HalDevice *device,
+ const char *key);
+gboolean hal_device_property_strlist_add (HalDevice *device,
+ const char *key,
+ const char *value);
+gboolean hal_device_property_strlist_remove (HalDevice *device,
+ const char *key,
+ const char *value);
+gboolean hal_device_property_strlist_is_empty (HalDevice *device,
+ const char *key);
+
+gboolean hal_device_property_remove (HalDevice *device,
+ const char *key);
+
+gboolean hal_device_copy_property (HalDevice *from_device,
+ const char *from,
+ HalDevice *to_device,
+ const char *to);
+
+
+void hal_device_print (HalDevice *device);
+
+void hal_device_async_wait_property (HalDevice *device,
+ const char *key,
+ HalDeviceAsyncCallback callback,
+ gpointer user_data,
+ int timeout);
+
+void hal_device_callouts_finished (HalDevice *device);
+
+void hal_device_cancel (HalDevice *device);
+
+gboolean hal_device_property_set_attribute (HalDevice *device,
+ const char *key,
+ enum PropertyAttribute attr,
+ gboolean persistence);
+
+void hal_device_inc_num_addons (HalDevice *device);
+
+gboolean hal_device_inc_num_ready_addons (HalDevice *device);
+
+gboolean hal_device_are_all_addons_ready (HalDevice *device);
+
+
+#endif /* DEVICE_H */
diff --git a/usr/src/cmd/hal/hald/device_info.c b/usr/src/cmd/hal/hald/device_info.c
new file mode 100644
index 0000000000..20359201e8
--- /dev/null
+++ b/usr/src/cmd/hal/hald/device_info.c
@@ -0,0 +1,1648 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device_store.c : Search for .fdi files and merge on match
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <expat.h>
+#include <assert.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <math.h>
+
+#include "hald.h"
+#include "logger.h"
+#include "device_info.h"
+#include "device_store.h"
+#include "util.h"
+
+/**
+ * @defgroup DeviceInfo Device Info File Parsing
+ * @ingroup HalDaemon
+ * @brief Parsing of device info files
+ * @{
+ */
+
+
+/** Maximum nesting depth */
+#define MAX_DEPTH 32
+
+/** Maximum amount of CDATA */
+#define CDATA_BUF_SIZE 1024
+
+/** Max length of property key */
+#define MAX_KEY_SIZE 128
+
+/** Possible elements the parser can process */
+enum {
+ /** Not processing a known tag */
+ CURELEM_UNKNOWN = -1,
+
+ /** Processing a deviceinfo element */
+ CURELEM_DEVICE_INFO = 0,
+
+ /** Processing a device element */
+ CURELEM_DEVICE = 1,
+
+ /** Processing a match element */
+ CURELEM_MATCH = 2,
+
+ /** Processing a merge element */
+ CURELEM_MERGE = 3,
+
+ /** Processing an append element */
+ CURELEM_APPEND = 4,
+
+ /** Processing a prepend element */
+ CURELEM_PREPEND = 5,
+
+ /** Processing a remove element */
+ CURELEM_REMOVE = 6,
+
+ /** Processing a clear element */
+ CURELEM_CLEAR = 7,
+
+ /** Processing a spawn element */
+ CURELEM_SPAWN = 8
+};
+
+/** What and how to merge */
+enum {
+ MERGE_TYPE_UNKNOWN = 0,
+ MERGE_TYPE_STRING = 1,
+ MERGE_TYPE_BOOLEAN = 2,
+ MERGE_TYPE_INT32 = 3,
+ MERGE_TYPE_UINT64 = 4,
+ MERGE_TYPE_DOUBLE = 5,
+ MERGE_TYPE_COPY_PROPERTY = 6,
+ MERGE_TYPE_STRLIST = 7,
+ MERGE_TYPE_REMOVE = 8,
+ MERGE_TYPE_CLEAR = 9,
+ MERGE_TYPE_SPAWN = 10
+};
+
+/** Parsing Context
+ */
+typedef struct {
+ /** Name of file being parsed */
+ char *file;
+
+ /** Parser object */
+ XML_Parser parser;
+
+ /** Device we are trying to match*/
+ HalDevice *device;
+
+ /** Buffer to put CDATA in */
+ char cdata_buf[CDATA_BUF_SIZE];
+
+ /** Current length of CDATA buffer */
+ int cdata_buf_len;
+
+ /** Current depth we are parsing at */
+ int depth;
+
+ /** Element currently being processed */
+ int curelem;
+
+ /** Stack of elements being processed */
+ int curelem_stack[MAX_DEPTH];
+
+ /** #TRUE if parsing of document have been aborted */
+ dbus_bool_t aborted;
+
+
+ /** Depth of match-fail */
+ int match_depth_first_fail;
+
+ /** #TRUE if all matches on prior depths have been OK */
+ dbus_bool_t match_ok;
+
+
+
+ /** When merging, the key to store the value in */
+ char merge_key[MAX_KEY_SIZE];
+
+ /** Type to merge*/
+ int merge_type;
+
+ /** Set to #TRUE if a device is matched */
+ dbus_bool_t device_matched;
+
+} ParsingContext;
+
+/** Resolve a udi-property path as used in .fdi files.
+ *
+ * Examples of udi-property paths:
+ *
+ * info.udi
+ * /org/freedesktop/Hal/devices/computer:kernel.name
+ * @block.storage_device:storage.bus
+ * @block.storage_device:@storage.physical_device:ide.channel
+ *
+ * @param source_udi UDI of source device
+ * @param path The given path
+ * @param udi_result Where to store the resulting UDI
+ * @param udi_result_size Size of UDI string
+ * @param prop_result Where to store the resulting property name
+ * @param prop_result_size Size of property string
+ * @return TRUE if and only if the path resolved.
+ */
+static gboolean
+resolve_udiprop_path (const char *path, const char *source_udi,
+ char *udi_result, size_t udi_result_size,
+ char *prop_result, size_t prop_result_size)
+{
+ int i;
+ gchar **tokens = NULL;
+ gboolean rc;
+
+ rc = FALSE;
+
+ /*HAL_INFO (("Looking at '%s' for udi='%s'", path, source_udi));*/
+
+ /* Split up path into ':' tokens */
+ tokens = g_strsplit (path, ":", 64);
+
+ /* Detect trivial property access, e.g. path='foo.bar' */
+ if (tokens == NULL || tokens[0] == NULL || tokens[1] == NULL) {
+ strncpy (udi_result, source_udi, udi_result_size);
+ strncpy (prop_result, path, prop_result_size);
+ rc = TRUE;
+ goto out;
+ }
+
+ /* Start with the source udi */
+ strncpy (udi_result, source_udi, udi_result_size);
+
+ for (i = 0; tokens[i] != NULL; i++) {
+ HalDevice *d;
+ gchar *curtoken;
+
+ /*HAL_INFO (("tokens[%d] = '%s'", i, tokens[i]));*/
+
+ d = hal_device_store_find (hald_get_gdl (), udi_result);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi_result);
+ if (d == NULL)
+ goto out;
+
+ curtoken = tokens[i];
+
+ /* process all but the last tokens as UDI paths */
+ if (tokens[i+1] == NULL) {
+ strncpy (prop_result, curtoken, prop_result_size);
+ rc = TRUE;
+ goto out;
+ }
+
+
+ /* Check for indirection */
+ if (curtoken[0] == '@') {
+ const char *udiprop;
+ const char *newudi;
+
+ udiprop = curtoken + 1;
+
+ newudi = hal_device_property_get_string (d, udiprop);
+ if (newudi == NULL)
+ goto out;
+
+ /*HAL_INFO (("new_udi = '%s' (from indirection)", newudi));*/
+
+ strncpy (udi_result, newudi, udi_result_size);
+ } else {
+ /*HAL_INFO (("new_udi = '%s'", curtoken));*/
+ strncpy (udi_result, curtoken, udi_result_size);
+ }
+
+ }
+
+out:
+
+/*
+ HAL_INFO (("success = '%s'", rc ? "yes" : "no"));
+ HAL_INFO (("udi_result = '%s'", udi_result));
+ HAL_INFO (("prop_result = '%s'", prop_result));
+*/
+
+ g_strfreev (tokens);
+
+ return rc;
+}
+
+/* Compare the value of a property on a hal device object against a string value
+ * and return the result. Note that this works for several types, e.g. both strings
+ * and integers - in the latter case the given right side string will be interpreted
+ * as a number.
+ *
+ * The comparison might not make sense if you are comparing a property which is an integer
+ * against a string in which case this function returns FALSE. Also, if the property doesn't
+ * exist this function will also return FALSE.
+ *
+ * @param d hal device object
+ * @param key Key of the property to compare
+ * @param right_side Value to compare against
+ * @param result Pointer to where to store result
+ * @return TRUE if, and only if, the comparison could take place
+ */
+static gboolean
+match_compare_property (HalDevice *d, const char *key, const char *right_side, dbus_int64_t *result)
+{
+ gboolean rc;
+ int proptype;
+
+ rc = FALSE;
+
+ if (!hal_device_has_property (d, key))
+ goto out;
+
+ proptype = hal_device_property_get_type (d, key);
+ switch (proptype) {
+ case HAL_PROPERTY_TYPE_STRING:
+ *result = (dbus_int64_t) strcmp (hal_device_property_get_string (d, key), right_side);
+ rc = TRUE;
+ break;
+
+ case HAL_PROPERTY_TYPE_INT32:
+ *result = ((dbus_int64_t) hal_device_property_get_int (d, key)) - strtoll (right_side, NULL, 0);
+ rc = TRUE;
+ break;
+
+ case HAL_PROPERTY_TYPE_UINT64:
+ *result = ((dbus_int64_t) hal_device_property_get_uint64 (d, key)) - ((dbus_int64_t) strtoll (right_side, NULL, 0));
+ rc = TRUE;
+ break;
+
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ *result = (dbus_int64_t) ceil (hal_device_property_get_double (d, key) - atof (right_side));
+ rc = TRUE;
+ break;
+
+ default:
+ /* explicit fallthrough */
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ /* explicit blank since this doesn't make sense */
+ break;
+ }
+
+out:
+ return rc;
+}
+
+/** Called when the match element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ * @return #FALSE if the device in question didn't
+ * match the data in the attributes
+ */
+static dbus_bool_t
+handle_match (ParsingContext * pc, const char **attr)
+{
+ char udi_to_check[256];
+ char prop_to_check[256];
+ const char *key;
+ int num_attrib;
+ HalDevice *d;
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++);
+
+ if (num_attrib != 4)
+ return FALSE;
+
+ if (strcmp (attr[0], "key") != 0)
+ return FALSE;
+ key = attr[1];
+
+ /* Resolve key paths like 'someudi/foo/bar/baz:prop.name' '@prop.here.is.an.udi:with.prop.name' */
+ if (!resolve_udiprop_path (key,
+ pc->device->udi,
+ udi_to_check, sizeof (udi_to_check),
+ prop_to_check, sizeof (prop_to_check))) {
+ HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", key, pc->device->udi));
+ return FALSE;
+ }
+
+ d = hal_device_store_find (hald_get_gdl (), udi_to_check);
+ if (d == NULL) {
+ d = hal_device_store_find (hald_get_tdl (), udi_to_check);
+ }
+ if (d == NULL) {
+ HAL_ERROR (("Could not find device with udi '%s'", udi_to_check));
+ return FALSE;
+ }
+
+
+ if (strcmp (attr[2], "string") == 0) {
+ const char *value;
+
+ /* match string property */
+
+ value = attr[3];
+
+ /*HAL_INFO(("Checking that key='%s' is a string that "
+ "equals '%s'", key, value)); */
+
+ if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
+ return FALSE;
+
+ if (strcmp (hal_device_property_get_string (d, prop_to_check),
+ value) != 0)
+ return FALSE;
+
+ /*HAL_INFO (("*** string match for key %s", key));*/
+ return TRUE;
+ } else if (strcmp (attr[2], "int") == 0) {
+ dbus_int32_t value;
+
+ /* match integer property */
+ value = strtol (attr[3], NULL, 0);
+
+ /** @todo Check error condition */
+
+ /*HAL_INFO (("Checking that key='%s' is a int that equals %d",
+ key, value));*/
+
+ if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_INT32)
+ return FALSE;
+
+ if (hal_device_property_get_int (d, prop_to_check) != value) {
+ return FALSE;
+ }
+
+ return TRUE;
+ } else if (strcmp (attr[2], "uint64") == 0) {
+ dbus_uint64_t value;
+
+ /* match integer property */
+ value = strtoull (attr[3], NULL, 0);
+
+ /** @todo Check error condition */
+
+ /*HAL_INFO (("Checking that key='%s' is a int that equals %d",
+ key, value));*/
+
+ if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_UINT64)
+ return FALSE;
+
+ if (hal_device_property_get_uint64 (d, prop_to_check) != value) {
+ return FALSE;
+ }
+
+ return TRUE;
+ } else if (strcmp (attr[2], "bool") == 0) {
+ dbus_bool_t value;
+
+ /* match string property */
+
+ if (strcmp (attr[3], "false") == 0)
+ value = FALSE;
+ else if (strcmp (attr[3], "true") == 0)
+ value = TRUE;
+ else
+ return FALSE;
+
+ /*HAL_INFO (("Checking that key='%s' is a bool that equals %s",
+ key, value ? "TRUE" : "FALSE"));*/
+
+ if (hal_device_property_get_type (d, prop_to_check) !=
+ HAL_PROPERTY_TYPE_BOOLEAN)
+ return FALSE;
+
+ if (hal_device_property_get_bool (d, prop_to_check) != value)
+ return FALSE;
+
+ /*HAL_INFO (("*** bool match for key %s", key));*/
+ return TRUE;
+ } else if (strcmp (attr[2], "exists") == 0) {
+ dbus_bool_t should_exist = TRUE;
+
+ if (strcmp (attr[3], "false") == 0)
+ should_exist = FALSE;
+
+ if (should_exist) {
+ if (hal_device_has_property (d, prop_to_check))
+ return TRUE;
+ else
+ return FALSE;
+ } else {
+ if (hal_device_has_property (d, prop_to_check))
+ return FALSE;
+ else
+ return TRUE;
+ }
+ } else if (strcmp (attr[2], "empty") == 0) {
+ int type;
+ dbus_bool_t is_empty = TRUE;
+ dbus_bool_t should_be_empty = TRUE;
+
+
+ if (strcmp (attr[3], "false") == 0)
+ should_be_empty = FALSE;
+
+ type = hal_device_property_get_type (d, prop_to_check);
+ switch (type) {
+ case HAL_PROPERTY_TYPE_STRING:
+ if (hal_device_has_property (d, prop_to_check))
+ if (strlen (hal_device_property_get_string (d, prop_to_check)) > 0)
+ is_empty = FALSE;
+ break;
+ case HAL_PROPERTY_TYPE_STRLIST:
+ if (hal_device_has_property (d, prop_to_check))
+ if (!hal_device_property_strlist_is_empty(d, prop_to_check))
+ is_empty = FALSE;
+ break;
+ default:
+ /* explicit fallthrough */
+ return FALSE;
+ break;
+ }
+
+ if (should_be_empty) {
+ if (is_empty)
+ return TRUE;
+ else
+ return FALSE;
+ } else {
+ if (is_empty)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ } else if (strcmp (attr[2], "is_ascii") == 0) {
+ dbus_bool_t is_ascii = TRUE;
+ dbus_bool_t should_be_ascii = TRUE;
+ unsigned int i;
+ const char *str;
+
+ if (strcmp (attr[3], "false") == 0)
+ should_be_ascii = FALSE;
+
+ if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
+ return FALSE;
+
+ is_ascii = TRUE;
+
+ str = hal_device_property_get_string (d, prop_to_check);
+ for (i = 0; str[i] != '\0'; i++) {
+ if (((unsigned char) str[i]) > 0x7f)
+ is_ascii = FALSE;
+ }
+
+ if (should_be_ascii) {
+ if (is_ascii)
+ return TRUE;
+ else
+ return FALSE;
+ } else {
+ if (is_ascii)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ } else if (strcmp (attr[2], "is_absolute_path") == 0) {
+ const char *path = NULL;
+ dbus_bool_t is_absolute_path = FALSE;
+ dbus_bool_t should_be_absolute_path = TRUE;
+
+ if (strcmp (attr[3], "false") == 0)
+ should_be_absolute_path = FALSE;
+
+ /*HAL_INFO (("d->udi='%s', prop_to_check='%s'", d->udi, prop_to_check));*/
+
+ if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
+ return FALSE;
+
+ if (hal_device_has_property (d, prop_to_check)) {
+ path = hal_device_property_get_string (d, prop_to_check);
+ if (g_path_is_absolute (path))
+ is_absolute_path = TRUE;
+ }
+
+ /*HAL_INFO (("is_absolute=%d, should_be=%d, path='%s'", is_absolute_path, should_be_absolute_path, path));*/
+
+ if (should_be_absolute_path) {
+ if (is_absolute_path)
+ return TRUE;
+ else
+ return FALSE;
+ } else {
+ if (is_absolute_path)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ } else if (strcmp (attr[2], "contains") == 0) {
+ const char *needle;
+ dbus_bool_t contains = FALSE;
+
+ needle = attr[3];
+
+ if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRING) {
+ if (hal_device_has_property (d, prop_to_check)) {
+ const char *haystack;
+
+ haystack = hal_device_property_get_string (d, prop_to_check);
+ if (needle != NULL && haystack != NULL && strstr (haystack, needle)) {
+ contains = TRUE;
+ }
+
+ }
+ } else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST &&
+ needle != NULL) {
+ GSList *i;
+ GSList *value;
+
+ value = hal_device_property_get_strlist (d, prop_to_check);
+ for (i = value; i != NULL; i = g_slist_next (i)) {
+ const char *str = i->data;
+ if (strcmp (str, needle) == 0) {
+ contains = TRUE;
+ break;
+ }
+ }
+ } else {
+ return FALSE;
+ }
+
+ return contains;
+ } else if (strcmp (attr[2], "contains_ncase") == 0) {
+ const char *needle;
+ dbus_bool_t contains_ncase = FALSE;
+
+ needle = attr[3];
+
+ if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRING) {
+ if (hal_device_has_property (d, prop_to_check)) {
+ char *needle_lowercase;
+ char *haystack_lowercase;
+
+ needle_lowercase = g_utf8_strdown (needle, -1);
+ haystack_lowercase = g_utf8_strdown (hal_device_property_get_string (d, prop_to_check), -1);
+ if (needle_lowercase != NULL && haystack_lowercase != NULL && strstr (haystack_lowercase, needle_lowercase)) {
+ contains_ncase = TRUE;
+ }
+
+ g_free (needle_lowercase);
+ g_free (haystack_lowercase);
+ }
+ } else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST &&
+ needle != NULL) {
+ GSList *i;
+ GSList *value;
+
+ value = hal_device_property_get_strlist (d, prop_to_check);
+ for (i = value; i != NULL; i = g_slist_next (i)) {
+ const char *str = i->data;
+ if (g_ascii_strcasecmp (str, needle) == 0) {
+ contains_ncase = TRUE;
+ break;
+ }
+ }
+ } else {
+ return FALSE;
+ }
+
+ return contains_ncase;
+ } else if (strcmp (attr[2], "compare_lt") == 0) {
+ dbus_int64_t result;
+ if (!match_compare_property (d, prop_to_check, attr[3], &result)) {
+ return FALSE;
+ } else {
+ return result < 0;
+ }
+ } else if (strcmp (attr[2], "compare_le") == 0) {
+ dbus_int64_t result;
+ if (!match_compare_property (d, prop_to_check, attr[3], &result))
+ return FALSE;
+ else
+ return result <= 0;
+ } else if (strcmp (attr[2], "compare_gt") == 0) {
+ dbus_int64_t result;
+ if (!match_compare_property (d, prop_to_check, attr[3], &result))
+ return FALSE;
+ else
+ return result > 0;
+ } else if (strcmp (attr[2], "compare_ge") == 0) {
+ dbus_int64_t result;
+ if (!match_compare_property (d, prop_to_check, attr[3], &result))
+ return FALSE;
+ else
+ return result >= 0;
+ }
+
+ return FALSE;
+}
+
+
+/** Called when the merge element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ */
+static void
+handle_merge (ParsingContext * pc, const char **attr)
+{
+ int num_attrib;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++) {
+ ;
+ }
+
+ if (num_attrib != 4)
+ return;
+
+ if (strcmp (attr[0], "key") != 0)
+ return;
+ strncpy (pc->merge_key, attr[1], MAX_KEY_SIZE);
+
+ if (strcmp (attr[2], "type") != 0)
+ return;
+
+ if (strcmp (attr[3], "string") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_STRING;
+ return;
+ } else if (strcmp (attr[3], "bool") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_BOOLEAN;
+ return;
+ } else if (strcmp (attr[3], "int") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_INT32;
+ return;
+ } else if (strcmp (attr[3], "uint64") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_UINT64;
+ return;
+ } else if (strcmp (attr[3], "double") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_DOUBLE;
+ return;
+ } else if (strcmp (attr[3], "strlist") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_STRLIST;
+ return;
+ } else if (strcmp (attr[3], "copy_property") == 0) {
+ /* copy another property */
+ pc->merge_type = MERGE_TYPE_COPY_PROPERTY;
+ return;
+ }
+
+ return;
+}
+
+/** Called when the append or prepend element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ */
+static void
+handle_append_prepend (ParsingContext * pc, const char **attr)
+{
+ int num_attrib;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++) {
+ ;
+ }
+
+ if (num_attrib != 4)
+ return;
+
+ if (strcmp (attr[0], "key") != 0)
+ return;
+ strncpy (pc->merge_key, attr[1], MAX_KEY_SIZE);
+
+ if (strcmp (attr[2], "type") != 0)
+ return;
+
+ if (strcmp (attr[3], "string") == 0) {
+ /* append to a string */
+ pc->merge_type = MERGE_TYPE_STRING;
+ return;
+ } else if (strcmp (attr[3], "strlist") == 0) {
+ /* append to a string list*/
+ pc->merge_type = MERGE_TYPE_STRLIST;
+ return;
+ } else if (strcmp (attr[3], "copy_property") == 0) {
+ /* copy another property */
+ pc->merge_type = MERGE_TYPE_COPY_PROPERTY;
+ return;
+ }
+
+ return;
+}
+
+
+/** Called when the spawn element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ */
+static void
+handle_spawn (ParsingContext * pc, const char **attr)
+{
+ int num_attrib;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++) {
+ ;
+ }
+
+ if (num_attrib != 2)
+ return;
+
+ if (strcmp (attr[0], "udi") != 0)
+ return;
+
+ strncpy (pc->merge_key, attr[1], MAX_KEY_SIZE);
+
+ pc->merge_type = MERGE_TYPE_SPAWN;
+ return;
+}
+
+/** Called when the remove element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ */
+static void
+handle_remove (ParsingContext * pc, const char **attr)
+{
+ int num_attrib;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++) {
+ ;
+ }
+
+ if (num_attrib != 2 && num_attrib != 4)
+ return;
+
+ if (strcmp (attr[0], "key") != 0)
+ return;
+ strncpy (pc->merge_key, attr[1], MAX_KEY_SIZE);
+
+ if (num_attrib == 4) {
+ if (strcmp (attr[2], "type") != 0)
+ return;
+
+ if (strcmp (attr[3], "strlist") == 0) {
+ /* remove from strlist */
+ pc->merge_type = MERGE_TYPE_STRLIST;
+ return;
+ } else {
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+ return;
+ }
+ } else {
+ pc->merge_type = MERGE_TYPE_REMOVE;
+ }
+
+ return;
+}
+
+/** Called when the clear element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ */
+static void
+handle_clear (ParsingContext * pc, const char **attr)
+{
+ int num_attrib;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++) {
+ ;
+ }
+
+ if (num_attrib != 4)
+ return;
+
+ if (strcmp (attr[0], "key") != 0)
+ return;
+
+
+ if (strcmp (attr[3], "strlist") != 0)
+ return;
+
+ strncpy (pc->merge_key, attr[1], MAX_KEY_SIZE);
+
+ pc->merge_type = MERGE_TYPE_CLEAR;
+
+ return;
+}
+
+/** Abort parsing of document
+ *
+ * @param pc Parsing context
+ */
+static void
+parsing_abort (ParsingContext * pc)
+{
+ /* Grr, expat can't abort parsing */
+ HAL_ERROR (("Aborting parsing of document"));
+ pc->aborted = TRUE;
+}
+
+/** Called by expat when an element begins.
+ *
+ * @param pc Parsing context
+ * @param el Element name
+ * @param attr Attribute key/value pairs
+ */
+static void
+start (ParsingContext * pc, const char *el, const char **attr)
+{
+ if (pc->aborted)
+ return;
+
+ pc->cdata_buf_len = 0;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+/*
+ for (i = 0; i < pc->depth; i++)
+ printf(" ");
+
+ printf("%s", el);
+
+ for (i = 0; attr[i]; i += 2) {
+ printf(" %s='%s'", attr[i], attr[i + 1]);
+ }
+
+ printf(" curelem=%d\n", pc->curelem);
+*/
+
+ if (strcmp (el, "match") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <match> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_MATCH;
+
+ /* don't bother checking if matching at lower depths failed */
+ if (pc->match_ok) {
+ if (!handle_match (pc, attr)) {
+ /* No match */
+ pc->match_depth_first_fail = pc->depth;
+ pc->match_ok = FALSE;
+ }
+ }
+ } else if (strcmp (el, "merge") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <merge> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_MERGE;
+ if (pc->match_ok) {
+ handle_merge (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "append") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <append> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_APPEND;
+ if (pc->match_ok) {
+ handle_append_prepend (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "prepend") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <prepend> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_PREPEND;
+ if (pc->match_ok) {
+ handle_append_prepend (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "remove") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <remove> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_REMOVE;
+ if (pc->match_ok) {
+ handle_remove (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "clear") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <remove> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_CLEAR;
+ if (pc->match_ok) {
+ handle_clear (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "device") == 0) {
+ if (pc->curelem != CURELEM_DEVICE_INFO) {
+ HAL_ERROR (("%s:%d:%d: Element <device> can only be "
+ "inside <deviceinfo>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+ pc->curelem = CURELEM_DEVICE;
+ } else if (strcmp (el, "deviceinfo") == 0) {
+ if (pc->curelem != CURELEM_UNKNOWN) {
+ HAL_ERROR (("%s:%d:%d: Element <deviceinfo> must be "
+ "a top-level element",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+ pc->curelem = CURELEM_DEVICE_INFO;
+ } else if (strcmp (el, "spawn") == 0) {
+ if (pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <spawn> can only be "
+ "inside <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_SPAWN;
+ if (pc->match_ok) {
+ handle_spawn (pc, attr);
+ }
+
+ } else {
+ HAL_ERROR (("%s:%d:%d: Unknown element <%s>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser), el));
+ parsing_abort (pc);
+ }
+
+ /* Nasty hack */
+ assert (pc->depth < MAX_DEPTH);
+
+ pc->depth++;
+
+ /* store depth */
+ pc->curelem_stack[pc->depth] = pc->curelem;
+
+}
+
+static void
+spawned_device_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ HAL_INFO (("Add callouts completed udi=%s", d->udi));
+
+ /* Move from temporary to global device store */
+ hal_device_store_remove (hald_get_tdl (), d);
+ hal_device_store_add (hald_get_gdl (), d);
+
+}
+
+/** Called by expat when an element ends.
+ *
+ * @param pc Parsing context
+ * @param el Element name
+ */
+static void
+end (ParsingContext * pc, const char *el)
+{
+ if (pc->aborted)
+ return;
+
+ pc->cdata_buf[pc->cdata_buf_len] = '\0';
+
+/* printf(" curelem=%d\n", pc->curelem);*/
+
+ if (pc->curelem == CURELEM_MERGE && pc->match_ok) {
+ /* As soon as we are merging, we have matched the device... */
+ pc->device_matched = TRUE;
+
+ switch (pc->merge_type) {
+ case MERGE_TYPE_STRING:
+ hal_device_property_set_string (pc->device, pc->merge_key, pc->cdata_buf);
+ break;
+
+ case MERGE_TYPE_STRLIST:
+ {
+ int type = hal_device_property_get_type (pc->device, pc->merge_key);
+ if (type == HAL_PROPERTY_TYPE_STRLIST || type == HAL_PROPERTY_TYPE_INVALID) {
+ hal_device_property_remove (pc->device, pc->merge_key);
+ hal_device_property_strlist_append (pc->device, pc->merge_key, pc->cdata_buf);
+ }
+ break;
+ }
+
+ case MERGE_TYPE_INT32:
+ {
+ dbus_int32_t value;
+
+ /* match integer property */
+ value = strtol (pc->cdata_buf, NULL, 0);
+
+ /** @todo FIXME: Check error condition */
+
+ hal_device_property_set_int (pc->device,
+ pc->merge_key, value);
+ break;
+ }
+
+ case MERGE_TYPE_UINT64:
+ {
+ dbus_uint64_t value;
+
+ /* match integer property */
+ value = strtoull (pc->cdata_buf, NULL, 0);
+
+ /** @todo FIXME: Check error condition */
+
+ hal_device_property_set_uint64 (pc->device,
+ pc->merge_key, value);
+ break;
+ }
+
+ case MERGE_TYPE_BOOLEAN:
+ hal_device_property_set_bool (pc->device, pc->merge_key,
+ (strcmp (pc->cdata_buf,
+ "true") == 0)
+ ? TRUE : FALSE);
+ break;
+
+ case MERGE_TYPE_DOUBLE:
+ hal_device_property_set_double (pc->device, pc->merge_key,
+ atof (pc->cdata_buf));
+ break;
+
+ case MERGE_TYPE_COPY_PROPERTY:
+ {
+ char udi_to_merge_from[256];
+ char prop_to_merge[256];
+
+ /* Resolve key paths like 'someudi/foo/bar/baz:prop.name'
+ * '@prop.here.is.an.udi:with.prop.name'
+ */
+ if (!resolve_udiprop_path (pc->cdata_buf,
+ pc->device->udi,
+ udi_to_merge_from, sizeof (udi_to_merge_from),
+ prop_to_merge, sizeof (prop_to_merge))) {
+ HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", pc->cdata_buf, pc->device->udi));
+ } else {
+ HalDevice *d;
+
+ d = hal_device_store_find (hald_get_gdl (), udi_to_merge_from);
+ if (d == NULL) {
+ d = hal_device_store_find (hald_get_tdl (), udi_to_merge_from);
+ }
+ if (d == NULL) {
+ HAL_ERROR (("Could not find device with udi '%s'", udi_to_merge_from));
+ } else {
+ hal_device_copy_property (d, prop_to_merge, pc->device, pc->merge_key);
+ }
+ }
+ break;
+ }
+
+ default:
+ HAL_ERROR (("Unknown merge_type=%d='%c'",
+ pc->merge_type, pc->merge_type));
+ break;
+ }
+ } else if (pc->curelem == CURELEM_APPEND && pc->match_ok &&
+ (hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRING ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRLIST ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_INVALID)) {
+ char buf[256];
+ char buf2[256];
+
+ /* As soon as we are appending, we have matched the device... */
+ pc->device_matched = TRUE;
+
+ if (pc->merge_type == MERGE_TYPE_STRLIST) {
+ hal_device_property_strlist_append (pc->device, pc->merge_key, pc->cdata_buf);
+ } else {
+ const char *existing_string;
+
+ switch (pc->merge_type) {
+ case MERGE_TYPE_STRING:
+ strncpy (buf, pc->cdata_buf, sizeof (buf));
+ break;
+
+ case MERGE_TYPE_COPY_PROPERTY:
+ hal_device_property_get_as_string (pc->device, pc->cdata_buf, buf, sizeof (buf));
+ break;
+
+ default:
+ HAL_ERROR (("Unknown merge_type=%d='%c'", pc->merge_type, pc->merge_type));
+ break;
+ }
+
+ existing_string = hal_device_property_get_string (pc->device, pc->merge_key);
+ if (existing_string != NULL) {
+ strncpy (buf2, existing_string, sizeof (buf2));
+ strncat (buf2, buf, sizeof (buf2) - strlen(buf2));
+ } else {
+ strncpy (buf2, buf, sizeof (buf2));
+ }
+ hal_device_property_set_string (pc->device, pc->merge_key, buf2);
+ }
+ } else if (pc->curelem == CURELEM_PREPEND && pc->match_ok &&
+ (hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRING ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRLIST ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_INVALID)) {
+ char buf[256];
+ char buf2[256];
+
+ /* As soon as we are prepending, we have matched the device... */
+ pc->device_matched = TRUE;
+
+ if (pc->merge_type == MERGE_TYPE_STRLIST) {
+ hal_device_property_strlist_prepend (pc->device, pc->merge_key, pc->cdata_buf);
+ } else {
+ const char *existing_string;
+
+ switch (pc->merge_type) {
+ case MERGE_TYPE_STRING:
+ strncpy (buf, pc->cdata_buf, sizeof (buf));
+ break;
+
+ case MERGE_TYPE_COPY_PROPERTY:
+ hal_device_property_get_as_string (pc->device, pc->cdata_buf, buf, sizeof (buf));
+ break;
+
+ default:
+ HAL_ERROR (("Unknown merge_type=%d='%c'", pc->merge_type, pc->merge_type));
+ break;
+ }
+
+ existing_string = hal_device_property_get_string (pc->device, pc->merge_key);
+ if (existing_string != NULL) {
+ strncpy (buf2, buf, sizeof (buf2));
+ strncat (buf2, existing_string, sizeof (buf2) - strlen(buf2));
+ } else {
+ strncpy (buf2, buf, sizeof (buf2));
+ }
+ hal_device_property_set_string (pc->device, pc->merge_key, buf2);
+ }
+ } else if (pc->curelem == CURELEM_REMOVE && pc->match_ok) {
+
+ if (pc->merge_type == MERGE_TYPE_STRLIST) {
+ /* covers <remove key="foobar" type="strlist">blah</remove> */
+ hal_device_property_strlist_remove (pc->device, pc->merge_key, pc->cdata_buf);
+ } else {
+ /* only allow <remove key="foobar"/>, not <remove key="foobar">blah</remove> */
+ if (strlen (pc->cdata_buf) == 0) {
+ hal_device_property_remove (pc->device, pc->merge_key);
+ }
+ }
+ } else if (pc->merge_type == MERGE_TYPE_SPAWN) {
+ HalDevice *spawned;
+
+ spawned = hal_device_store_find (hald_get_gdl (), pc->merge_key);
+ if (spawned == NULL)
+ spawned = hal_device_store_find (hald_get_tdl (), pc->merge_key);
+
+ if (spawned == NULL) {
+ HAL_INFO (("Spawning new device object '%s' caused by <spawn> on udi '%s'",
+ pc->merge_key, pc->device->udi));
+
+ spawned = hal_device_new ();
+ hal_device_property_set_string (spawned, "info.bus", "unknown");
+ hal_device_property_set_string (spawned, "info.udi", pc->merge_key);
+ hal_device_property_set_string (spawned, "info.parent", pc->device->udi);
+ hal_device_set_udi (spawned, pc->merge_key);
+
+ hal_device_store_add (hald_get_tdl (), spawned);
+
+ di_search_and_merge (spawned, DEVICE_INFO_TYPE_INFORMATION);
+ di_search_and_merge (spawned, DEVICE_INFO_TYPE_POLICY);
+
+ hal_util_callout_device_add (spawned, spawned_device_callouts_add_done, NULL, NULL);
+ }
+
+ } else if (pc->curelem == CURELEM_CLEAR && pc->match_ok) {
+ if (pc->merge_type == MERGE_TYPE_CLEAR) {
+ hal_device_property_strlist_clear (pc->device, pc->merge_key);
+ }
+ }
+
+
+ pc->cdata_buf_len = 0;
+ pc->depth--;
+
+ /* maintain curelem */
+ pc->curelem = pc->curelem_stack[pc->depth];
+
+ /* maintain pc->match_ok */
+ if (pc->depth <= pc->match_depth_first_fail)
+ pc->match_ok = TRUE;
+}
+
+/** Called when there is CDATA
+ *
+ * @param pc Parsing context
+ * @param s Pointer to data
+ * @param len Length of data
+ */
+static void
+cdata (ParsingContext * pc, const char *s, int len)
+{
+ int bytes_left;
+ int bytes_to_copy;
+
+ if (pc->aborted)
+ return;
+
+ bytes_left = CDATA_BUF_SIZE - pc->cdata_buf_len;
+ if (len > bytes_left) {
+ HAL_ERROR (("CDATA in element larger than %d",
+ CDATA_BUF_SIZE));
+ }
+
+ bytes_to_copy = len;
+ if (bytes_to_copy > bytes_left)
+ bytes_to_copy = bytes_left;
+
+ if (bytes_to_copy > 0)
+ memcpy (pc->cdata_buf + pc->cdata_buf_len, s,
+ bytes_to_copy);
+
+ pc->cdata_buf_len += bytes_to_copy;
+}
+
+
+/** Process a device information info file.
+ *
+ * @param dir Directory file resides in
+ * @param filename File name
+ * @param device Device to match on
+ * @return #TRUE if file matched device and information
+ * was merged
+ */
+static dbus_bool_t
+process_fdi_file (const char *dir, const char *filename,
+ HalDevice * device)
+{
+ int rc;
+ char buf[512];
+ FILE *file;
+ int filesize;
+ size_t read;
+ char *filebuf;
+ dbus_bool_t device_matched;
+ XML_Parser parser;
+ ParsingContext *parsing_context;
+
+ file = NULL;
+ filebuf = NULL;
+ parser = NULL;
+ parsing_context = NULL;
+
+ device_matched = FALSE;
+
+ snprintf (buf, sizeof (buf), "%s/%s", dir, filename);
+
+ /*HAL_INFO(("analyzing file %s", buf));*/
+
+ /* open file and read it into a buffer; it's a small file... */
+ file = fopen (buf, "r");
+ if (file == NULL) {
+ HAL_ERROR (("Could not open file %s", buf));
+ goto out;
+ }
+
+ fseek (file, 0L, SEEK_END);
+ filesize = (int) ftell (file);
+ rewind (file);
+ filebuf = (char *) malloc (filesize);
+ if (filebuf == NULL) {
+ HAL_ERROR (("Could not allocate %d bytes for file %s", filesize, buf));
+ goto out;
+ }
+ read = fread (filebuf, sizeof (char), filesize, file);
+
+ /* initialize parsing context */
+ parsing_context =
+ (ParsingContext *) malloc (sizeof (ParsingContext));
+ if (parsing_context == NULL) {
+ HAL_ERROR (("Could not allocate parsing context"));
+ goto out;
+ }
+
+ /* TODO: reuse parser
+ */
+ parser = XML_ParserCreate (NULL);
+ if (parser == NULL) {
+ HAL_ERROR (("Could not allocate XML parser"));
+ goto out;
+ }
+
+ parsing_context->depth = 0;
+ parsing_context->device_matched = FALSE;
+ parsing_context->match_ok = TRUE;
+ parsing_context->curelem = CURELEM_UNKNOWN;
+ parsing_context->aborted = FALSE;
+ parsing_context->file = buf;
+ parsing_context->parser = parser;
+ parsing_context->device = device;
+ parsing_context->match_depth_first_fail = -1;
+
+ XML_SetElementHandler (parser,
+ (XML_StartElementHandler) start,
+ (XML_EndElementHandler) end);
+ XML_SetCharacterDataHandler (parser,
+ (XML_CharacterDataHandler) cdata);
+ XML_SetUserData (parser, parsing_context);
+
+ rc = XML_Parse (parser, filebuf, filesize, 1);
+ /*printf("XML_Parse rc=%d\r\n", rc); */
+
+ if (rc == 0) {
+ /* error parsing document */
+ HAL_ERROR (("Error parsing XML document %s at line %d, "
+ "column %d : %s",
+ buf,
+ XML_GetCurrentLineNumber (parser),
+ XML_GetCurrentColumnNumber (parser),
+ XML_ErrorString (XML_GetErrorCode (parser))));
+ device_matched = FALSE;
+ } else {
+ /* document parsed ok */
+ device_matched = parsing_context->device_matched;
+ }
+
+out:
+ if (filebuf != NULL)
+ free (filebuf);
+ if (file != NULL)
+ fclose (file);
+ if (parser != NULL)
+ XML_ParserFree (parser);
+ if (parsing_context != NULL)
+ free (parsing_context);
+
+ return device_matched;
+}
+
+
+
+static int
+#ifdef __GLIBC__
+my_alphasort(const void *a, const void *b)
+#else
+my_alphasort(const struct dirent **a, const struct dirent **b)
+#endif
+{
+ return -alphasort (a, b);
+}
+
+
+/** Scan all directories and subdirectories in the given directory and
+ * process each *.fdi file
+ *
+ * @param d Device to merge information into
+ * @return #TRUE if information was merged
+ */
+static dbus_bool_t
+scan_fdi_files (const char *dir, HalDevice * d)
+{
+ int i;
+ int num_entries;
+ dbus_bool_t found_fdi_file;
+ struct dirent **name_list;
+
+ found_fdi_file = 0;
+
+ /*HAL_INFO(("scan_fdi_files: Processing dir '%s'", dir));*/
+
+ num_entries = scandir (dir, &name_list, 0, my_alphasort);
+ if (num_entries == -1) {
+ return FALSE;
+ }
+
+ for (i = num_entries - 1; i >= 0; i--) {
+ int len;
+ char *filename;
+ gchar *full_path;
+
+ filename = name_list[i]->d_name;
+ len = strlen (filename);
+
+ full_path = g_strdup_printf ("%s/%s", dir, filename);
+ /*HAL_INFO (("Full path = %s", full_path));*/
+
+ /* Mmm, d_type can be DT_UNKNOWN, use glib to determine
+ * the type
+ */
+ if (g_file_test (full_path, (G_FILE_TEST_IS_REGULAR))) {
+ /* regular file */
+
+ if (len >= 5 &&
+ filename[len - 4] == '.' &&
+ filename[len - 3] == 'f' &&
+ filename[len - 2] == 'd' &&
+ filename[len - 1] == 'i') {
+ /*HAL_INFO (("scan_fdi_files: Processing file '%s'", filename));*/
+ found_fdi_file = process_fdi_file (dir, filename, d);
+ if (found_fdi_file) {
+ HAL_INFO (("*** Matched file %s/%s", dir, filename));
+ /*break;*/
+ }
+ }
+
+ } else if (g_file_test (full_path, (G_FILE_TEST_IS_DIR))
+ && strcmp (filename, ".") != 0
+ && strcmp (filename, "..") != 0) {
+ int num_bytes;
+ char *dirname;
+
+ /* Directory; do the recursion thingy but not
+ * for . and ..
+ */
+
+ num_bytes = len + strlen (dir) + 1 + 1;
+ dirname = (char *) malloc (num_bytes);
+ if (dirname == NULL) {
+ HAL_ERROR (("couldn't allocated %d bytes",
+ num_bytes));
+ break;
+ }
+
+ snprintf (dirname, num_bytes, "%s/%s", dir,
+ filename);
+ found_fdi_file = scan_fdi_files (dirname, d);
+ free (dirname);
+ /*
+ if (found_fdi_file)
+ break;
+ */
+ }
+
+ g_free (full_path);
+
+ free (name_list[i]);
+ }
+
+ for (; i >= 0; i--) {
+ free (name_list[i]);
+ }
+
+ free (name_list);
+
+ return found_fdi_file;
+}
+
+/** Search the device info file repository for a .fdi file to merge
+ * more information into the device object.
+ *
+ * @param d Device to merge information into
+ * @return #TRUE if information was merged
+ */
+dbus_bool_t
+di_search_and_merge (HalDevice *d, DeviceInfoType type)
+{
+ static gboolean have_checked_hal_fdi_source = FALSE;
+ static char *hal_fdi_source_preprobe = NULL;
+ static char *hal_fdi_source_information = NULL;
+ static char *hal_fdi_source_policy = NULL;
+ dbus_bool_t ret;
+ char *s1;
+ char *s2;
+
+ ret = FALSE;
+
+ if (!have_checked_hal_fdi_source) {
+ hal_fdi_source_preprobe = getenv ("HAL_FDI_SOURCE_PREPROBE");
+ hal_fdi_source_information = getenv ("HAL_FDI_SOURCE_INFORMATION");
+ hal_fdi_source_policy = getenv ("HAL_FDI_SOURCE_POLICY");
+ have_checked_hal_fdi_source = TRUE;
+ }
+
+ switch (type) {
+ case DEVICE_INFO_TYPE_PREPROBE:
+ if (hal_fdi_source_preprobe != NULL) {
+ s1 = hal_fdi_source_preprobe;
+ s2 = NULL;
+ } else {
+ s1 = PACKAGE_DATA_DIR "/hal/fdi/preprobe";
+ s2 = PACKAGE_SYSCONF_DIR "/hal/fdi/preprobe";
+ }
+ break;
+
+ case DEVICE_INFO_TYPE_INFORMATION:
+ if (hal_fdi_source_information != NULL) {
+ s1 = hal_fdi_source_information;
+ s2 = NULL;
+ } else {
+ s1 = PACKAGE_DATA_DIR "/hal/fdi/information";
+ s2 = PACKAGE_SYSCONF_DIR "/hal/fdi/information";
+ }
+ break;
+
+ case DEVICE_INFO_TYPE_POLICY:
+ if (hal_fdi_source_policy != NULL) {
+ s1 = hal_fdi_source_policy;
+ s2 = NULL;
+ } else {
+ s1 = PACKAGE_DATA_DIR "/hal/fdi/policy";
+ s2 = PACKAGE_SYSCONF_DIR "/hal/fdi/policy";
+ }
+ break;
+
+ default:
+ s1 = NULL;
+ s2 = NULL;
+ HAL_ERROR (("Bogus device information type %d", type));
+ break;
+ }
+
+ if (s1 != NULL)
+ ret = scan_fdi_files (s1, d) || ret;
+ if (s2 != NULL)
+ ret = scan_fdi_files (s2, d) || ret;
+
+ return ret;
+}
+
+/** @} */
diff --git a/usr/src/cmd/hal/hald/device_info.h b/usr/src/cmd/hal/hald/device_info.h
new file mode 100644
index 0000000000..e37973f86a
--- /dev/null
+++ b/usr/src/cmd/hal/hald/device_info.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device_store.c : Search for .fdi files and merge on match
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef DEVICE_INFO_H
+#define DEVICE_INFO_H
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <dbus/dbus.h>
+
+#include "device_store.h"
+
+typedef enum {
+ DEVICE_INFO_TYPE_PREPROBE,
+ DEVICE_INFO_TYPE_INFORMATION,
+ DEVICE_INFO_TYPE_POLICY
+} DeviceInfoType;
+
+dbus_bool_t di_search_and_merge (HalDevice *d, DeviceInfoType type);
+
+#endif /* DEVICE_INFO_H */
diff --git a/usr/src/cmd/hal/hald/device_store.c b/usr/src/cmd/hal/hald/device_store.c
new file mode 100644
index 0000000000..d11cf6ed1b
--- /dev/null
+++ b/usr/src/cmd/hal/hald/device_store.c
@@ -0,0 +1,493 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device_store.c : HalDeviceStore methods
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2004 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "device_store.h"
+#include "hald_marshal.h"
+#include "logger.h"
+
+static GObjectClass *parent_class;
+
+enum {
+ STORE_CHANGED,
+ DEVICE_PROPERTY_CHANGED,
+ DEVICE_CAPABILITY_ADDED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+hal_device_store_finalize (GObject *obj)
+{
+ HalDeviceStore *store = HAL_DEVICE_STORE (obj);
+
+ g_slist_foreach (store->devices, (GFunc) g_object_unref, NULL);
+
+ if (parent_class->finalize)
+ parent_class->finalize (obj);
+}
+
+static void
+hal_device_store_class_init (HalDeviceStoreClass *klass)
+{
+ GObjectClass *obj_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ obj_class->finalize = hal_device_store_finalize;
+
+ signals[STORE_CHANGED] =
+ g_signal_new ("store_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceStoreClass,
+ store_changed),
+ NULL, NULL,
+ hald_marshal_VOID__OBJECT_BOOL,
+ G_TYPE_NONE, 2,
+ G_TYPE_OBJECT,
+ G_TYPE_BOOLEAN);
+
+ signals[DEVICE_PROPERTY_CHANGED] =
+ g_signal_new ("device_property_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceStoreClass,
+ device_property_changed),
+ NULL, NULL,
+ hald_marshal_VOID__OBJECT_STRING_BOOL_BOOL,
+ G_TYPE_NONE, 4,
+ G_TYPE_OBJECT,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+
+ signals[DEVICE_CAPABILITY_ADDED] =
+ g_signal_new ("device_capability_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HalDeviceStoreClass,
+ device_capability_added),
+ NULL, NULL,
+ hald_marshal_VOID__OBJECT_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_OBJECT,
+ G_TYPE_STRING);
+}
+
+static void
+hal_device_store_init (HalDeviceStore *device)
+{
+}
+
+GType
+hal_device_store_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo type_info = {
+ sizeof (HalDeviceStoreClass),
+ NULL, NULL,
+ (GClassInitFunc) hal_device_store_class_init,
+ NULL, NULL,
+ sizeof (HalDeviceStore),
+ 0,
+ (GInstanceInitFunc) hal_device_store_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "HalDeviceStore",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+HalDeviceStore *
+hal_device_store_new (void)
+{
+ HalDeviceStore *store;
+
+ store = g_object_new (HAL_TYPE_DEVICE_STORE, NULL, NULL);
+
+ return store;
+}
+
+static void
+emit_device_property_changed (HalDevice *device,
+ const char *key,
+ gboolean added,
+ gboolean removed,
+ gpointer data)
+{
+ HalDeviceStore *store = HAL_DEVICE_STORE (data);
+
+ g_signal_emit (store, signals[DEVICE_PROPERTY_CHANGED], 0,
+ device, key, added, removed);
+}
+
+static void
+emit_device_capability_added (HalDevice *device,
+ const char *capability,
+ gpointer data)
+{
+ HalDeviceStore *store = HAL_DEVICE_STORE (data);
+
+ g_signal_emit (store, signals[DEVICE_CAPABILITY_ADDED], 0,
+ device, capability);
+}
+
+void
+hal_device_store_add (HalDeviceStore *store, HalDevice *device)
+{
+ const char buf[] = "/org/freedesktop/Hal/devices/";
+
+ if (strncmp(device->udi, buf, sizeof (buf) - 1) != 0) {
+
+ HAL_ERROR(("Can't add HalDevice with incorrect UDI. Valid "
+ "UDI must start with '/org/freedesktop/Hal/devices/'"));
+ goto out;
+ }
+ store->devices = g_slist_prepend (store->devices,
+ g_object_ref (device));
+
+ g_signal_connect (device, "property_changed",
+ G_CALLBACK (emit_device_property_changed), store);
+ g_signal_connect (device, "capability_added",
+ G_CALLBACK (emit_device_capability_added), store);
+
+ g_signal_emit (store, signals[STORE_CHANGED], 0, device, TRUE);
+
+out:
+ ;
+}
+
+gboolean
+hal_device_store_remove (HalDeviceStore *store, HalDevice *device)
+{
+ if (!g_slist_find (store->devices, device))
+ return FALSE;
+
+ store->devices = g_slist_remove (store->devices, device);
+
+ g_signal_handlers_disconnect_by_func (device,
+ (gpointer)emit_device_property_changed,
+ store);
+ g_signal_handlers_disconnect_by_func (device,
+ (gpointer)emit_device_capability_added,
+ store);
+
+ g_signal_emit (store, signals[STORE_CHANGED], 0, device, FALSE);
+
+ g_object_unref (device);
+
+ return TRUE;
+}
+
+HalDevice *
+hal_device_store_find (HalDeviceStore *store, const char *udi)
+{
+ GSList *iter;
+
+ for (iter = store->devices; iter != NULL; iter = iter->next) {
+ HalDevice *d = iter->data;
+
+ if (strcmp (hal_device_get_udi (d), udi) == 0)
+ return d;
+ }
+
+ return NULL;
+}
+
+void
+hal_device_store_foreach (HalDeviceStore *store,
+ HalDeviceStoreForeachFn callback,
+ gpointer user_data)
+{
+ GSList *iter;
+
+ g_return_if_fail (store != NULL);
+ g_return_if_fail (callback != NULL);
+
+ for (iter = store->devices; iter != NULL; iter = iter->next) {
+ HalDevice *d = HAL_DEVICE (iter->data);
+ gboolean cont;
+
+ cont = callback (store, d, user_data);
+
+ if (cont == FALSE)
+ return;
+ }
+}
+
+static gboolean
+hal_device_store_print_foreach_fn (HalDeviceStore *store,
+ HalDevice *device,
+ gpointer user_data)
+{
+ fprintf (stderr, "----\n");
+ hal_device_print (device);
+ fprintf (stderr, "----\n");
+ return TRUE;
+}
+
+void
+hal_device_store_print (HalDeviceStore *store)
+{
+ fprintf (stderr, "===============================================\n");
+ fprintf (stderr, "Dumping %d devices\n",
+ g_slist_length (store->devices));
+ fprintf (stderr, "===============================================\n");
+ hal_device_store_foreach (store,
+ hal_device_store_print_foreach_fn,
+ NULL);
+ fprintf (stderr, "===============================================\n");
+}
+
+HalDevice *
+hal_device_store_match_key_value_string (HalDeviceStore *store,
+ const char *key,
+ const char *value)
+{
+ GSList *iter;
+
+ g_return_val_if_fail (store != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+
+ for (iter = store->devices; iter != NULL; iter = iter->next) {
+ HalDevice *d = HAL_DEVICE (iter->data);
+ int type;
+
+ if (!hal_device_has_property (d, key))
+ continue;
+
+ type = hal_device_property_get_type (d, key);
+ if (type != HAL_PROPERTY_TYPE_STRING)
+ continue;
+
+ if (strcmp (hal_device_property_get_string (d, key),
+ value) == 0)
+ return d;
+ }
+
+ return NULL;
+}
+
+HalDevice *
+hal_device_store_match_key_value_int (HalDeviceStore *store,
+ const char *key,
+ int value)
+{
+ GSList *iter;
+
+ g_return_val_if_fail (store != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ for (iter = store->devices; iter != NULL; iter = iter->next) {
+ HalDevice *d = HAL_DEVICE (iter->data);
+ int type;
+
+ if (!hal_device_has_property (d, key))
+ continue;
+
+ type = hal_device_property_get_type (d, key);
+ if (type != HAL_PROPERTY_TYPE_INT32)
+ continue;
+
+ if (hal_device_property_get_int (d, key) == value)
+ return d;
+ }
+
+ return NULL;
+}
+
+GSList *
+hal_device_store_match_multiple_key_value_string (HalDeviceStore *store,
+ const char *key,
+ const char *value)
+{
+ GSList *iter;
+ GSList *matches = NULL;
+
+ g_return_val_if_fail (store != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+
+ for (iter = store->devices; iter != NULL; iter = iter->next) {
+ HalDevice *d = HAL_DEVICE (iter->data);
+ int type;
+
+ if (!hal_device_has_property (d, key))
+ continue;
+
+ type = hal_device_property_get_type (d, key);
+ if (type != HAL_PROPERTY_TYPE_STRING)
+ continue;
+
+ if (strcmp (hal_device_property_get_string (d, key),
+ value) == 0)
+ matches = g_slist_prepend (matches, d);
+ }
+
+ return matches;
+}
+
+typedef struct {
+ HalDeviceStore *store;
+ char *key;
+ char *value;
+ HalDeviceStoreAsyncCallback callback;
+ gpointer user_data;
+
+ guint prop_signal_id;
+ guint store_signal_id;
+ guint timeout_id;
+} AsyncMatchInfo;
+
+static void
+destroy_async_match_info (AsyncMatchInfo *info)
+{
+ g_object_unref (info->store);
+
+ g_free (info->key);
+ g_free (info->value);
+
+ g_signal_handler_disconnect (info->store, info->prop_signal_id);
+ g_signal_handler_disconnect (info->store, info->store_signal_id);
+ g_source_remove (info->timeout_id);
+
+ g_free (info);
+}
+
+static void
+match_device_async (HalDeviceStore *store, HalDevice *device,
+ const char *key, gboolean removed, gboolean added,
+ gpointer user_data)
+{
+ AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
+
+ /* Only want to do it for added or changed properties */
+ if (removed)
+ return;
+
+ /* Keys have to match */
+ if (strcmp (info->key, key) != 0)
+ return;
+
+ /* Values have to match */
+ if (strcmp (hal_device_property_get_string (device, key),
+ info->value) != 0)
+ return;
+
+ info->callback (store, device, info->user_data);
+
+ destroy_async_match_info (info);
+}
+
+static void
+store_changed (HalDeviceStore *store, HalDevice *device,
+ gboolean added, gpointer user_data)
+{
+ AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
+
+ if (!added)
+ return;
+
+ if (!hal_device_has_property (device, info->key))
+ return;
+
+ if (strcmp (hal_device_property_get_string (device, info->key),
+ info->value) != 0)
+ return;
+
+ info->callback (store, device, info->user_data);
+
+ destroy_async_match_info (info);
+}
+
+static gboolean
+match_device_async_timeout (gpointer user_data)
+{
+ AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
+
+ info->callback (info->store, NULL, info->user_data);
+
+ destroy_async_match_info (info);
+
+ return FALSE;
+}
+
+void
+hal_device_store_match_key_value_string_async (HalDeviceStore *store,
+ const char *key,
+ const char *value,
+ HalDeviceStoreAsyncCallback callback,
+ gpointer user_data,
+ int timeout)
+{
+ HalDevice *device;
+ AsyncMatchInfo *info;
+
+ /* First check to see if it's already there */
+ device = hal_device_store_match_key_value_string (store, key, value);
+
+ if (device != NULL || timeout == 0) {
+ callback (store, device, user_data);
+
+ return;
+ }
+
+ info = g_new0 (AsyncMatchInfo, 1);
+
+ info->store = g_object_ref (store);
+ info->key = g_strdup (key);
+ info->value = g_strdup (value);
+ info->callback = callback;
+ info->user_data = user_data;
+
+ info->prop_signal_id = g_signal_connect (store,
+ "device_property_changed",
+ G_CALLBACK (match_device_async),
+ info);
+ info->store_signal_id = g_signal_connect (store,
+ "store_changed",
+ G_CALLBACK (store_changed),
+ info);
+
+ info->timeout_id = g_timeout_add (timeout,
+ match_device_async_timeout,
+ info);
+}
diff --git a/usr/src/cmd/hal/hald/device_store.h b/usr/src/cmd/hal/hald/device_store.h
new file mode 100644
index 0000000000..6a03ea8cef
--- /dev/null
+++ b/usr/src/cmd/hal/hald/device_store.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device.c : HalDevice methods
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2004 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef DEVICE_STORE_H
+#define DEVICE_STORE_H
+
+#include <glib-object.h>
+
+#include "device.h"
+
+typedef struct _HalDeviceStore HalDeviceStore;
+typedef struct _HalDeviceStoreClass HalDeviceStoreClass;
+
+struct _HalDeviceStore {
+ GObject parent;
+
+ GSList *devices;
+};
+
+struct _HalDeviceStoreClass {
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*store_changed) (HalDeviceStore *store,
+ HalDevice *device,
+ gboolean added);
+
+ void (*device_property_changed) (HalDeviceStore *store,
+ HalDevice *device,
+ const char *key,
+ gboolean removed,
+ gboolean added);
+
+ void (*device_capability_added) (HalDeviceStore *store,
+ HalDevice *device,
+ const char *capability);
+
+};
+
+#define HAL_TYPE_DEVICE_STORE (hal_device_store_get_type ())
+#define HAL_DEVICE_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+ HAL_TYPE_DEVICE_STORE, \
+ HalDeviceStore))
+#define HAL_DEVICE_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ HAL_TYPE_DEVICE_STORE, \
+ HalDeviceStoreClass))
+#define HAL_IS_DEVICE_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ HAL_TYPE_DEVICE_STORE))
+#define HAL_IS_DEVICE_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ HAL_TYPE_DEVICE_STORE))
+
+typedef void (*HalDeviceStoreAsyncCallback) (HalDeviceStore *store,
+ HalDevice *device,
+ gpointer user_data);
+
+/* Return value of FALSE means that the foreach should be short-circuited */
+typedef gboolean (*HalDeviceStoreForeachFn) (HalDeviceStore *store,
+ HalDevice *device,
+ gpointer user_data);
+
+GType hal_device_store_get_type (void);
+
+HalDeviceStore *hal_device_store_new (void);
+
+void hal_device_store_add (HalDeviceStore *store,
+ HalDevice *device);
+gboolean hal_device_store_remove (HalDeviceStore *store,
+ HalDevice *device);
+
+HalDevice *hal_device_store_find (HalDeviceStore *store,
+ const char *udi);
+
+void hal_device_store_foreach (HalDeviceStore *store,
+ HalDeviceStoreForeachFn callback,
+ gpointer user_data);
+
+HalDevice *hal_device_store_match_key_value_string (HalDeviceStore *store,
+ const char *key,
+ const char *value);
+
+HalDevice *hal_device_store_match_key_value_int (HalDeviceStore *store,
+ const char *key,
+ int value);
+
+GSList *hal_device_store_match_multiple_key_value_string (HalDeviceStore *store,
+ const char *key,
+ const char *value);
+
+void hal_device_store_match_key_value_string_async (HalDeviceStore *store,
+ const char *key,
+ const char *value,
+ HalDeviceStoreAsyncCallback callback,
+ gpointer user_data,
+ int timeout);
+
+void hal_device_store_print (HalDeviceStore *store);
+
+
+#endif /* DEVICE_STORE_H */
diff --git a/usr/src/cmd/hal/hald/hald.c b/usr/src/cmd/hal/hald/hald.c
new file mode 100644
index 0000000000..02ae7a09cf
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald.c
@@ -0,0 +1,641 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hald.c : main startup for HAL daemon
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2005 Danny Kukawka, <danny.kukawka@web.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <pwd.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <grp.h>
+#include <syslog.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+/*#include "master_slave.h"*/
+
+#include "logger.h"
+#include "hald.h"
+#include "device_store.h"
+#include "device_info.h"
+#include "osspec.h"
+#include "hald_dbus.h"
+#include "util.h"
+#include "hald_runner.h"
+#include "util_helper.h"
+
+static void delete_pid(void)
+{
+ unlink(HALD_PID_FILE);
+}
+
+/**
+ * @defgroup HalDaemon HAL daemon
+ * @brief The HAL daemon manages persistent device objects available through
+ * a D-BUS network API
+ */
+
+static HalDeviceStore *global_device_list = NULL;
+
+static HalDeviceStore *temporary_device_list = NULL;
+
+
+static void
+addon_terminated (HalDevice *device, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ HAL_INFO (("in addon_terminated for udi=%s", device->udi));
+
+ /* TODO: log to syslog - addons shouldn't just terminate, this is a bug with the addon */
+
+ /* however, the world can stop, mark this addon as ready
+ * (TODO: potential bug if the addon crashed after calling libhal_device_addon_is_ready())
+ */
+ if (hal_device_inc_num_ready_addons (device)) {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_added (device);
+ }
+ }
+}
+
+
+
+
+static void
+gdl_store_changed (HalDeviceStore *store, HalDevice *device,
+ gboolean is_added, gpointer user_data)
+{
+ if (is_added) {
+ GSList *addons;
+
+ HAL_INFO (("Added device to GDL; udi=%s", hal_device_get_udi(device)));
+
+ if ((addons = hal_device_property_get_strlist (device, "info.addons")) != NULL) {
+ GSList *i;
+
+ for (i = addons; i != NULL; i = g_slist_next (i)) {
+ const gchar *command_line;
+ gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
+
+ command_line = (const gchar *) i->data;
+ if (hald_runner_start(device, command_line, extra_env, addon_terminated, NULL, NULL)) {
+ HAL_INFO (("Started addon %s for udi %s",
+ command_line, hal_device_get_udi(device)));
+ hal_device_inc_num_addons (device);
+ } else {
+ HAL_ERROR (("Cannot start addon %s for udi %s",
+ command_line, hal_device_get_udi(device)));
+ }
+ }
+ }
+ } else {
+ HAL_INFO (("Removed device from GDL; udi=%s", hal_device_get_udi(device)));
+ hald_runner_kill_device(device);
+ }
+
+ /*hal_device_print (device);*/
+
+ if (is_added) {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_added (device);
+ }
+ } else {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_removed (device);
+ }
+ }
+}
+
+static void
+gdl_property_changed (HalDeviceStore *store, HalDevice *device,
+ const char *key, gboolean added, gboolean removed,
+ gpointer user_data)
+{
+ if (hal_device_are_all_addons_ready (device)) {
+ device_send_signal_property_modified (device, key, removed, added);
+ }
+
+ /* only execute the callouts if the property _changed_ */
+ if (added == FALSE && removed == FALSE)
+ /*hal_callout_property (device, key)*/;
+}
+
+static void
+gdl_capability_added (HalDeviceStore *store, HalDevice *device,
+ const char *capability, gpointer user_data)
+{
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_new_capability (device, capability);
+ }
+ /*hal_callout_capability (device, capability, TRUE)*/;
+}
+
+HalDeviceStore *
+hald_get_gdl (void)
+{
+ if (global_device_list == NULL) {
+ global_device_list = hal_device_store_new ();
+
+ g_signal_connect (global_device_list,
+ "store_changed",
+ G_CALLBACK (gdl_store_changed), NULL);
+ g_signal_connect (global_device_list,
+ "device_property_changed",
+ G_CALLBACK (gdl_property_changed), NULL);
+ g_signal_connect (global_device_list,
+ "device_capability_added",
+ G_CALLBACK (gdl_capability_added), NULL);
+ }
+
+ return global_device_list;
+}
+
+HalDeviceStore *
+hald_get_tdl (void)
+{
+ if (temporary_device_list == NULL) {
+ temporary_device_list = hal_device_store_new ();
+
+ }
+
+ return temporary_device_list;
+}
+
+/**
+ * @defgroup MainDaemon Basic functions
+ * @ingroup HalDaemon
+ * @brief Basic functions in the HAL daemon
+ * @{
+ */
+
+/** Print out program usage.
+ *
+ */
+static void
+usage ()
+{
+ fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--verbose=yes|no] [--help]\n");
+ fprintf (stderr,
+ "\n"
+ " --daemon=yes|no Become a daemon\n"
+ " --verbose=yes|no Print out debug (overrides HALD_VERBOSE)\n"
+ " --use-syslog Print out debug messages to syslog instead of stderr.\n"
+ " Use this option to get debug messages if HAL runs as\n"
+ " daemon.\n"
+ " --help Show this information and exit\n"
+ " --version Output version information and exit"
+ "\n"
+ "The HAL daemon detects devices present in the system and provides the\n"
+ "org.freedesktop.Hal service through the system-wide message bus provided\n"
+ "by D-BUS.\n"
+ "\n"
+ "For more information visit http://freedesktop.org/Software/hal\n"
+ "\n");
+}
+
+/** If #TRUE, we will daemonize */
+static dbus_bool_t opt_become_daemon = TRUE;
+
+/** If #TRUE, we will spew out debug */
+dbus_bool_t hald_is_verbose = FALSE;
+dbus_bool_t hald_use_syslog = FALSE;
+
+static int sigterm_unix_signal_pipe_fds[2];
+static GIOChannel *sigterm_iochn;
+
+static void
+handle_sigterm (int value)
+{
+ ssize_t written;
+ static char marker[1] = {'S'};
+
+ /* write a 'S' character to the other end to tell about
+ * the signal. Note that 'the other end' is a GIOChannel thingy
+ * that is only called from the mainloop - thus this is how we
+ * defer this since UNIX signal handlers are evil
+ *
+ * Oh, and write(2) is indeed reentrant */
+ written = write (sigterm_unix_signal_pipe_fds[1], marker, 1);
+}
+
+static gboolean
+sigterm_iochn_data (GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ GError *err = NULL;
+ gchar data[1];
+ gsize bytes_read;
+
+ /* Empty the pipe */
+ if (G_IO_STATUS_NORMAL !=
+ g_io_channel_read_chars (source, data, 1, &bytes_read, &err)) {
+ HAL_ERROR (("Error emptying sigterm pipe: %s",
+ err->message));
+ g_error_free (err);
+ goto out;
+ }
+
+ HAL_INFO (("Caught SIGTERM, initiating shutdown"));
+ hald_runner_kill_all();
+ exit (0);
+
+out:
+ return TRUE;
+}
+
+
+/** This is set to #TRUE if we are probing and #FALSE otherwise */
+dbus_bool_t hald_is_initialising;
+
+static int startup_daemonize_pipe[2];
+
+
+/*--------------------------------------------------------------------------------------------------*/
+
+static gboolean child_died = FALSE;
+
+static void
+handle_sigchld (int value)
+{
+ child_died = TRUE;
+}
+
+static int
+parent_wait_for_child (int child_fd, pid_t child_pid)
+{
+ fd_set rfds;
+ fd_set efds;
+ struct timeval tv;
+ int retval;
+ int ret;
+
+ signal(SIGCHLD, handle_sigchld);
+
+ /* wait for either
+ *
+ * o Child writes something to the child_fd; means that device
+ * probing is completed and the parent should exit with success
+ *
+ * o Child is killed (segfault etc.); means that parent should exit
+ * with failure
+ *
+ * o Timeout; means that we should kill the child and exit with
+ * failure
+ *
+ */
+
+ FD_ZERO(&rfds);
+ FD_SET(child_fd, &rfds);
+ FD_ZERO(&efds);
+ FD_SET(child_fd, &efds);
+ /* Wait up to 250 seconds for device probing */
+ tv.tv_sec = 250;
+ tv.tv_usec = 0;
+
+ retval = select (child_fd + 1, &rfds, NULL, &efds, &tv);
+
+ if (child_died) {
+ /* written from handle_sigchld */
+ ret = 1;
+ goto out;
+ }
+
+ if (retval > 0) {
+ /* means child wrote to socket or closed it; all good */
+ ret = 0;
+ goto out;
+ }
+
+ /* assume timeout; kill child */
+ kill (child_pid, SIGTERM);
+ ret = 2;
+
+out:
+ return ret;
+}
+
+/*--------------------------------------------------------------------------------------------------*/
+
+/** Entry point for HAL daemon
+ *
+ * @param argc Number of arguments
+ * @param argv Array of arguments
+ * @return Exit code
+ */
+int
+main (int argc, char *argv[])
+{
+ GMainLoop *loop;
+ guint sigterm_iochn_listener_source_id;
+ char *path;
+ char newpath[512];
+
+ openlog ("hald", LOG_PID, LOG_DAEMON);
+
+ g_type_init ();
+
+ if (getenv ("HALD_VERBOSE"))
+ hald_is_verbose = TRUE;
+ else
+ hald_is_verbose = FALSE;
+
+ /* our helpers are installed into libexec, so adjust out $PATH
+ * to include this at the end (since we want to overide in
+ * run-hald.sh and friends)
+ */
+ path = getenv ("PATH");
+ if (path != NULL) {
+ g_strlcpy (newpath, path, sizeof (newpath));
+ g_strlcat (newpath, ":", sizeof (newpath));
+ } else {
+ /* No PATH was set */
+ newpath[0] = '\0';
+ }
+
+ g_strlcat (newpath, PACKAGE_LIBEXEC_DIR, sizeof (newpath));
+ g_strlcat (newpath, ":", sizeof (newpath));
+ g_strlcat (newpath, PACKAGE_SCRIPT_DIR, sizeof (newpath));
+
+ setenv ("PATH", newpath, TRUE);
+
+ while (1) {
+ int c;
+ int option_index = 0;
+ const char *opt;
+ static struct option long_options[] = {
+ {"daemon", 1, NULL, 0},
+ {"verbose", 1, NULL, 0},
+ {"use-syslog", 0, NULL, 0},
+ {"help", 0, NULL, 0},
+ {"version", 0, NULL, 0},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, "",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ opt = long_options[option_index].name;
+
+ if (strcmp (opt, "help") == 0) {
+ usage ();
+ return 0;
+ } else if (strcmp (opt, "version") == 0) {
+ fprintf (stderr, "HAL package version: " PACKAGE_VERSION "\n");
+ return 0;
+ } else if (strcmp (opt, "daemon") == 0) {
+ if (strcmp ("yes", optarg) == 0) {
+ opt_become_daemon = TRUE;
+ } else if (strcmp ("no", optarg) == 0) {
+ opt_become_daemon = FALSE;
+ } else {
+ usage ();
+ return 1;
+ }
+ } else if (strcmp (opt, "verbose") == 0) {
+ if (strcmp ("yes", optarg) == 0) {
+ hald_is_verbose = TRUE;
+ } else if (strcmp ("no", optarg) == 0) {
+ hald_is_verbose = FALSE;
+ } else {
+ usage ();
+ return 1;
+ }
+ } else if (strcmp (opt, "use-syslog") == 0) {
+ hald_use_syslog = TRUE;
+ }
+
+ break;
+
+ default:
+ usage ();
+ return 1;
+ break;
+ }
+ }
+
+ if (hald_is_verbose)
+ logger_enable ();
+ else
+ logger_disable ();
+
+ if (hald_use_syslog)
+ logger_enable_syslog ();
+ else
+ logger_disable_syslog ();
+
+ /* will fork into two; only the child will return here if we are successful */
+ /*master_slave_setup ();
+ sleep (100000000);*/
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ HAL_INFO ((PACKAGE_STRING));
+
+ if (opt_become_daemon) {
+ int child_pid;
+ int dev_null_fd;
+ int pf;
+ ssize_t written;
+ char pid[9];
+
+ HAL_INFO (("Will daemonize"));
+ HAL_INFO (("Becoming a daemon"));
+
+ if (pipe (startup_daemonize_pipe) != 0) {
+ fprintf (stderr, "Could not setup pipe: %s\n", strerror(errno));
+ exit (1);
+ }
+
+
+ if (chdir ("/") < 0) {
+ fprintf (stderr, "Could not chdir to /: %s\n", strerror(errno));
+ exit (1);
+ }
+
+ child_pid = fork ();
+ switch (child_pid) {
+ case -1:
+ fprintf (stderr, "Cannot fork(): %s\n", strerror(errno));
+ break;
+
+ case 0:
+ /* child */
+
+ dev_null_fd = open ("/dev/null", O_RDWR);
+ /* ignore if we can't open /dev/null */
+ if (dev_null_fd >= 0) {
+ /* attach /dev/null to stdout, stdin, stderr */
+ dup2 (dev_null_fd, 0);
+ dup2 (dev_null_fd, 1);
+ dup2 (dev_null_fd, 2);
+ close (dev_null_fd);
+ }
+
+ umask (022);
+ break;
+
+ default:
+ /* parent, block until child writes */
+ exit (parent_wait_for_child (startup_daemonize_pipe[0], child_pid));
+ break;
+ }
+
+ /* Create session */
+ setsid ();
+
+ /* remove old pid file */
+ unlink (HALD_PID_FILE);
+
+ /* Make a new one */
+ if ((pf= open (HALD_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) > 0) {
+ snprintf (pid, sizeof(pid), "%lu\n", (long unsigned) getpid ());
+ written = write (pf, pid, strlen(pid));
+ close (pf);
+ atexit (delete_pid);
+ }
+ } else {
+ HAL_INFO (("Will not daemonize"));
+ }
+
+
+ /* we need to do stuff when we are expected to terminate, thus
+ * this involves looking for SIGTERM; UNIX signal handlers are
+ * evil though, so set up a pipe to transmit the signal.
+ */
+
+ /* create pipe */
+ if (pipe (sigterm_unix_signal_pipe_fds) != 0) {
+ DIE (("Could not setup pipe, errno=%d", errno));
+ }
+
+ /* setup glib handler - 0 is for reading, 1 is for writing */
+ sigterm_iochn = g_io_channel_unix_new (sigterm_unix_signal_pipe_fds[0]);
+ if (sigterm_iochn == NULL)
+ DIE (("Could not create GIOChannel"));
+
+ /* get callback when there is data to read */
+ sigterm_iochn_listener_source_id = g_io_add_watch (
+ sigterm_iochn, G_IO_IN, sigterm_iochn_data, NULL);
+
+ /* Finally, setup unix signal handler for TERM */
+ signal (SIGTERM, handle_sigterm);
+
+ /* set up the local dbus server */
+ if (!hald_dbus_local_server_init ())
+ return 1;
+ /* Start the runner helper daemon */
+ if (!hald_runner_start_runner ()) {
+ return 1;
+ }
+
+ drop_privileges(0);
+
+ /* initialize operating system specific parts */
+ osspec_init ();
+
+ hald_is_initialising = TRUE;
+
+ /* detect devices */
+ osspec_probe ();
+
+ /* run the main loop and serve clients */
+ g_main_loop_run (loop);
+
+ return 0;
+}
+
+#ifdef HALD_MEMLEAK_DBG
+extern int dbg_hal_device_object_delta;
+
+/* useful for valgrinding; see below */
+static gboolean
+my_shutdown (gpointer data)
+{
+ HalDeviceStore *gdl;
+
+ printf ("Num devices in TDL: %d\n", g_slist_length ((hald_get_tdl ())->devices));
+ printf ("Num devices in GDL: %d\n", g_slist_length ((hald_get_gdl ())->devices));
+
+ gdl = hald_get_gdl ();
+next:
+ if (g_slist_length (gdl->devices) > 0) {
+ HalDevice *d = HAL_DEVICE(gdl->devices->data);
+ hal_device_store_remove (gdl, d);
+ g_object_unref (d);
+ goto next;
+ }
+
+ printf ("hal_device_object_delta = %d (should be zero)\n", dbg_hal_device_object_delta);
+ exit (1);
+}
+#endif
+
+void
+osspec_probe_done (void)
+{
+ ssize_t written;
+ char buf[1] = {0};
+
+ HAL_INFO (("Device probing completed"));
+
+ if (!hald_dbus_init ()) {
+ hald_runner_kill_all();
+ exit (1);
+ }
+
+ /* tell parent to exit */
+ written = write (startup_daemonize_pipe[1], buf, sizeof (buf));
+ close (startup_daemonize_pipe[0]);
+ close (startup_daemonize_pipe[1]);
+
+ hald_is_initialising = FALSE;
+
+#ifdef HALD_MEMLEAK_DBG
+ g_timeout_add ((HALD_MEMLEAK_DBG) * 1000,
+ my_shutdown,
+ NULL);
+#endif
+}
+
+
+/** @} */
diff --git a/usr/src/cmd/hal/hald/hald.h b/usr/src/cmd/hal/hald/hald.h
new file mode 100644
index 0000000000..b810947495
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * device_store.h : device store interface
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef HALD_H
+#define HALD_H
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <dbus/dbus.h>
+
+#include "device_store.h"
+
+/**
+ * @addtogroup HalDaemon
+ *
+ * @{
+ */
+
+HalDeviceStore *hald_get_gdl (void);
+HalDeviceStore *hald_get_tdl (void);
+
+void property_atomic_update_begin ();
+void property_atomic_update_end ();
+
+extern dbus_bool_t hald_is_verbose;
+extern dbus_bool_t hald_use_syslog;
+extern dbus_bool_t hald_is_initialising;
+extern dbus_bool_t hald_is_shutting_down;
+
+/* If this is defined, the amount of time, in seconds, before hald
+ * does an exit where resources are freed - useful for valgrinding
+ * and finding memory leaks; e.g. plug in a device, do something
+ * with the hal daemon and then look at the report
+ *
+ * Use hald/valgrind-hald.sh for this
+ */
+/*#define HALD_MEMLEAK_DBG 60*/
+
+/**
+ * @}
+ */
+
+#endif /* HALD_H */
diff --git a/usr/src/cmd/hal/hald/hald_dbus.c b/usr/src/cmd/hal/hald/hald_dbus.c
new file mode 100644
index 0000000000..379630f341
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald_dbus.c
@@ -0,0 +1,4383 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * dbus.c : D-BUS interface of HAL daemon
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <sys/time.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "hald.h"
+#include "hald_dbus.h"
+#include "device.h"
+#include "device_store.h"
+#include "device_info.h"
+#include "logger.h"
+#include "osspec.h"
+#include "util.h"
+#include "hald_runner.h"
+
+#define HALD_DBUS_ADDRESS "unix:tmpdir=" HALD_SOCKET_DIR
+
+static DBusConnection *dbus_connection = NULL;
+
+static void
+raise_error (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ const char *error_name,
+ char *format, ...) __attribute__((format (printf, 4, 5)));
+
+/**
+ * @defgroup DaemonErrors Error conditions
+ * @ingroup HalDaemon
+ * @brief Various error messages the HAL daemon can raise
+ * @{
+ */
+
+/** Raise HAL error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param error_name D-Bus error name
+ * @param format printf-style format for error message
+ */
+static void
+raise_error (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ const char *error_name,
+ char *format, ...)
+{
+ char buf[512];
+ DBusMessage *reply;
+
+ va_list args;
+ va_start(args, format);
+ vsnprintf(buf, sizeof buf, format, args);
+ va_end(args);
+
+ HAL_WARNING ((buf));
+ reply = dbus_message_new_error (in_reply_to, error_name, buf);
+ if (reply == NULL)
+ DIE (("No memory"));
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+ dbus_message_unref (reply);
+}
+
+/** Raise the org.freedesktop.Hal.NoSuchDevice error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param udi Unique device id given
+ */
+static void
+raise_no_such_device (DBusConnection *connection,
+ DBusMessage *in_reply_to, const char *udi)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.NoSuchDevice",
+ "No device with id %s",
+ udi
+ );
+}
+
+/** Raise the org.freedesktop.Hal.NoSuchProperty error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param device_id Id of the device
+ * @param key Key of the property that didn't exist
+ */
+static void
+raise_no_such_property (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ const char *device_id, const char *key)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.NoSuchProperty",
+ "No property %s on device with id %s",
+ key, device_id
+ );
+}
+
+/** Raise the org.freedesktop.Hal.TypeMismatch error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param device_id Id of the device
+ * @param key Key of the property
+ */
+static void
+raise_property_type_error (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ const char *device_id, const char *key)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.TypeMismatch",
+ "Type mismatch setting property %s on device with id %s",
+ key, device_id
+ );
+}
+
+/** Raise the org.freedesktop.Hal.SyntaxError error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param method_name Name of the method that was invoked with
+ * the wrong signature
+ */
+static void
+raise_syntax (DBusConnection *connection,
+ DBusMessage *in_reply_to, const char *method_name)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.SyntaxError",
+ "There is a syntax error in the invocation of the method %s",
+ method_name
+ );
+}
+
+/** Raise the org.freedesktop.Hal.DeviceNotLocked error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param device device which isn't locked
+ */
+static void
+raise_device_not_locked (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ HalDevice *device)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.DeviceNotLocked",
+ "The device %s is not locked",
+ hal_device_get_udi (device)
+ );
+}
+
+/** Raise the org.freedesktop.Hal.DeviceAlreadyLocked error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param device device which isn't locked
+ */
+static void
+raise_device_already_locked (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ HalDevice *device)
+{
+ DBusMessage *reply;
+ const char *reason;
+
+ reason = hal_device_property_get_string (device, "info.locked.reason");
+ HAL_WARNING (("Device %s is already locked: %s",
+ hal_device_get_udi (device), reason));
+
+
+ reply = dbus_message_new_error (in_reply_to,
+ "org.freedesktop.Hal.DeviceAlreadyLocked",
+ reason);
+
+ if (reply == NULL || !dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+}
+
+/** Raise the org.freedesktop.Hal.BranchAlreadyClaimed error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param udi branch which isn't claimed
+ */
+static void
+raise_branch_already_claimed (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ HalDevice *device)
+{
+ DBusMessage *reply;
+ const char *claim_service;
+
+ claim_service = hal_device_property_get_string (device, "info.claimed.service");
+ HAL_WARNING (("Branch %s is already claimed by: %s",
+ hal_device_get_udi (device), claim_service));
+
+
+ reply = dbus_message_new_error (in_reply_to,
+ "org.freedesktop.Hal.BranchAlreadyClaimed",
+ claim_service);
+
+ if (reply == NULL || !dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+}
+
+/** Raise the org.freedesktop.Hal.BranchNotClaimed error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param udi branch which isn't claimed
+ */
+static void
+raise_branch_not_claimed (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ HalDevice *device)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.BranchNotClaimed",
+ "The branch %s is not claimed",
+ hal_device_get_udi (device)
+ );
+}
+
+/** Raise the org.freedesktop.Hal.PermissionDenied error
+ *
+ * @param connection D-Bus connection
+ * @param in_reply_to message to report error on
+ * @param message what you're not allowed to do
+ */
+static void
+raise_permission_denied (DBusConnection *connection,
+ DBusMessage *in_reply_to,
+ const char *reason)
+{
+ raise_error (
+ connection, in_reply_to,
+ "org.freedesktop.Hal.PermissionDenied",
+ "Permission denied: %s",
+ reason
+ );
+}
+
+/** @} */
+
+/**
+ * @defgroup ManagerInterface D-BUS interface org.freedesktop.Hal.Manager
+ * @ingroup HalDaemon
+ * @brief D-BUS interface for querying device objects
+ *
+ * @{
+ */
+
+static gboolean
+foreach_device_get_udi (HalDeviceStore *store, HalDevice *device,
+ gpointer user_data)
+{
+ DBusMessageIter *iter = user_data;
+ const char *udi;
+
+ udi = hal_device_get_udi (device);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &udi);
+
+ return TRUE;
+}
+
+/** Get all devices.
+ *
+ * <pre>
+ * array{object_reference} Manager.GetAllDevices()
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+manager_get_all_devices (DBusConnection * connection,
+ DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_array);
+
+ hal_device_store_foreach (hald_get_gdl (),
+ foreach_device_get_udi,
+ &iter_array);
+
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+typedef struct {
+ const char *key;
+ const char *value;
+ DBusMessageIter *iter;
+} DeviceMatchInfo;
+
+static gboolean
+foreach_device_match_get_udi (HalDeviceStore *store, HalDevice *device,
+ gpointer user_data)
+{
+ DeviceMatchInfo *info = user_data;
+ const char *dev_value;
+
+ if (hal_device_property_get_type (device,
+ info->key) != DBUS_TYPE_STRING)
+ return TRUE;
+
+ dev_value = hal_device_property_get_string (device, info->key);
+
+ if (dev_value != NULL && strcmp (dev_value, info->value) == 0) {
+ const char *udi;
+ udi = hal_device_get_udi (device);
+ dbus_message_iter_append_basic (info->iter,
+ DBUS_TYPE_STRING,
+ &udi);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+foreach_device_match_get_udi_tdl (HalDeviceStore *store, HalDevice *device,
+ gpointer user_data)
+{
+ DeviceMatchInfo *info = user_data;
+ const char *dev_value;
+
+ /* skip devices in the TDL that hasn't got a real UDI yet */
+ if (strncmp (device->udi, "/org/freedesktop/Hal/devices/temp",
+ sizeof ("/org/freedesktop/Hal/devices/temp")) == 0)
+ return TRUE;
+
+ if (hal_device_property_get_type (device,
+ info->key) != DBUS_TYPE_STRING)
+ return TRUE;
+
+ dev_value = hal_device_property_get_string (device, info->key);
+
+ if (dev_value != NULL && strcmp (dev_value, info->value) == 0) {
+ const char *udi;
+ udi = hal_device_get_udi (device);
+
+ dbus_message_iter_append_basic (info->iter,
+ DBUS_TYPE_STRING,
+ &udi);
+ }
+
+ return TRUE;
+}
+
+/** Find devices in the GDL where a single string property matches a given
+ * value. Also returns devices in the TDL that has a non-tmp UDI.
+ *
+ * <pre>
+ * array{object_reference} Manager.FindDeviceStringMatch(string key,
+ * string value)
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+manager_find_device_string_match (DBusConnection * connection,
+ DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+ DBusError error;
+ const char *key;
+ const char *value;
+ DeviceMatchInfo info;
+
+ HAL_TRACE (("entering"));
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_STRING, &value,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message,
+ "Manager.FindDeviceStringMatch");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_array);
+
+ info.key = key;
+ info.value = value;
+ info.iter = &iter_array;
+
+ hal_device_store_foreach (hald_get_gdl (),
+ foreach_device_match_get_udi,
+ &info);
+
+ /* Also returns devices in the TDL that has a non-tmp UDI */
+ hal_device_store_foreach (hald_get_tdl (),
+ foreach_device_match_get_udi_tdl,
+ &info);
+
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+typedef struct {
+ const char *capability;
+ DBusMessageIter *iter;
+} DeviceCapabilityInfo;
+
+static gboolean
+foreach_device_by_capability (HalDeviceStore *store, HalDevice *device, gpointer user_data)
+{
+ DeviceCapabilityInfo *info = (DeviceCapabilityInfo *) user_data;
+
+ if (hal_device_has_capability (device, info->capability)) {
+ dbus_message_iter_append_basic (info->iter,
+ DBUS_TYPE_STRING,
+ &(device->udi));
+ }
+
+ return TRUE;
+}
+
+/** Find devices in the GDL with a given capability.
+ *
+ * <pre>
+ * array{object_reference} Manager.FindDeviceByCapability(string capability)
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+manager_find_device_by_capability (DBusConnection * connection,
+ DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+ DBusError error;
+ const char *capability;
+ DeviceCapabilityInfo info;
+
+ HAL_TRACE (("entering"));
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &capability,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message,
+ "Manager.FindDeviceByCapability");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_array);
+
+ info.capability = capability;
+ info.iter = &iter_array;
+
+ hal_device_store_foreach (hald_get_gdl (),
+ foreach_device_by_capability,
+ &info);
+
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/** Determine if a device exists.
+ *
+ * <pre>
+ * bool Manager.DeviceExists(string udi)
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+manager_device_exists (DBusConnection * connection, DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ const char *udi;
+ dbus_bool_t b;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "Manager.DeviceExists");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+ b = d != NULL;
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &b);
+
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/** Send signal DeviceAdded(string udi) on the org.freedesktop.Hal.Manager
+ * interface on the object /org/freedesktop/Hal/Manager.
+ *
+ * @param device The HalDevice added
+ */
+void
+manager_send_signal_device_added (HalDevice *device)
+{
+ const char *udi = hal_device_get_udi (device);
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+ if (dbus_connection == NULL)
+ goto out;
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ message = dbus_message_new_signal ("/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "DeviceAdded");
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+
+ if (!dbus_connection_send (dbus_connection, message, NULL))
+ DIE (("error broadcasting message"));
+
+ dbus_message_unref (message);
+
+out:
+ ;
+}
+
+/** Send signal DeviceRemoved(string udi) on the org.freedesktop.Hal.Manager
+ * interface on the object /org/freedesktop/Hal/Manager.
+ *
+ * @param device The HalDevice removed
+ */
+void
+manager_send_signal_device_removed (HalDevice *device)
+{
+ const char *udi = hal_device_get_udi (device);
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+ if (dbus_connection == NULL)
+ goto out;
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ message = dbus_message_new_signal ("/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "DeviceRemoved");
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+
+ if (!dbus_connection_send (dbus_connection, message, NULL))
+ DIE (("error broadcasting message"));
+
+ dbus_message_unref (message);
+out:
+ ;
+}
+
+/** Send signal NewCapability(string udi, string capability) on the
+ * org.freedesktop.Hal.Manager interface on the object
+ * /org/freedesktop/Hal/Manager.
+ *
+ * @param udi Unique Device Id
+ * @param capability Capability
+ */
+void
+manager_send_signal_new_capability (HalDevice *device,
+ const char *capability)
+{
+ const char *udi = hal_device_get_udi (device);
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+ if (dbus_connection == NULL)
+ goto out;
+
+ HAL_TRACE (("entering, udi=%s, cap=%s", udi, capability));
+
+ message = dbus_message_new_signal ("/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "NewCapability");
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
+
+ if (!dbus_connection_send (dbus_connection, message, NULL))
+ DIE (("error broadcasting message"));
+
+ dbus_message_unref (message);
+out:
+ ;
+}
+
+/** @} */
+
+/**
+ * @defgroup DeviceInterface D-BUS interface org.freedesktop.Hal.Device
+ * @ingroup HalDaemon
+ * @brief D-BUS interface for generic device operations
+ * @{
+ */
+
+static gboolean
+foreach_property_append (HalDevice *device, HalProperty *p,
+ gpointer user_data)
+{
+ DBusMessageIter *iter;
+ DBusMessageIter iter_dict_entry;
+ const char *key;
+ int type;
+
+ iter = (DBusMessageIter *)user_data;
+
+ dbus_message_iter_open_container (iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL,
+ &iter_dict_entry);
+
+ key = hal_property_get_key (p);
+ type = hal_property_get_type (p);
+
+ dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &key);
+
+ switch (type) {
+ case HAL_PROPERTY_TYPE_STRING:
+ {
+ DBusMessageIter iter_var;
+ const char *v;
+
+ v = hal_property_get_string (p);
+
+ dbus_message_iter_open_container (&iter_dict_entry,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_var);
+
+ dbus_message_iter_append_basic (&iter_var,
+ DBUS_TYPE_STRING,
+ &v);
+
+ dbus_message_iter_close_container (&iter_dict_entry,
+ &iter_var);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_INT32:
+ {
+ DBusMessageIter iter_var;
+ dbus_int32_t v;
+
+ v = hal_property_get_int (p);
+
+ dbus_message_iter_open_container (&iter_dict_entry,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_INT32_AS_STRING,
+ &iter_var);
+
+ dbus_message_iter_append_basic (&iter_var,
+ DBUS_TYPE_INT32,
+ &v);
+
+ dbus_message_iter_close_container (&iter_dict_entry,
+ &iter_var);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_UINT64:
+ {
+ DBusMessageIter iter_var;
+ dbus_uint64_t v;
+
+ v = hal_property_get_uint64 (p);
+
+ dbus_message_iter_open_container (&iter_dict_entry,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_UINT64_AS_STRING,
+ &iter_var);
+
+ dbus_message_iter_append_basic (&iter_var,
+ DBUS_TYPE_UINT64,
+ &v);
+
+ dbus_message_iter_close_container (&iter_dict_entry,
+ &iter_var);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ {
+ DBusMessageIter iter_var;
+ double v;
+
+ v = hal_property_get_double (p);
+
+ dbus_message_iter_open_container (&iter_dict_entry,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_DOUBLE_AS_STRING,
+ &iter_var);
+
+ dbus_message_iter_append_basic (&iter_var,
+ DBUS_TYPE_DOUBLE,
+ &v);
+
+ dbus_message_iter_close_container (&iter_dict_entry,
+ &iter_var);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ {
+ DBusMessageIter iter_var;
+ dbus_bool_t v;
+
+ v = hal_property_get_bool (p);
+
+ dbus_message_iter_open_container (&iter_dict_entry,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_BOOLEAN_AS_STRING,
+ &iter_var);
+
+ dbus_message_iter_append_basic (&iter_var,
+ DBUS_TYPE_BOOLEAN,
+ &v);
+
+ dbus_message_iter_close_container (&iter_dict_entry,
+ &iter_var);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_STRLIST:
+ {
+ DBusMessageIter iter_var, iter_array;
+ GSList *iter;
+
+ dbus_message_iter_open_container (&iter_dict_entry,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_var);
+
+ dbus_message_iter_open_container (&iter_var,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_array);
+
+ for (iter = hal_property_get_strlist (p); iter != NULL; iter = iter->next) {
+
+ const char *v;
+ v = (const char *) iter->data;
+
+ dbus_message_iter_append_basic (&iter_array,
+ DBUS_TYPE_STRING,
+ &v);
+ }
+
+ dbus_message_iter_close_container (&iter_var,
+ &iter_array);
+
+ dbus_message_iter_close_container (&iter_dict_entry,
+ &iter_var);
+ break;
+ }
+
+ default:
+ HAL_WARNING (("Unknown property type 0x%04x", type));
+ break;
+ }
+
+ dbus_message_iter_close_container (iter, &iter_dict_entry);
+
+
+ return TRUE;
+}
+
+
+
+/** Get all properties on a device.
+ *
+ * <pre>
+ * map{string, any} Device.GetAllProperties()
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_get_all_properties (DBusConnection * connection,
+ DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_dict;
+ HalDevice *d;
+ const char *udi;
+
+ udi = dbus_message_get_path (message);
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &iter_dict);
+
+ hal_device_property_foreach (d,
+ foreach_property_append,
+ &iter_dict);
+
+ dbus_message_iter_close_container (&iter, &iter_dict);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+#ifdef sun
+#include <sys/stat.h>
+static dbus_bool_t
+user_at_console(unsigned long uid)
+{
+ struct stat st;
+
+ return ((stat("/dev/console", &st) == 0) && (st.st_uid == uid));
+}
+#endif /* sun */
+
+static dbus_bool_t
+sender_has_privileges (DBusConnection *connection, DBusMessage *message)
+{
+ DBusError error;
+ unsigned long user_uid;
+ const char *user_base_svc;
+ dbus_bool_t ret;
+
+ ret = FALSE;
+
+ user_base_svc = dbus_message_get_sender (message);
+ if (user_base_svc == NULL) {
+ HAL_WARNING (("Cannot determine base service of caller"));
+ goto out;
+ }
+
+ HAL_DEBUG (("base_svc = %s", user_base_svc));
+
+ dbus_error_init (&error);
+ user_uid = dbus_bus_get_unix_user (connection, user_base_svc, &error);
+ if (user_uid == (unsigned long) -1 || dbus_error_is_set (&error)) {
+ HAL_WARNING (("Could not get uid for connection: %s %s", error.name, error.message));
+ dbus_error_free (&error);
+ goto out;
+ }
+
+ HAL_INFO (("uid for caller is %ld", user_uid));
+
+ if (user_uid != 0 && user_uid != geteuid()) {
+#ifdef sun
+ if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "Rescan")) {
+ if (user_at_console(user_uid)) {
+ ret = TRUE;
+ goto out;
+ }
+ }
+#endif
+ HAL_WARNING (("uid %d is not privileged", user_uid));
+ goto out;
+ }
+
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+
+/** Set multiple properties on a device in an atomic fashion.
+ *
+ * <pre>
+ * Device.GetAllProperties(map{string, any} properties)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+static DBusHandlerResult
+device_set_multiple_properties (DBusConnection *connection, DBusMessage *message, dbus_bool_t local_interface)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter dict_iter;
+ HalDevice *d;
+ const char *udi;
+
+ udi = dbus_message_get_path (message);
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "SetProperty: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_message_iter_init (message, &iter);
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY &&
+ dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DICT_ENTRY) {
+ HAL_ERROR (("error, expecting an array of dict entries", __FILE__, __LINE__));
+ raise_syntax (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_message_iter_recurse (&iter, &dict_iter);
+
+ /* update atomically */
+ device_property_atomic_update_begin ();
+
+ while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
+ {
+ DBusMessageIter dict_entry_iter, var_iter, array_iter;
+ const char *key;
+ int change_type;
+ dbus_bool_t rc;
+
+ dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
+ dbus_message_iter_get_basic (&dict_entry_iter, &key);
+
+ dbus_message_iter_next (&dict_entry_iter);
+ dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
+ change_type = dbus_message_iter_get_arg_type (&var_iter);
+
+ rc = FALSE;
+
+ switch (change_type) {
+ case DBUS_TYPE_ARRAY:
+ if (dbus_message_iter_get_element_type (&var_iter) != DBUS_TYPE_STRING) {
+ /* TODO: error */
+ }
+ dbus_message_iter_recurse (&var_iter, &array_iter);
+
+ hal_device_property_strlist_clear (d, key);
+
+ while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
+ const char *v;
+ dbus_message_iter_get_basic (&array_iter, &v);
+ HAL_INFO ((" strlist elem %s -> %s", key, v));
+ rc = hal_device_property_strlist_append (d, key, v);
+ dbus_message_iter_next (&array_iter);
+ }
+
+ break;
+ case DBUS_TYPE_STRING:
+ {
+ const char *v;
+ dbus_message_iter_get_basic (&var_iter, &v);
+ HAL_INFO (("%s -> %s", key, v));
+ rc = hal_device_property_set_string (d, key, v);
+ break;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t v;
+ dbus_message_iter_get_basic (&var_iter, &v);
+ HAL_INFO (("%s -> %d", key, v));
+ rc = hal_device_property_set_int (d, key, v);
+ break;
+ }
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_uint64_t v;
+ dbus_message_iter_get_basic (&var_iter, &v);
+ HAL_INFO (("%s -> %lld", key, v));
+ rc = hal_device_property_set_uint64 (d, key, v);
+ break;
+ }
+ case DBUS_TYPE_DOUBLE:
+ {
+ double v;
+ dbus_message_iter_get_basic (&var_iter, &v);
+ HAL_INFO (("%s -> %g", key, v));
+ rc = hal_device_property_set_double (d, key, v);
+ break;
+ }
+ case DBUS_TYPE_BOOLEAN:
+ {
+ gboolean v;
+ dbus_message_iter_get_basic (&var_iter, &v);
+ HAL_INFO (("%s -> %s", key, v ? "True" : "False"));
+ rc = hal_device_property_set_bool (d, key, v);
+ break;
+ }
+ default:
+ /* TODO: error */
+ break;
+ }
+
+ /* TODO: error out on rc==FALSE? */
+
+ dbus_message_iter_next (&dict_iter);
+ }
+
+ device_property_atomic_update_end ();
+
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/** Get a property on a device.
+ *
+ * <pre>
+ * any Device.GetProperty(string key)
+ * string Device.GetPropertyString(string key)
+ * int Device.GetPropertyInteger(string key)
+ * bool Device.GetPropertyBoolean(string key)
+ * double Device.GetPropertyDouble(string key)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * org.freedesktop.Hal.NoSuchProperty
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_get_property (DBusConnection * connection, DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ const char *udi;
+ char *key;
+ int type;
+ HalProperty *p;
+
+ udi = dbus_message_get_path (message);
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "GetProperty");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ p = hal_device_property_find (d, key);
+ if (p == NULL) {
+ raise_no_such_property (connection, message, udi, key);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+
+ type = hal_property_get_type (p);
+ switch (type) {
+ case HAL_PROPERTY_TYPE_STRING:
+ {
+ const char *s;
+ s = hal_property_get_string (p);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &s);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_INT32:
+ {
+ dbus_int32_t i;
+ i = hal_property_get_int (p);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &i);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_UINT64:
+ {
+ dbus_uint64_t ul;
+ ul = hal_property_get_uint64 (p);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &ul);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ {
+ double d;
+ d = hal_property_get_double (p);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &d);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ {
+ dbus_bool_t b;
+ b = hal_property_get_bool (p);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &b);
+ break;
+ }
+ case HAL_PROPERTY_TYPE_STRLIST:
+ {
+ GSList *l;
+ DBusMessageIter iter_array;
+
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_array);
+
+ for (l = hal_property_get_strlist (p); l != NULL; l = g_slist_next (l)) {
+ dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &(l->data));
+ }
+
+ dbus_message_iter_close_container (&iter, &iter_array);
+ }
+ break;
+
+ default:
+ HAL_WARNING (("Unknown property type %d", type));
+ break;
+ }
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/** Get the type of a property on a device.
+ *
+ * <pre>
+ * int Device.GetPropertyType(string key)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * org.freedesktop.Hal.NoSuchProperty
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_get_property_type (DBusConnection * connection,
+ DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ const char *udi;
+ char *key;
+ HalProperty *p;
+ dbus_int32_t i;
+
+ udi = dbus_message_get_path (message);
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "GetPropertyType");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ p = hal_device_property_find (d, key);
+ if (p == NULL) {
+ raise_no_such_property (connection, message, udi, key);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ i = hal_property_get_type (p);
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &i);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/** Set a property on a device.
+ *
+ * <pre>
+ * void Device.SetProperty(string key, any value)
+ * void Device.SetPropertyString(string key, string value)
+ * void Device.SetPropertyInteger(string key, int value)
+ * void Device.SetPropertyBoolean(string key, bool value)
+ * void Device.SetPropertyDouble(string key, double value)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * org.freedesktop.Hal.NoSuchProperty
+ * org.freedesktop.Hal.TypeMismatch
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_set_property (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ char *key;
+ int type;
+ dbus_bool_t rc;
+ HalDevice *device;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ dbus_message_iter_init (message, &iter);
+ type = dbus_message_iter_get_arg_type (&iter);
+ if (type != DBUS_TYPE_STRING) {
+ raise_syntax (connection, message, "SetProperty");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ dbus_message_iter_get_basic (&iter, &key);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "SetProperty: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s, key=%s", udi, key));
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ dbus_message_iter_next (&iter);
+
+ /** @todo check permissions of the sender vs property to be modified */
+
+ type = dbus_message_iter_get_arg_type (&iter);
+ rc = FALSE;
+
+ switch (type) {
+ case DBUS_TYPE_STRING:
+ {
+ const char *v;
+ dbus_message_iter_get_basic (&iter, &v);
+ rc = hal_device_property_set_string (device, key, v);
+ break;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t v;
+ dbus_message_iter_get_basic (&iter, &v);
+ rc = hal_device_property_set_int (device, key, v);
+ break;
+ }
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_uint64_t v;
+ dbus_message_iter_get_basic (&iter, &v);
+ rc = hal_device_property_set_uint64 (device, key, v);
+ break;
+ }
+ case DBUS_TYPE_DOUBLE:
+ {
+ double v;
+ dbus_message_iter_get_basic (&iter, &v);
+ rc = hal_device_property_set_double (device, key, v);
+ break;
+ }
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_bool_t v;
+ dbus_message_iter_get_basic (&iter, &v);
+ rc = hal_device_property_set_bool (device, key, v);
+ break;
+ }
+ default:
+ HAL_WARNING (("Unsupported property type %d", type));
+ break;
+ }
+
+ if (!rc) {
+ raise_property_type_error (connection, message, udi, key);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/** This function is used to modify the Capabilities property. The reason
+ * for having a dedicated function is that the HAL daemon will broadcast
+ * a signal on the Manager interface to tell applications that the device
+ * have got a new capability.
+ *
+ * This is useful as capabilities can be merged after the device is created.
+ * One example of this is networking cards under Linux 2.6; the net.ethernet
+ * capability is not merged when the device is initially found by looking in
+ * /sys/devices; it is merged when the /sys/classes tree is searched.
+ *
+ * Note that the signal is emitted every time this method is invoked even
+ * though the capability already existed. This is useful in the above
+ * scenario when the PCI class says ethernet networking card but we yet
+ * don't have enough information to fill in the net.* and net.ethernet.*
+ * fields since this only happens when we visit the /sys/classes tree.
+ *
+ * <pre>
+ * void Device.AddCapability(string capability)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * raises org.freedesktop.Hal.PermissionDenied,
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_add_capability (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ const char *capability;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+
+ HAL_TRACE (("entering"));
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "AddCapability: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &capability,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "AddCapability");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+
+ hal_device_add_capability (d, capability);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/* TODO: docs */
+static DBusHandlerResult
+device_string_list_append_prepend (DBusConnection * connection, DBusMessage * message, dbus_bool_t do_prepend)
+{
+ const char *udi;
+ const char *key;
+ const char *value;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+ gboolean ret;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_STRING, &value,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, do_prepend ? "StringListPrepend" : "StringListAppend");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (do_prepend)
+ ret = hal_device_property_strlist_prepend (d, key, value);
+ else
+ ret = hal_device_property_strlist_append (d, key, value);
+ if (!ret) {
+ raise_property_type_error (connection, message, udi, key);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/* TODO: docs */
+static DBusHandlerResult
+device_string_list_remove (DBusConnection * connection, DBusMessage * message)
+{
+ const char *udi;
+ const char *key;
+ const char *value;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+ gboolean ret;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_STRING, &value,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "StringListRemove");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ ret = hal_device_property_strlist_remove (d, key, value);
+ if (!ret) {
+ raise_property_type_error (connection, message, udi, key);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+
+/** Remove a property on a device.
+ *
+ * <pre>
+ * void Device.RemoveProperty(string key)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * org.freedesktop.Hal.NoSuchProperty
+ * org.freedesktop.Hal.PermissionDenied
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_remove_property (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ char *key;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "RemoveProperty: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "RemoveProperty");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (!hal_device_property_remove (d, key)) {
+ raise_no_such_property (connection, message, udi, key);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/** Determine if a property exists
+ *
+ * <pre>
+ * bool Device.PropertyExists(string key)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_property_exists (DBusConnection * connection, DBusMessage * message)
+{
+ const char *udi;
+ char *key;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter iter;
+ dbus_bool_t b;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "RemoveProperty");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ b = hal_device_has_property (d, key);
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &b);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/** Determine if a device has a capability
+ *
+ * <pre>
+ * bool Device.QueryCapability(string capability_name)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_query_capability (DBusConnection * connection,
+ DBusMessage * message)
+{
+ dbus_bool_t rc;
+ const char *udi;
+ GSList *caps;
+ char *capability;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter iter;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &capability,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "QueryCapability");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ rc = FALSE;
+ caps = hal_device_property_get_strlist (d, "info.capabilities");
+ if (caps != NULL) {
+ GSList *iter;
+
+ for (iter = caps; iter != NULL; iter=g_slist_next(iter)) {
+ if (strcmp (iter->data, capability) == 0) {
+ rc = TRUE;
+ break;
+ }
+ }
+ }
+
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &rc);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static GHashTable *services_with_locks = NULL;
+
+/** Grab an advisory lock on a device.
+ *
+ * <pre>
+ * bool Device.Lock(string reason)
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * org.freedesktop.Hal.DeviceAlreadyLocked
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_lock (DBusConnection * connection,
+ DBusMessage * message)
+{
+ const char *udi;
+ HalDevice *d;
+ DBusMessage *reply;
+ dbus_bool_t already_locked;
+ DBusError error;
+ char *reason;
+ const char *sender;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ already_locked = hal_device_property_get_bool (d, "info.locked");
+
+ if (already_locked) {
+ raise_device_already_locked (connection, message, d);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &reason,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "Lock");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ sender = dbus_message_get_sender (message);
+
+ hal_device_property_set_bool (d, "info.locked", TRUE);
+ hal_device_property_set_string (d, "info.locked.reason", reason);
+ hal_device_property_set_string (d, "info.locked.dbus_name",
+ sender);
+
+ if (services_with_locks == NULL) {
+ services_with_locks =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_object_unref);
+ }
+
+ g_hash_table_insert (services_with_locks, g_strdup (sender),
+ g_object_ref (d));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/** Release an advisory lock on a device.
+ *
+ * <pre>
+ * bool Device.Unlock()
+ *
+ * raises org.freedesktop.Hal.NoSuchDevice,
+ * org.freedesktop.Hal.DeviceNotLocked,
+ * org.freedesktop.Hal.PermissionDenied
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+device_unlock (DBusConnection * connection,
+ DBusMessage * message)
+{
+ dbus_bool_t rc;
+ const char *udi;
+ HalDevice *d;
+ DBusMessage *reply;
+ DBusError error;
+ const char *sender;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "Unlock");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ rc = hal_device_property_get_bool (d, "info.locked");
+
+ if (!rc) {
+ raise_device_not_locked (connection, message, d);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ sender = dbus_message_get_sender (message);
+
+ if (strcmp (sender, hal_device_property_get_string (
+ d, "info.locked.dbus_name")) != 0) {
+ char *reason;
+
+ reason = g_strdup_printf ("Service '%s' does not own the "
+ "lock on %s", sender,
+ hal_device_get_udi (d));
+
+ raise_permission_denied (connection, message, reason);
+
+ g_free (reason);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (g_hash_table_lookup (services_with_locks, sender))
+ g_hash_table_remove (services_with_locks, sender);
+ else {
+ HAL_WARNING (("Service '%s' was not in the list of services "
+ "with locks!", sender));
+ }
+
+ hal_device_property_remove (d, "info.locked");
+ hal_device_property_remove (d, "info.locked.reason");
+ hal_device_property_remove (d, "info.locked.dbus_name");
+
+ /* FIXME? Pointless? */
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static GHashTable *services_with_claims = NULL;
+
+/** Claim a branch.
+ *
+ * <pre>
+ * bool Manager.ClaimBranch(string udi, string claim_service)
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+manager_claim_branch (DBusConnection * connection, DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ const char *udi;
+ const char *claim_service;
+ const char *sender;
+ dbus_bool_t already_claimed;
+ unsigned long uid;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_STRING, &claim_service,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "Manager.ClaimBranch");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ already_claimed = hal_device_property_get_bool (d, "info.claimed");
+ if (already_claimed) {
+ raise_branch_already_claimed (connection, message, d);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ sender = dbus_message_get_sender (message);
+
+ dbus_error_init (&error);
+ uid = dbus_bus_get_unix_user (connection, sender, &error);
+ if (uid == (unsigned long) -1 || dbus_error_is_set (&error)) {
+ HAL_WARNING (("Could not get uid for connection: %s %s", error.name, error.message));
+ dbus_error_free (&error);
+ dbus_message_unref (reply);
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ hal_util_branch_claim (hald_get_gdl (), d, TRUE, claim_service, uid);
+ hal_device_property_set_string (d, "info.claimed.dbus_name", sender);
+
+ if (services_with_claims == NULL) {
+ services_with_claims =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_object_unref);
+ }
+
+ g_hash_table_insert (services_with_claims, g_strdup (sender),
+ g_object_ref (d));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+/** Unclaim a branch.
+ *
+ * <pre>
+ * bool Manager.UnclaimBranch(string udi)
+ * </pre>
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @return What to do with the message
+ */
+DBusHandlerResult
+manager_unclaim_branch (DBusConnection * connection, DBusMessage * message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ const char *udi;
+ const char *claim_service;
+ const char *sender;
+ dbus_bool_t already_claimed;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "Manager.UnclaimBranch");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_TRACE (("entering, udi=%s", udi));
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ already_claimed = hal_device_property_get_bool (d, "info.claimed");
+ if (!already_claimed) {
+ raise_branch_not_claimed (connection, message, d);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (strcmp (sender, hal_device_property_get_string (
+ d, "info.claimed.dbus_name")) != 0) {
+ char *reason;
+
+ reason = g_strdup_printf ("Service '%s' does not own the "
+ "claim on %s", sender,
+ hal_device_get_udi (d));
+
+ raise_permission_denied (connection, message, reason);
+
+ g_free (reason);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (g_hash_table_lookup (services_with_claims, sender))
+ g_hash_table_remove (services_with_claims, sender);
+ else {
+ HAL_WARNING (("Service '%s' was not in the list of services "
+ "with claims!", sender));
+ }
+
+ hal_util_branch_claim (hald_get_gdl (), d, FALSE, NULL, 0);
+ hal_device_property_remove (d, "info.claimed.dbus_name");
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/** Counter for atomic updating */
+static int atomic_count = 0;
+
+/** Number of updates pending */
+static int num_pending_updates = 0;
+
+/** Structure for queing updates */
+typedef struct PendingUpdate_s {
+ char *udi; /**< udi of device */
+ char *key; /**< key of property; free when done */
+ dbus_bool_t removed; /**< true iff property was removed */
+ dbus_bool_t added; /**< true iff property was added */
+ struct PendingUpdate_s *next; /**< next update or #NULL */
+} PendingUpdate;
+
+static PendingUpdate *pending_updates_head = NULL;
+
+/** Begin an atomic update - this is useful for updating several properties
+ * in one go.
+ *
+ * Note that an atomic update is recursive - use with caution!
+ */
+void
+device_property_atomic_update_begin (void)
+{
+ atomic_count++;
+}
+
+/** End an atomic update.
+ *
+ * Note that an atomic update is recursive - use with caution!
+ */
+void
+device_property_atomic_update_end (void)
+{
+ PendingUpdate *pu_iter = NULL;
+ PendingUpdate *pu_iter_next = NULL;
+ PendingUpdate *pu_iter2 = NULL;
+
+ --atomic_count;
+
+ if (atomic_count < 0) {
+ HAL_WARNING (("*** atomic_count = %d < 0 !!", atomic_count));
+ atomic_count = 0;
+ }
+
+ if (atomic_count == 0 && num_pending_updates > 0) {
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+
+ for (pu_iter = pending_updates_head;
+ pu_iter != NULL; pu_iter = pu_iter_next) {
+ int num_updates_this;
+
+ pu_iter_next = pu_iter->next;
+
+ /* see if we've already processed this */
+ if (pu_iter->udi == NULL)
+ goto already_processed;
+
+ /* count number of updates for this device */
+ num_updates_this = 0;
+ for (pu_iter2 = pu_iter; pu_iter2 != NULL; pu_iter2 = pu_iter2->next) {
+ if (strcmp (pu_iter2->udi, pu_iter->udi) == 0)
+ num_updates_this++;
+ }
+
+ /* prepare message */
+ message = dbus_message_new_signal (pu_iter->udi,
+ "org.freedesktop.Hal.Device",
+ "PropertyModified");
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32,
+ &num_updates_this);
+
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_BOOLEAN_AS_STRING
+ DBUS_TYPE_BOOLEAN_AS_STRING
+ DBUS_STRUCT_END_CHAR_AS_STRING,
+ &iter_array);
+
+ for (pu_iter2 = pu_iter; pu_iter2 != NULL;
+ pu_iter2 = pu_iter2->next) {
+ if (strcmp (pu_iter2->udi, pu_iter->udi) == 0) {
+ DBusMessageIter iter_struct;
+ dbus_message_iter_open_container (&iter_array,
+ DBUS_TYPE_STRUCT,
+ NULL,
+ &iter_struct);
+ dbus_message_iter_append_basic
+ (&iter_struct,
+ DBUS_TYPE_STRING,
+ &(pu_iter2->key));
+ dbus_message_iter_append_basic
+ (&iter_struct,
+ DBUS_TYPE_BOOLEAN,
+ &(pu_iter2->removed));
+ dbus_message_iter_append_basic
+ (&iter_struct,
+ DBUS_TYPE_BOOLEAN,
+ &(pu_iter2->added));
+
+ dbus_message_iter_close_container (&iter_array, &iter_struct);
+
+ /* signal this is already processed */
+ g_free (pu_iter2->key);
+ if (pu_iter2 != pu_iter) {
+ g_free (pu_iter2->udi);
+ pu_iter2->udi = NULL;
+ }
+ }
+ }
+
+ g_free (pu_iter->udi);
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ if (dbus_connection != NULL) {
+ if (!dbus_connection_send (dbus_connection, message, NULL))
+ DIE (("error broadcasting message"));
+ }
+
+ dbus_message_unref (message);
+
+ already_processed:
+ g_free (pu_iter);
+
+ } /* for all updates */
+
+ num_pending_updates = 0;
+ pending_updates_head = NULL;
+ }
+}
+
+
+
+void
+device_send_signal_property_modified (HalDevice *device, const char *key,
+ dbus_bool_t added, dbus_bool_t removed)
+{
+ const char *udi = hal_device_get_udi (device);
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+/*
+ HAL_INFO(("Entering, udi=%s, key=%s, in_gdl=%s, removed=%s added=%s",
+ device->udi, key,
+ in_gdl ? "true" : "false",
+ removed ? "true" : "false",
+ added ? "true" : "false"));
+*/
+
+ if (atomic_count > 0) {
+ PendingUpdate *pu;
+
+ pu = g_new0 (PendingUpdate, 1);
+ pu->udi = g_strdup (udi);
+ pu->key = g_strdup (key);
+ pu->removed = removed;
+ pu->added = added;
+ pu->next = pending_updates_head;
+
+ pending_updates_head = pu;
+ num_pending_updates++;
+ } else {
+ dbus_int32_t i;
+ DBusMessageIter iter_struct;
+ DBusMessageIter iter_array;
+
+ if (dbus_connection == NULL)
+ goto out;
+
+ message = dbus_message_new_signal (udi,
+ "org.freedesktop.Hal.Device",
+ "PropertyModified");
+
+ dbus_message_iter_init_append (message, &iter);
+ i = 1;
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &i);
+
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_BOOLEAN_AS_STRING
+ DBUS_TYPE_BOOLEAN_AS_STRING
+ DBUS_STRUCT_END_CHAR_AS_STRING,
+ &iter_array);
+
+ dbus_message_iter_open_container (&iter_array,
+ DBUS_TYPE_STRUCT,
+ NULL,
+ &iter_struct);
+
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &removed);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &added);
+
+ dbus_message_iter_close_container (&iter_array, &iter_struct);
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ if (!dbus_connection_send (dbus_connection, message, NULL))
+ DIE (("error broadcasting message"));
+
+ dbus_message_unref (message);
+ }
+out:
+ ;
+}
+
+/** Emits a condition on a device; the device has to be in the GDL for
+ * this function to have effect.
+ *
+ * Is intended for non-continuous events on the device like
+ * ProcesserOverheating, BlockDeviceGotDevice, e.g. conditions that
+ * are exceptional and may not be inferred by looking at properties
+ * (though some may).
+ *
+ * This function accepts a number of parameters that are passed along
+ * in the D-BUS message. The recipient is supposed to extract the parameters
+ * himself, by looking at the HAL specification.
+ *
+ * @param udi The UDI for this device
+ * @param condition_name Name of condition
+ * @param first_arg_type Type of the first argument
+ * @param ... value of first argument, list of additional
+ * type-value pairs. Must be terminated with
+ * DBUS_TYPE_INVALID
+ */
+void
+device_send_signal_condition (HalDevice *device, const char *condition_name, const char *condition_details)
+{
+ const char *udi = hal_device_get_udi (device);
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+ if (dbus_connection == NULL)
+ goto out;
+
+ message = dbus_message_new_signal (udi,
+ "org.freedesktop.Hal.Device",
+ "Condition");
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter,
+ DBUS_TYPE_STRING,
+ &condition_name);
+ dbus_message_iter_append_basic (&iter,
+ DBUS_TYPE_STRING,
+ &condition_details);
+
+ if (!dbus_connection_send (dbus_connection, message, NULL))
+ DIE (("error broadcasting message"));
+
+ dbus_message_unref (message);
+out:
+ return;
+}
+
+
+
+static gboolean
+reinit_dbus (gpointer user_data)
+{
+ HAL_INFO (("entering!"));
+ if (hald_dbus_init ())
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static void
+service_deleted (DBusMessage *message)
+{
+ char *old_service_name;
+ char *new_service_name;
+ HalDevice *d;
+
+ if (!dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &old_service_name,
+ DBUS_TYPE_STRING, &new_service_name,
+ DBUS_TYPE_INVALID)) {
+ HAL_ERROR (("Invalid NameOwnerChanged signal from bus!"));
+ return;
+ }
+
+ if (services_with_locks != NULL) {
+ d = g_hash_table_lookup (services_with_locks, new_service_name);
+
+ if (d != NULL) {
+ hal_device_property_remove (d, "info.locked");
+ hal_device_property_remove (d, "info.locked.reason");
+ hal_device_property_remove (d, "info.locked.dbus_name");
+
+ g_hash_table_remove (services_with_locks, new_service_name);
+ }
+ }
+
+ if (services_with_claims != NULL) {
+ d = g_hash_table_lookup (services_with_claims, new_service_name);
+
+ if (d != NULL) {
+ hal_util_branch_claim (hald_get_gdl (), d, FALSE, NULL, 0);
+ hal_device_property_remove (d, "info.claimed.dbus_name");
+
+ g_hash_table_remove (services_with_claims, new_service_name);
+ }
+ }
+}
+
+static DBusHandlerResult
+device_rescan (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ HalDevice *device;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ gboolean res;
+
+ HAL_INFO (("entering, local_interface=%d", local_interface));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "Rescan: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s", udi));
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ res = osspec_device_rescan (device);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &res);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+device_reprobe (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ HalDevice *device;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ gboolean res;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "Reprobe: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s", udi));
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ res = osspec_device_reprobe (device);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &res);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+static DBusHandlerResult
+device_emit_condition (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ HalDevice *device;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ DBusError error;
+ const char *condition_name;
+ const char *condition_details;
+ dbus_bool_t res;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface) {
+ raise_permission_denied (connection, message, "EmitCondition: only allowed for helpers");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s", udi));
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &condition_name,
+ DBUS_TYPE_STRING, &condition_details,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "EmitCondition");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ device_send_signal_condition (device, condition_name, condition_details);
+
+ res = TRUE;
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &res);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+typedef struct
+{
+ DBusConnection *connection;
+ char *interface_name;
+ char *introspection_xml;
+ char *udi;
+} HelperInterfaceHandler;
+
+static GSList *helper_interface_handlers = NULL;
+
+static DBusHandlerResult
+device_claim_interface (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ HalDevice *device;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ DBusError error;
+ const char *interface_name;
+ const char *introspection_xml;
+ dbus_bool_t res;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface) {
+ raise_permission_denied (connection, message, "ClaimInterface: only allowed for helpers");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s", udi));
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &interface_name,
+ DBUS_TYPE_STRING, &introspection_xml,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "ClaimInterface");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ res = TRUE;
+
+ HAL_INFO (("Local connection 0x%x to handle interface '%s' on udi '%s'",
+ connection,
+ interface_name,
+ udi));
+
+ hal_device_property_strlist_add (device, "info.interfaces", interface_name);
+
+ HelperInterfaceHandler *hih = g_new0 (HelperInterfaceHandler, 1);
+ hih->connection = connection;
+ hih->interface_name = g_strdup (interface_name);
+ hih->introspection_xml = g_strdup (introspection_xml);
+ hih->udi = g_strdup (udi);
+ helper_interface_handlers = g_slist_append (helper_interface_handlers, hih);
+
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &res);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+
+static DBusHandlerResult
+addon_is_ready (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ HalDevice *device;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ DBusError error;
+ dbus_bool_t res;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface) {
+ raise_permission_denied (connection, message, "AddonIsReady: only allowed for helpers");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s", udi));
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "AddonIsReady");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (hal_device_inc_num_ready_addons (device)) {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_added (device);
+ }
+ }
+
+ res = TRUE;
+
+ HAL_INFO (("AddonIsReady on udi '%s'", udi));
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &res);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/*
+ * Create new device in tdl. Return temporary udi.
+ */
+DBusHandlerResult
+manager_new_device (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ gchar *udi;
+ int i;
+ struct timeval tv;
+
+ dbus_error_init (&error);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "NewDevice: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+ d = hal_device_new ();
+
+ gettimeofday(&tv, NULL);
+ for (i = 0; i < 1000000 ; i++) {
+ udi = g_strdup_printf ("/org/freedesktop/Hal/devices/tmp%05x", ((unsigned) tv.tv_usec & 0xfffff)) + i;
+ if (!hal_device_store_find (hald_get_tdl (), udi)) break;
+ g_free (udi);
+ udi = NULL;
+ }
+
+ if (!udi) {
+ raise_error (connection, message, "org.freedesktop.Hal.NoSpace", "NewDevice: no space for device");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+ hal_device_store_add (hald_get_tdl (), d);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+ g_free (udi);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/*
+ * Callout helper.
+ */
+static void
+manager_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+
+ if (!hal_device_store_remove (hald_get_gdl (), d)) {
+ HAL_WARNING (("Error removing device"));
+ }
+}
+
+
+/*
+ * Remove device. Looks in gdl and tdl.
+ */
+DBusHandlerResult
+manager_remove (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ char *udi;
+ int in_tdl = 0;
+
+ dbus_error_init (&error);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "Remove: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "Remove");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL) {
+ hal_device_store_find (hald_get_tdl (), udi);
+ in_tdl = 1;
+ }
+ if (d == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ /* FIXME:
+ * run "info.callouts.remove" ?
+ * delete in gdl ?
+ * (auto) stop "info.addons" ?
+ */
+
+ if (!in_tdl) {
+ hal_util_callout_device_remove (d, manager_remove_done, NULL, NULL);
+ }
+
+ hal_device_store_remove (in_tdl ? hald_get_tdl () : hald_get_gdl (), d);
+ g_object_unref (d);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+/*
+ * Callout helper.
+ */
+static void
+manager_commit_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ HAL_INFO (("Add callouts completed udi=%s", d->udi));
+}
+
+/*
+ * Preprobing helper.
+ */
+static void
+manager_commit_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ if (hal_device_property_get_bool (d, "info.ignore")) {
+ /* Leave the device here with info.ignore==TRUE so we won't pick up children
+ * Also remove category and all capabilities
+ */
+ hal_device_property_remove (d, "info.category");
+ hal_device_property_remove (d, "info.capabilities");
+ hal_device_property_set_string (d, "info.udi", "/org/freedesktop/Hal/devices/ignored-device");
+ hal_device_property_set_string (d, "info.product", "Ignored Device");
+
+ HAL_INFO (("Preprobing merged info.ignore==TRUE"));
+
+ return;
+ }
+
+ /* Merge properties from .fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
+ di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY);
+
+ hal_util_callout_device_add (d, manager_commit_done, NULL, NULL);
+}
+
+
+/*
+ * Move device from tdl to gdl. Runs helpers and callouts.
+ */
+DBusHandlerResult
+manager_commit_to_gdl (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ HalDevice *d;
+ char udi[256], *udi0, *tmp_udi;
+
+ dbus_error_init (&error);
+
+ if (!local_interface && !sender_has_privileges (connection, message)) {
+ raise_permission_denied (connection, message, "CommitToGdl: not privileged");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &tmp_udi,
+ DBUS_TYPE_STRING, &udi0,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "CommitToGdl");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+
+ /* look it up in tdl */
+
+ d = hal_device_store_find (hald_get_tdl (), tmp_udi);
+ if (d == NULL) {
+ raise_no_such_device (connection, message, tmp_udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ /* sanity check & avoid races */
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof udi, "%s", udi0);
+
+ if (hal_device_store_find (hald_get_gdl (), udi)) {
+ /* loose it */
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ raise_error (connection, message, "org.freedesktop.Hal.DeviceExists", "CommitToGdl: Device exists: %s", udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ /* set new udi */
+ hal_device_property_remove (d, "info.udi");
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+
+ /* FIXME:
+ * 'RequireEnable' property?
+ * fdi "preprobe"?
+ * run "info.callouts.preprobe"?
+ * remove "info.ignore" devices?
+ * fdi "information"?
+ * fdi "policy"?
+ * run "info.callouts.add"?
+ * tdl -> gdl?
+ * (auto) start "info.addons"?
+ */
+
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+ hal_util_callout_device_preprobe (d, manager_commit_preprobing_done, NULL, NULL);
+
+ /* move from tdl to gdl */
+ hal_device_store_remove (hald_get_tdl (), d);
+ hal_device_store_add (hald_get_gdl (), d);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+typedef struct {
+ char *udi;
+ char *execpath;
+ char **extra_env;
+ char *mstdin;
+ char *member;
+ char *interface;
+ DBusMessage *message;
+ DBusConnection *connection;
+} MethodInvocation;
+
+static void
+hald_exec_method_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2);
+
+
+static void
+hald_exec_method_free_mi (MethodInvocation *mi)
+{
+ /* hald_runner_run_method() assumes ownership of mi->message.. so we don't free it here */
+ g_free (mi->udi);
+ g_free (mi->execpath);
+ g_strfreev (mi->extra_env);
+ g_free (mi->mstdin);
+ g_free (mi->member);
+ g_free (mi->interface);
+ g_free (mi);
+}
+
+/* returns FALSE if we don't actually invoke anything */
+static gboolean
+hald_exec_method_do_invocation (MethodInvocation *mi)
+{
+ gboolean ret;
+ HalDevice *d;
+
+ ret = FALSE;
+
+ d = hal_device_store_find (hald_get_gdl (), mi->udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), mi->udi);
+
+ if (d != NULL) {
+ /* no timeout */
+ hald_runner_run_method(d,
+ mi->execpath,
+ mi->extra_env,
+ mi->mstdin,
+ TRUE,
+ 0,
+ hald_exec_method_cb,
+ (gpointer) mi->message,
+ (gpointer) mi->connection);
+
+ ret = TRUE;
+ } else {
+ HAL_WARNING (("In-queue method call on non-existant device"));
+
+ raise_no_such_device (mi->connection, mi->message, mi->udi);
+ }
+
+ return ret;
+}
+
+
+static GHashTable *udi_to_method_queue = NULL;
+
+
+gboolean
+device_is_executing_method (HalDevice *d, const char *interface_name, const char *method_name)
+{
+ gpointer origkey;
+ gboolean ret;
+ GList *queue;
+
+ ret = FALSE;
+
+ if (g_hash_table_lookup_extended (udi_to_method_queue, d->udi, &origkey, (gpointer) &queue)) {
+
+ if (queue != NULL) {
+ MethodInvocation *mi;
+ mi = (MethodInvocation *) queue->data;
+ if ((strcmp (mi->interface, interface_name) == 0) &&
+ (strcmp (mi->member, method_name) == 0)) {
+ ret = TRUE;
+ }
+ }
+
+ ret = TRUE;
+ }
+ return ret;
+}
+
+static void
+hald_exec_method_process_queue (const char *udi);
+
+static void
+hald_exec_method_enqueue (MethodInvocation *mi)
+{
+ gpointer origkey;
+ GList *queue;
+
+ if (udi_to_method_queue == NULL) {
+ udi_to_method_queue = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ }
+
+ if (g_hash_table_lookup_extended (udi_to_method_queue, mi->udi, &origkey, (gpointer) &queue)) {
+ HAL_INFO (("enqueue"));
+ queue = g_list_append (queue, mi);
+ g_hash_table_replace (udi_to_method_queue, g_strdup (mi->udi), queue);
+ } else {
+ HAL_INFO (("no need to enqueue"));
+ queue = g_list_append (NULL, mi);
+ g_hash_table_insert (udi_to_method_queue, g_strdup (mi->udi), queue);
+
+ hald_exec_method_do_invocation (mi);
+ }
+}
+
+
+static void
+hald_exec_method_process_queue (const char *udi)
+{
+ gpointer origkey;
+ GList *queue;
+ MethodInvocation *mi;
+
+ if (g_hash_table_lookup_extended (udi_to_method_queue, udi, &origkey, (gpointer) &queue)) {
+
+ /* clean the top of the list */
+ if (queue != NULL) {
+ mi = (MethodInvocation *) queue->data;
+ queue = g_list_delete_link (queue, queue);
+ if (queue == NULL) {
+ g_hash_table_remove (udi_to_method_queue, udi);
+ HAL_INFO (("No more methods in queue"));
+ }
+
+ /* if method was Volume.Unmount() then refresh mount state */
+ if (strcmp (mi->interface, "org.freedesktop.Hal.Device.Volume") == 0 &&
+ strcmp (mi->member, "Unmount") == 0) {
+ HalDevice *d;
+
+ HAL_INFO (("Refreshing mount state for %s since Unmount() completed", mi->udi));
+
+ d = hal_device_store_find (hald_get_gdl (), mi->udi);
+ if (d == NULL) {
+ d = hal_device_store_find (hald_get_tdl (), mi->udi);
+ }
+
+ if (d != NULL) {
+ osspec_refresh_mount_state_for_block_device (d);
+ } else {
+ HAL_WARNING ((" Cannot find device object for %s", mi->udi));
+ }
+ }
+
+ hald_exec_method_free_mi (mi);
+ }
+
+ /* process the rest of the list */
+ if (queue != NULL) {
+ HAL_INFO (("Execing next method in queue"));
+ g_hash_table_replace (udi_to_method_queue, g_strdup (udi), queue);
+
+ mi = (MethodInvocation *) queue->data;
+ if (!hald_exec_method_do_invocation (mi)) {
+ /* the device went away before we got to it... */
+ hald_exec_method_process_queue (mi->udi);
+ }
+ }
+ }
+}
+
+static void
+hald_exec_method_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ dbus_uint32_t result;
+ DBusMessage *reply = NULL;
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusConnection *conn;
+ gchar *exp_name = NULL;
+ gchar *exp_detail = NULL;
+
+ hald_exec_method_process_queue (d->udi);
+
+ message = (DBusMessage *) data1;
+ conn = (DBusConnection *) data2;
+
+ if (exit_type == HALD_RUN_SUCCESS && error != NULL &&
+ error[0] != NULL && error[1] != NULL) {
+ exp_name = error[0];
+ if (error[0] != NULL) {
+ exp_detail = error[1];
+ }
+ HAL_INFO (("failed with '%s' '%s'", exp_name, exp_detail));
+ }
+
+ if (exit_type != HALD_RUN_SUCCESS) {
+ reply = dbus_message_new_error (message, "org.freedesktop.Hal.Device.UnknownError", "An unknown error occured");
+ if (conn != NULL) {
+ if (!dbus_connection_send (conn, reply, NULL))
+ DIE (("No memory"));
+ }
+ dbus_message_unref (reply);
+ } else if (exp_name != NULL && exp_detail != NULL) {
+ reply = dbus_message_new_error (message, exp_name, exp_detail);
+ if (reply == NULL) {
+ /* error name may be invalid - assume caller fucked up and use a generic HAL error name */
+ reply = dbus_message_new_error (message, "org.freedesktop.Hal.Device.UnknownError", "An unknown error occured");
+ if (reply == NULL) {
+ DIE (("No memory"));
+ }
+ }
+ if (conn != NULL) {
+ if (!dbus_connection_send (conn, reply, NULL))
+ DIE (("No memory"));
+ }
+ dbus_message_unref (reply);
+
+ } else {
+ result = (dbus_uint32_t) return_code;
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &result);
+
+ if (conn != NULL) {
+ if (!dbus_connection_send (conn, reply, NULL))
+ DIE (("No memory"));
+ }
+
+ dbus_message_unref (reply);
+ }
+
+ dbus_message_unref (message);
+}
+
+static DBusHandlerResult
+hald_exec_method (HalDevice *d, DBusConnection *connection, dbus_bool_t local_interface,
+ DBusMessage *message, const char *execpath)
+{
+ int type;
+ GString *stdin_str;
+ DBusMessageIter iter;
+ char *extra_env[3];
+ char uid_export[128];
+ char sender_export[128];
+ MethodInvocation *mi;
+
+ /* add calling uid */
+ extra_env[0] = NULL;
+ extra_env[1] = NULL;
+ if (local_interface) {
+ extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
+ extra_env[1] = "HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=0";
+ } else {
+ const char *sender;
+
+ sender = dbus_message_get_sender (message);
+ if (sender != NULL) {
+ DBusError error;
+ unsigned long uid;
+
+ dbus_error_init (&error);
+ uid = dbus_bus_get_unix_user (connection, sender, &error);
+ if (!dbus_error_is_set (&error)) {
+ sprintf (uid_export, "HAL_METHOD_INVOKED_BY_UID=%lu", uid);
+ extra_env[0] = uid_export;
+ }
+ snprintf (sender_export, sizeof (sender_export),
+ "HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=%s", sender);
+ extra_env[1] = sender_export;
+ }
+ }
+
+ if (extra_env[0] == NULL)
+ extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=nobody";
+ if (extra_env[1] == NULL)
+ extra_env[1] = "HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=0";
+
+
+ extra_env[2] = NULL;
+
+ /* prepare stdin with parameters */
+ stdin_str = g_string_sized_new (256); /* default size for passing params; can grow */
+ dbus_message_iter_init (message, &iter);
+ while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) {
+ switch (type) {
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%u", value);
+ break;
+ }
+ case DBUS_TYPE_INT16:
+ {
+ dbus_int16_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%d", value);
+ break;
+ }
+ case DBUS_TYPE_UINT16:
+ {
+ dbus_uint16_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%u", value);
+ break;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%d", value);
+ break;
+ }
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_uint32_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%u", value);
+ break;
+ }
+ case DBUS_TYPE_INT64:
+ {
+ dbus_int64_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%lld", (long long int) value);
+ break;
+ }
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_uint64_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%llu", (long long unsigned int) value);
+ break;
+ }
+ case DBUS_TYPE_DOUBLE:
+ {
+ double value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append_printf (stdin_str, "%g", value);
+ break;
+ }
+ case DBUS_TYPE_BOOLEAN:
+ {
+ dbus_bool_t value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append (stdin_str, value ? "true" : "false");
+ break;
+ }
+ case DBUS_TYPE_STRING:
+ {
+ char *value;
+ dbus_message_iter_get_basic (&iter, &value);
+ g_string_append (stdin_str, value);
+ break;
+ }
+
+ case DBUS_TYPE_ARRAY:
+ {
+ DBusMessageIter iter_strlist;
+ if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_recurse (&iter, &iter_strlist);
+ while (dbus_message_iter_get_arg_type (&iter_strlist) == DBUS_TYPE_STRING) {
+ const char *value;
+ dbus_message_iter_get_basic (&iter_strlist, &value);
+ g_string_append (stdin_str, value);
+ g_string_append (stdin_str, "\t");
+ dbus_message_iter_next(&iter_strlist);
+ }
+ break;
+ }
+
+ default:
+ goto error;
+ }
+
+ g_string_append_c (stdin_str, '\n');
+ dbus_message_iter_next (&iter);
+ }
+
+ mi = g_new0 (MethodInvocation, 1);
+ mi->udi = g_strdup (d->udi);
+ mi->execpath = g_strdup (execpath);
+ mi->extra_env = g_strdupv (extra_env);
+ mi->mstdin = g_strdup (stdin_str->str);
+ mi->message = message;
+ mi->connection = connection;
+ mi->member = g_strdup (dbus_message_get_member (message));
+ mi->interface = g_strdup (dbus_message_get_interface (message));
+ hald_exec_method_enqueue (mi);
+
+ dbus_message_ref (message);
+ g_string_free (stdin_str, TRUE);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+
+error:
+ g_string_free (stdin_str, TRUE);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static gboolean
+foreach_device_get_xml_node (HalDeviceStore *store, HalDevice *device,
+ gpointer user_data)
+{
+ GString *xml = user_data;
+ const char *udi, *name;
+
+ udi = hal_device_get_udi (device);
+ name = strrchr(udi, '/')+1;
+
+ xml = g_string_append(xml, " <node name=\"");
+ xml = g_string_append(xml, name);
+ xml = g_string_append(xml, "\"/>\n");
+
+ return TRUE;
+}
+
+static DBusHandlerResult
+do_introspect (DBusConnection *connection,
+ DBusMessage *message,
+ dbus_bool_t local_interface)
+{
+ const char *path;
+ DBusMessage *reply;
+ GString *xml;
+ char *xml_string;
+
+ HAL_TRACE (("entering do_introspect"));
+
+ path = dbus_message_get_path (message);
+
+ xml = g_string_new ("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+ "<node>\n"
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+ " <method name=\"Introspect\">\n"
+ " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " </interface>\n");
+
+ if (strcmp (path, "/") == 0) {
+
+ xml = g_string_append (xml,
+ " <node name=\"org\"/>\n");
+
+ } else if (strcmp (path, "/org") == 0) {
+
+ xml = g_string_append (xml,
+ " <node name=\"freedesktop\"/>\n");
+
+ } else if (strcmp (path, "/org/freedesktop") == 0) {
+
+ xml = g_string_append (xml,
+ " <node name=\"Hal\"/>\n");
+
+ } else if (strcmp (path, "/org/freedesktop/Hal") == 0) {
+
+ xml = g_string_append (xml,
+ " <node name=\"Manager\"/>\n"
+ " <node name=\"devices\"/>\n");
+
+ } else if (strcmp (path, "/org/freedesktop/Hal/devices") == 0) {
+
+ hal_device_store_foreach (hald_get_gdl (),
+ foreach_device_get_xml_node,
+ xml);
+
+ } else if (strcmp (path, "/org/freedesktop/Hal/Manager") == 0) {
+
+ xml = g_string_append (xml,
+ " <interface name=\"org.freedesktop.Hal.Manager\">\n"
+ " <method name=\"GetAllDevices\">\n"
+ " <arg name=\"devices\" direction=\"out\" type=\"ao\"/>\n"
+ " </method>\n"
+ " <method name=\"DeviceExists\">\n"
+ " <arg name=\"does_it_exist\" direction=\"out\" type=\"b\"/>\n"
+ " <arg name=\"udi\" direction=\"in\" type=\"o\"/>\n"
+ " </method>\n"
+ " <method name=\"FindDeviceStringMatch\">\n"
+ " <arg name=\"devices\" direction=\"out\" type=\"ao\"/>\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"FindDeviceByCapability\">\n"
+ " <arg name=\"devices\" direction=\"out\" type=\"ao\"/>\n"
+ " <arg name=\"capability\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"ClaimBranch\">\n"
+ " <arg name=\"udi\" direction=\"in\" type=\"o\"/>\n"
+ " <arg name=\"claim_service\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"result\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"UnclaimBranch\">\n"
+ " <arg name=\"udi\" direction=\"in\" type=\"o\"/>\n"
+ " <arg name=\"result\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"NewDevice\">\n"
+ " <arg name=\"temporary_udi\" direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"Remove\">\n"
+ " <arg name=\"udi\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"CommitToGdl\">\n"
+ " <arg name=\"temporary_udi\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"global_udi\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " </interface>\n");
+ } else {
+ HalDevice *d;
+
+ d = hal_device_store_find (hald_get_gdl (), path);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), path);
+
+ if (d == NULL) {
+ raise_no_such_device (connection, message, path);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ xml = g_string_append (xml,
+ " <interface name=\"org.freedesktop.Hal.Device\">\n"
+ " <method name=\"GetAllProperties\">\n"
+ " <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n"
+ " </method>\n"
+ " <method name=\"SetMultipleProperties\">\n"
+ " <arg name=\"properties\" direction=\"in\" type=\"a{sv}\"/>\n"
+ " </method>\n"
+ " <method name=\"GetProperty\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"
+ " </method>\n"
+ " <method name=\"GetPropertyString\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"out\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"GetPropertyStringList\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"out\" type=\"as\"/>\n"
+ " </method>\n"
+ " <method name=\"GetPropertyInteger\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"out\" type=\"i\"/>\n"
+ " </method>\n"
+ " <method name=\"GetPropertyBoolean\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"GetPropertyDouble\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"out\" type=\"d\"/>\n"
+ " </method>\n"
+ " <method name=\"SetProperty\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"v\"/>\n"
+ " </method>\n"
+ " <method name=\"SetPropertyString\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"SetPropertyStringList\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"as\"/>\n"
+ " </method>\n"
+ " <method name=\"SetPropertyInteger\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"i\"/>\n"
+ " </method>\n"
+ " <method name=\"SetPropertyBoolean\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"SetPropertyDouble\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"d\"/>\n"
+ " </method>\n"
+
+ " <method name=\"RemoveProperty\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"GetPropertyType\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"type\" direction=\"out\" type=\"i\"/>\n"
+ " </method>\n"
+ " <method name=\"PropertyExists\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"does_it_exist\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"AddCapability\">\n"
+ " <arg name=\"capability\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"QueryCapability\">\n"
+ " <arg name=\"capability\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"does_it_have_capability\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"Lock\">\n"
+ " <arg name=\"reason\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"acquired_lock\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"Unlock\">\n"
+ " <arg name=\"released_lock\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+
+ " <method name=\"StringListAppend\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"StringListPrepend\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"StringListRemove\">\n"
+ " <arg name=\"key\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"value\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
+ " <method name=\"EmitCondition\">\n"
+ " <arg name=\"condition_name\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"condition_details\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"rc\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+
+ " <method name=\"Rescan\">\n"
+ " <arg name=\"call_had_sideeffect\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+ " <method name=\"Reprobe\">\n"
+ " <arg name=\"call_had_sideeffect\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+
+ " <method name=\"ClaimInterface\">\n"
+ " <arg name=\"interface_name\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"introspection_xml\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"rc\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+
+ " <method name=\"AddonIsReady\">\n"
+ " <arg name=\"rc\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+
+ " </interface>\n");
+
+ GSList *interfaces;
+ GSList *i;
+
+ interfaces = hal_device_property_get_strlist (d, "info.interfaces");
+ for (i = interfaces; i != NULL; i = g_slist_next (i)) {
+ const char *ifname = (const char *) i->data;
+ char *method_names_prop;
+ char *method_signatures_prop;
+ char *method_argnames_prop;
+ GSList *method_names;
+ GSList *method_signatures;
+ GSList *method_argnames;
+ GSList *j;
+ GSList *k;
+ GSList *l;
+
+ g_string_append_printf (xml, " <interface name=\"%s\">\n", ifname);
+
+ method_names_prop = g_strdup_printf ("%s.method_names", ifname);
+ method_signatures_prop = g_strdup_printf ("%s.method_signatures", ifname);
+ method_argnames_prop = g_strdup_printf ("%s.method_argnames", ifname);
+
+ method_names = hal_device_property_get_strlist (d, method_names_prop);
+ method_signatures = hal_device_property_get_strlist (d, method_signatures_prop);
+ method_argnames = hal_device_property_get_strlist (d, method_argnames_prop);
+
+ /* consult local list */
+ if (method_names == NULL) {
+ GSList *i;
+
+ for (i = helper_interface_handlers; i != NULL; i = g_slist_next (i)) {
+ HelperInterfaceHandler *hih = i->data;
+ if (strcmp (hih->udi, path) == 0) {
+ xml = g_string_append (xml, hih->introspection_xml);
+ }
+ }
+
+ }
+
+ for (j = method_names, k = method_signatures, l = method_argnames;
+ j != NULL && k != NULL && l != NULL;
+ j = g_slist_next (j), k = g_slist_next (k), l = g_slist_next (l)) {
+ const char *name;
+ const char *sig;
+ const char *argnames;
+ char **args;
+ unsigned int n;
+ unsigned int m;
+
+ name = j->data;
+ sig = k->data;
+ argnames = l->data;
+
+ args = g_strsplit (argnames, " ", 0);
+
+ g_string_append_printf (xml, " <method name=\"%s\">\n", name);
+
+ for (n = 0, m = 0; n < strlen (sig) && args[m] != NULL; n++, m++) {
+ switch (sig[n]) {
+ case 'a':
+ if (n == strlen (sig) - 1) {
+ HAL_WARNING (("Broken signature for method %s "
+ "on interface %s for object %s",
+ name, ifname, path));
+ continue;
+ }
+ g_string_append_printf (
+ xml,
+ " <arg name=\"%s\" direction=\"in\" type=\"a%c\"/>\n",
+ args[m], sig[n + 1]);
+ n++;
+ break;
+
+ default:
+ g_string_append_printf (
+ xml,
+ " <arg name=\"%s\" direction=\"in\" type=\"%c\"/>\n",
+ args[m], sig[n]);
+ break;
+ }
+ }
+ xml = g_string_append (
+ xml,
+ " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n");
+ xml = g_string_append (
+ xml,
+ " </method>\n");
+
+ }
+
+
+ xml = g_string_append (xml, " </interface>\n");
+
+ g_free (method_names_prop);
+ g_free (method_signatures_prop);
+ g_free (method_argnames_prop);
+ }
+
+ }
+
+ reply = dbus_message_new_method_return (message);
+
+ xml = g_string_append (xml, "</node>\n");
+ xml_string = g_string_free (xml, FALSE);
+
+ dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &xml_string,
+ DBUS_TYPE_INVALID);
+
+ g_free (xml_string);
+
+ if (reply == NULL)
+ DIE (("No memory"));
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+reply_from_fwd_message (DBusPendingCall *pending_call,
+ void *user_data)
+{
+ DBusMessage *reply_from_addon;
+ DBusMessage *method_from_caller;
+ DBusMessage *reply;
+
+ /*HAL_INFO (("in reply_from_fwd_message : user_data = 0x%x", user_data));*/
+
+ method_from_caller = (DBusMessage *) user_data;
+ reply_from_addon = dbus_pending_call_steal_reply (pending_call);
+
+ reply = dbus_message_copy (reply_from_addon);
+ dbus_message_set_destination (reply, dbus_message_get_sender (method_from_caller));
+ dbus_message_set_reply_serial (reply, dbus_message_get_serial (method_from_caller));
+
+ if (dbus_connection != NULL)
+ dbus_connection_send (dbus_connection, reply, NULL);
+
+ dbus_message_unref (reply_from_addon);
+ dbus_message_unref (reply);
+ dbus_message_unref (method_from_caller);
+ dbus_pending_call_unref (pending_call);
+}
+
+static DBusHandlerResult
+hald_dbus_filter_handle_methods (DBusConnection *connection, DBusMessage *message,
+ void *user_data, dbus_bool_t local_interface)
+{
+ /*HAL_INFO (("connection=0x%x obj_path=%s interface=%s method=%s local_interface=%d",
+ connection,
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message),
+ local_interface));*/
+
+ if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "GetAllDevices") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_get_all_devices (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "DeviceExists") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_device_exists (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "FindDeviceStringMatch") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_find_device_string_match (connection,
+ message);
+ } else if (dbus_message_is_method_call
+ (message, "org.freedesktop.Hal.Manager",
+ "FindDeviceByCapability")
+ && strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_find_device_by_capability (connection,
+ message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "ClaimBranch") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_claim_branch (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "UnclaimBranch") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_unclaim_branch (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "NewDevice") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_new_device (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "Remove") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_remove (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Manager",
+ "CommitToGdl") &&
+ strcmp (dbus_message_get_path (message),
+ "/org/freedesktop/Hal/Manager") == 0) {
+ return manager_commit_to_gdl (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetAllProperties")) {
+ return device_get_all_properties (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "SetMultipleProperties")) {
+ return device_set_multiple_properties (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetProperty")) {
+ return device_get_property (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyString")) {
+ return device_get_property (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyStringList")) {
+ return device_get_property (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyInteger")) {
+ return device_get_property (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyBoolean")) {
+ return device_get_property (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyDouble")) {
+ return device_get_property (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "SetProperty")) {
+ return device_set_property (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "SetPropertyString")) {
+ return device_set_property (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "SetPropertyInteger")) {
+ return device_set_property (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "SetPropertyBoolean")) {
+ return device_set_property (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "SetPropertyDouble")) {
+ return device_set_property (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "RemoveProperty")) {
+ return device_remove_property (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyType")) {
+ return device_get_property_type (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "PropertyExists")) {
+ return device_property_exists (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "AddCapability")) {
+ return device_add_capability (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "QueryCapability")) {
+ return device_query_capability (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "Lock")) {
+ return device_lock (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "Unlock")) {
+ return device_unlock (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "StringListAppend")) {
+ return device_string_list_append_prepend (connection, message, FALSE);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "StringListPrepend")) {
+ return device_string_list_append_prepend (connection, message, TRUE);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "StringListRemove")) {
+ return device_string_list_remove (connection, message);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "Rescan")) {
+ return device_rescan (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "Reprobe")) {
+ return device_reprobe (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "EmitCondition")) {
+ return device_emit_condition (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "ClaimInterface")) {
+ return device_claim_interface (connection, message, local_interface);
+#if 0
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "ReleaseInterface")) {
+ return device_release_interface (connection, message, local_interface);
+#endif
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "AddonIsReady")) {
+ return addon_is_ready (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.DBus.Introspectable",
+ "Introspect")) {
+ return do_introspect (connection, message, local_interface);
+ } else {
+ const char *interface;
+ const char *udi;
+ const char *method;
+ const char *signature;
+ HalDevice *d;
+
+ /* check for device-specific interfaces that individual objects may support */
+
+ udi = dbus_message_get_path (message);
+ interface = dbus_message_get_interface (message);
+ method = dbus_message_get_member (message);
+ signature = dbus_message_get_signature (message);
+
+ d = NULL;
+
+ if (udi != NULL) {
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+ }
+
+ if (d != NULL && interface != NULL) {
+ GSList *i;
+
+ for (i = helper_interface_handlers; i != NULL; i = g_slist_next (i)) {
+ HelperInterfaceHandler *hih = i->data;
+ if (strcmp (hih->udi, udi) == 0 &&
+ strcmp (hih->interface_name, interface) == 0) {
+ DBusPendingCall *pending_call;
+ DBusMessage *copy;
+
+ /*HAL_INFO (("forwarding method to connection 0x%x", hih->connection));*/
+
+ dbus_message_ref (message);
+
+ /* send a copy of the message */
+ copy = dbus_message_copy (message);
+ if (!dbus_connection_send_with_reply (hih->connection,
+ copy,
+ &pending_call,
+ /*-1*/ 8000)) {
+ /* TODO: handle error */
+ } else {
+ /*HAL_INFO (("connection=%x message=%x", connection, message));*/
+ dbus_pending_call_set_notify (pending_call,
+ reply_from_fwd_message,
+ (void *) message,
+ NULL);
+ }
+
+ dbus_message_unref (copy);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+ }
+
+ if (d != NULL && interface != NULL && method != NULL && signature != NULL) {
+ GSList *interfaces;
+ GSList *i;
+
+ interfaces = hal_device_property_get_strlist (d, "info.interfaces");
+ for (i = interfaces; i != NULL; i = g_slist_next (i)) {
+ const char *ifname = (const char *) i->data;
+
+ if (strcmp (ifname, interface) == 0) {
+ guint num;
+ GSList *method_names;
+ char *s;
+
+ s = g_strdup_printf ("%s.method_names", interface);
+ method_names = hal_device_property_get_strlist (d, s);
+ g_free (s);
+ for (i = method_names, num = 0; i != NULL; i = g_slist_next (i), num++) {
+ const char *methodname = (const char *) i->data;
+ if (strcmp (methodname, method) == 0) {
+ const char *execpath;
+ const char *sig;
+
+ s = g_strdup_printf ("%s.method_execpaths", interface);
+ execpath = hal_device_property_get_strlist_elem (d, s, num);
+ g_free (s);
+ s = g_strdup_printf ("%s.method_signatures", interface);
+ sig = hal_device_property_get_strlist_elem (d, s, num);
+ g_free (s);
+
+ if (execpath != NULL && sig != NULL &&
+ strcmp (sig, signature) == 0) {
+
+ HAL_INFO (("OK for method '%s' with signature '%s' on interface '%s' for UDI '%s' and execpath '%s'", method, signature, interface, udi, execpath));
+
+ return hald_exec_method (d, connection, local_interface,
+ message, execpath);
+ }
+
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ return osspec_filter_function (connection, message, user_data);
+}
+
+
+/** Message handler for method invocations. All invocations on any object
+ * or interface is routed through this function.
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @param user_data User data
+ * @return What to do with the message
+ */
+DBusHandlerResult
+hald_dbus_filter_function (DBusConnection * connection,
+ DBusMessage * message, void *user_data)
+{
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
+ strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) {
+
+ /* this is a local message; e.g. from libdbus in this process */
+
+ HAL_INFO (("Got disconnected from the system message bus; "
+ "retrying to reconnect every 3000 ms"));
+ dbus_connection_unref (dbus_connection);
+ dbus_connection = NULL;
+
+ g_timeout_add (3000, reinit_dbus, NULL);
+
+ } else if (dbus_message_is_signal (message,
+ DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged")) {
+
+ if (services_with_locks != NULL || services_with_claims != NULL)
+ service_deleted (message);
+ } else
+ return hald_dbus_filter_handle_methods (connection, message, user_data, FALSE);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
+
+static DBusHandlerResult
+local_server_message_handler (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ /*HAL_INFO (("local_server_message_handler: destination=%s obj_path=%s interface=%s method=%s",
+ dbus_message_get_destination (message),
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message)));*/
+
+ if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) {
+ DBusMessage *reply;
+
+ /* cheat, and handle AddMatch since libhal will try to invoke this method */
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
+ strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) {
+ GSList *i;
+ GSList *j;
+
+ HAL_INFO (("Client to local_server was disconnected"));
+
+ for (i = helper_interface_handlers; i != NULL; i = j) {
+ HelperInterfaceHandler *hih = i->data;
+
+ j = g_slist_next (i);
+
+ if (hih->connection == connection) {
+ g_free (hih->interface_name);
+ g_free (hih->introspection_xml);
+ g_free (hih->udi);
+ g_free (hih);
+ helper_interface_handlers = g_slist_remove (helper_interface_handlers, i);
+ }
+ }
+
+ dbus_connection_unref (connection);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL) {
+ DBusMessage *copy;
+
+ /* it's a signal, just forward it onto the system message bus */
+ copy = dbus_message_copy (message);
+ if (dbus_connection != NULL) {
+ dbus_connection_send (dbus_connection, copy, NULL);
+ }
+ dbus_message_unref (copy);
+ } else {
+ return hald_dbus_filter_handle_methods (connection, message, user_data, TRUE);
+ }
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+local_server_unregister_handler (DBusConnection *connection, void *user_data)
+{
+ HAL_INFO (("unregistered"));
+}
+
+static void
+local_server_handle_connection (DBusServer *server,
+ DBusConnection *new_connection,
+ void *data)
+{
+ DBusObjectPathVTable vtable = { &local_server_unregister_handler,
+ &local_server_message_handler,
+ NULL, NULL, NULL, NULL};
+
+ HAL_INFO (("%d: Got a connection", getpid ()));
+ HAL_INFO (("dbus_connection_get_is_connected = %d", dbus_connection_get_is_connected (new_connection)));
+
+ /*dbus_connection_add_filter (new_connection, server_filter_function, NULL, NULL);*/
+
+ dbus_connection_register_fallback (new_connection,
+ "/org/freedesktop",
+ &vtable,
+ NULL);
+ dbus_connection_ref (new_connection);
+ dbus_connection_setup_with_g_main (new_connection, NULL);
+}
+
+
+static DBusServer *local_server = NULL;
+
+char *
+hald_dbus_local_server_addr (void)
+{
+ if (local_server == NULL)
+ return NULL;
+
+ return dbus_server_get_address (local_server);
+}
+
+gboolean
+hald_dbus_local_server_init (void)
+{
+ gboolean ret;
+ DBusError error;
+ char *server_addr;
+
+ ret = FALSE;
+
+ /* setup a server listening on a socket so we can do point to point
+ * connections for programs spawned by hald
+ */
+ dbus_error_init (&error);
+ if ((local_server = dbus_server_listen (HALD_DBUS_ADDRESS, &error)) == NULL) {
+ HAL_ERROR (("Cannot create D-BUS server"));
+ goto out;
+ }
+ server_addr = dbus_server_get_address (local_server);
+ HAL_INFO (("local server is listening at %s", server_addr));
+ dbus_free (server_addr);
+ dbus_server_setup_with_g_main (local_server, NULL);
+ dbus_server_set_new_connection_function (local_server, local_server_handle_connection, NULL, NULL);
+
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+gboolean
+hald_dbus_init (void)
+{
+ DBusError dbus_error;
+
+ HAL_INFO (("entering"));
+
+ dbus_connection_set_change_sigpipe (TRUE);
+
+ dbus_error_init (&dbus_error);
+ dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
+ if (dbus_connection == NULL) {
+ HAL_ERROR (("dbus_bus_get(): %s", dbus_error.message));
+ return FALSE;
+ }
+
+ dbus_connection_setup_with_g_main (dbus_connection, NULL);
+ dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
+
+ dbus_bus_request_name (dbus_connection, "org.freedesktop.Hal",
+ 0, &dbus_error);
+ if (dbus_error_is_set (&dbus_error)) {
+ HAL_ERROR (("dbus_bus_request_name(): %s",
+ dbus_error.message));
+ return FALSE;
+ }
+
+ dbus_connection_add_filter (dbus_connection, hald_dbus_filter_function, NULL, NULL);
+
+ dbus_bus_add_match (dbus_connection,
+ "type='signal'"
+ ",interface='"DBUS_INTERFACE_DBUS"'"
+ ",sender='"DBUS_SERVICE_DBUS"'"
+ ",member='NameOwnerChanged'",
+ NULL);
+
+ return TRUE;
+}
+
+/** @} */
diff --git a/usr/src/cmd/hal/hald/hald_dbus.h b/usr/src/cmd/hal/hald/hald_dbus.h
new file mode 100644
index 0000000000..d81cb477a3
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald_dbus.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal_dbus.h : D-BUS interface of HAL daemon
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef HAL_DBUS_H
+#define HAL_DBUS_H
+
+#include <dbus/dbus.h>
+
+#include "device.h"
+
+DBusHandlerResult manager_get_all_devices (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult manager_find_device_string_match (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult manager_find_device_by_capability (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult manager_device_exists (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_get_all_properties (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_get_property (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_get_property_type (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_set_property (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult device_add_capability (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult device_remove_capability (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult device_remove_property (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult device_property_exists (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_query_capability (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_lock (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_unlock (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult manager_new_device (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult manager_commit_to_gdl (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult manager_remove (DBusConnection *conn,
+ DBusMessage *msg, dbus_bool_t local_interface);
+DBusHandlerResult merge_properties (DBusConnection *conn,
+ DBusMessage *msg);
+DBusHandlerResult device_matches (DBusConnection *conn,
+ DBusMessage *msg);
+
+void manager_send_signal_device_added (HalDevice *device);
+void manager_send_signal_device_removed (HalDevice *device);
+void manager_send_signal_new_capability (HalDevice *device,
+ const char *capability);
+
+void device_send_signal_property_modified (HalDevice *device,
+ const char *key,
+ dbus_bool_t removed,
+ dbus_bool_t added);
+void device_send_signal_condition (HalDevice *device,
+ const char *condition_name,
+ const char *condition_details);
+
+void device_property_atomic_update_begin (void);
+void device_property_atomic_update_end (void);
+
+gboolean hald_dbus_init (void);
+
+gboolean hald_dbus_local_server_init (void);
+
+DBusHandlerResult hald_dbus_filter_function (DBusConnection * connection, DBusMessage * message, void *user_data);
+
+char *hald_dbus_local_server_addr (void);
+
+gboolean device_is_executing_method (HalDevice *d, const char *interface_name, const char *method_name);
+
+#endif /* HAL_DBUS_H */
diff --git a/usr/src/cmd/hal/hald/hald_marshal.list b/usr/src/cmd/hal/hald/hald_marshal.list
new file mode 100644
index 0000000000..8e3863a85c
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald_marshal.list
@@ -0,0 +1,6 @@
+VOID:STRING,BOOL,BOOL
+VOID:STRING
+VOID:OBJECT,BOOL
+VOID:OBJECT,STRING,BOOL,BOOL
+VOID:OBJECT,STRING
+VOID:VOID
diff --git a/usr/src/cmd/hal/hald/hald_runner.c b/usr/src/cmd/hal/hald/hald_runner.c
new file mode 100644
index 0000000000..a0f07d1197
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald_runner.c
@@ -0,0 +1,593 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hald_runner.c - Interface to the hal runner helper daemon
+ *
+ * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/utsname.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "hald.h"
+#include "util.h"
+#include "logger.h"
+#include "hald_dbus.h"
+#include "hald_runner.h"
+
+typedef struct {
+ HalDevice *d;
+ HalRunTerminatedCB cb;
+ gpointer data1;
+ gpointer data2;
+} HelperData;
+
+#define DBUS_SERVER_ADDRESS "unix:tmpdir=" HALD_SOCKET_DIR
+
+static DBusConnection *runner_connection = NULL;
+
+typedef struct
+{
+ GPid pid;
+ HalDevice *device;
+ HalRunTerminatedCB cb;
+ gpointer data1;
+ gpointer data2;
+} RunningProcess;
+
+/* mapping from PID to RunningProcess */
+static GHashTable *running_processes;
+
+static gboolean
+rprd_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ gboolean remove = FALSE;
+ RunningProcess *rp = value;
+ HalDevice *device = user_data;
+
+ if (rp->device == device) {
+ remove = TRUE;
+ g_free (rp);
+ }
+
+ return remove;
+}
+
+static void
+running_processes_remove_device (HalDevice *device)
+{
+ g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
+}
+
+void
+runner_device_finalized (HalDevice *device)
+{
+ running_processes_remove_device (device);
+}
+
+
+static DBusHandlerResult
+runner_server_message_handler (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+
+ /*HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s",
+ dbus_message_get_destination (message),
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message)));*/
+ if (dbus_message_is_signal (message,
+ "org.freedesktop.HalRunner",
+ "StartedProcessExited")) {
+ dbus_uint64_t dpid;
+ DBusError error;
+ dbus_error_init (&error);
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_INT64, &dpid,
+ DBUS_TYPE_INVALID)) {
+ RunningProcess *rp;
+ GPid pid;
+
+ pid = (GPid) dpid;
+
+ /*HAL_INFO (("Previously started process with pid %d exited", pid));*/
+ rp = g_hash_table_lookup (running_processes, (gpointer) pid);
+ if (rp != NULL) {
+ rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
+ g_hash_table_remove (running_processes, (gpointer) pid);
+ g_free (rp);
+ }
+ }
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+runner_server_unregister_handler (DBusConnection *connection, void *user_data)
+{
+ HAL_INFO (("unregistered"));
+}
+
+
+static void
+handle_connection(DBusServer *server,
+ DBusConnection *new_connection,
+ void *data)
+{
+
+ if (runner_connection == NULL) {
+ DBusObjectPathVTable vtable = { &runner_server_unregister_handler,
+ &runner_server_message_handler,
+ NULL, NULL, NULL, NULL};
+
+ runner_connection = new_connection;
+ dbus_connection_ref (new_connection);
+ dbus_connection_setup_with_g_main (new_connection, NULL);
+
+ dbus_connection_register_fallback (new_connection,
+ "/org/freedesktop",
+ &vtable,
+ NULL);
+
+ /* dbus_server_unref(server); */
+
+ }
+}
+
+static void
+runner_died(GPid pid, gint status, gpointer data) {
+ g_spawn_close_pid (pid);
+ DIE (("Runner died"));
+}
+
+gboolean
+hald_runner_start_runner(void)
+{
+ DBusServer *server = NULL;
+ DBusError err;
+ GError *error = NULL;
+ GPid pid;
+ char *argv[] = { NULL, NULL};
+ char *env[] = { NULL, NULL, NULL, NULL};
+ const char *hald_runner_path;
+ char *server_addr;
+
+ running_processes = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ dbus_error_init(&err);
+ server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
+ if (server == NULL) {
+ HAL_ERROR (("Cannot create D-BUS server for the runner"));
+ goto error;
+ }
+
+ dbus_server_setup_with_g_main(server, NULL);
+ dbus_server_set_new_connection_function(server, handle_connection,
+ NULL, NULL);
+
+
+ argv[0] = "hald-runner";
+ server_addr = dbus_server_get_address (server);
+ env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s", server_addr);
+ dbus_free (server_addr);
+ hald_runner_path = g_getenv("HALD_RUNNER_PATH");
+ if (hald_runner_path != NULL) {
+ env[1] = g_strdup_printf ("PATH=%s:" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR, hald_runner_path);
+ } else {
+ env[1] = g_strdup_printf ("PATH=" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR);
+ }
+
+ /*env[2] = "DBUS_VERBOSE=1";*/
+
+
+ if (!g_spawn_async(NULL, argv, env, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
+ NULL, NULL, &pid, &error)) {
+ HAL_ERROR (("Could not spawn runner : '%s'", error->message));
+ g_error_free (error);
+ goto error;
+ }
+ g_free(env[0]);
+ g_free(env[1]);
+
+ HAL_INFO (("Runner has pid %d", pid));
+
+ g_child_watch_add(pid, runner_died, NULL);
+ while (runner_connection == NULL) {
+ /* Wait for the runner */
+ g_main_context_iteration(NULL, TRUE);
+ }
+ return TRUE;
+
+error:
+ if (server != NULL)
+ dbus_server_unref(server);
+ return FALSE;
+}
+
+static gboolean
+add_property_to_msg (HalDevice *device, HalProperty *property,
+ gpointer user_data)
+{
+ char *prop_upper, *value;
+ char *c;
+ gchar *env;
+ DBusMessageIter *iter = (DBusMessageIter *)user_data;
+
+ prop_upper = g_ascii_strup (hal_property_get_key (property), -1);
+
+ /* periods aren't valid in the environment, so replace them with
+ * underscores. */
+ for (c = prop_upper; *c; c++) {
+ if (*c == '.')
+ *c = '_';
+ }
+
+ value = hal_property_to_string (property);
+ env = g_strdup_printf ("HAL_PROP_%s=%s", prop_upper, value);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
+
+ g_free (env);
+ g_free (value);
+ g_free (prop_upper);
+
+ return TRUE;
+}
+
+static void
+add_env(DBusMessageIter *iter, const gchar *key, const gchar *value) {
+ gchar *env;
+ env = g_strdup_printf ("%s=%s", key, value);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
+ g_free(env);
+}
+
+static void
+add_basic_env(DBusMessageIter *iter, const gchar *udi) {
+ struct utsname un;
+ char *server_addr;
+
+ if (hald_is_verbose) {
+ add_env(iter, "HALD_VERBOSE", "1");
+ }
+ if (hald_is_initialising) {
+ add_env(iter, "HALD_STARTUP", "1");
+ }
+ if (hald_use_syslog) {
+ add_env(iter, "HALD_USE_SYSLOG", "1");
+ }
+ add_env(iter, "UDI", udi);
+ server_addr = hald_dbus_local_server_addr();
+ add_env(iter, "HALD_DIRECT_ADDR", server_addr);
+ dbus_free (server_addr);
+#ifdef HAVE_POLKIT
+ add_env(iter, "HAVE_POLKIT", "1");
+#endif
+
+ if (uname(&un) == 0) {
+ char *sysname;
+
+ sysname = g_ascii_strdown(un.sysname, -1);
+ add_env(iter, "HALD_UNAME_S", sysname);
+ g_free(sysname);
+ }
+}
+
+static void
+add_extra_env(DBusMessageIter *iter, gchar **env) {
+ int i;
+ if (env != NULL) for (i = 0; env[i] != NULL; i++) {
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env[i]);
+ }
+}
+
+static gboolean
+add_command(DBusMessageIter *iter, const gchar *command_line) {
+ gint argc;
+ gint x;
+ char **argv;
+ GError *err = NULL;
+ DBusMessageIter array_iter;
+
+ if (!g_shell_parse_argv(command_line, &argc, &argv, &err)) {
+ HAL_ERROR (("Error parsing commandline '%s': %s",
+ command_line, err->message));
+ g_error_free (err);
+ return FALSE;
+ }
+ if (!dbus_message_iter_open_container(iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &array_iter))
+ DIE (("No memory"));
+ for (x = 0 ; argv[x] != NULL; x++) {
+ dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &argv[x]);
+ }
+ dbus_message_iter_close_container(iter, &array_iter);
+
+ g_strfreev(argv);
+ return TRUE;
+}
+
+static gboolean
+add_first_part(DBusMessageIter *iter, HalDevice *device,
+ const gchar *command_line, char **extra_env) {
+ DBusMessageIter array_iter;
+ const char *udi;
+
+ udi = hal_device_get_udi(device);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &udi);
+
+ dbus_message_iter_open_container(iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &array_iter);
+ hal_device_property_foreach (device, add_property_to_msg, &array_iter);
+ add_basic_env(&array_iter, udi);
+ add_extra_env(&array_iter, extra_env);
+ dbus_message_iter_close_container(iter, &array_iter);
+
+ if (!add_command(iter, command_line)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Start a helper, returns true on a successfull start */
+gboolean
+hald_runner_start (HalDevice *device, const gchar *command_line, char **extra_env,
+ HalRunTerminatedCB cb, gpointer data1, gpointer data2)
+{
+ DBusMessage *msg, *reply;
+ DBusError err;
+ DBusMessageIter iter;
+
+ dbus_error_init(&err);
+ msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
+ "/org/freedesktop/HalRunner",
+ "org.freedesktop.HalRunner",
+ "Start");
+ if (msg == NULL)
+ DIE(("No memory"));
+ dbus_message_iter_init_append(msg, &iter);
+
+ if (!add_first_part(&iter, device, command_line, extra_env))
+ goto error;
+
+ /* Wait for the reply, should be almost instantanious */
+ reply =
+ dbus_connection_send_with_reply_and_block(runner_connection,
+ msg, -1, &err);
+ if (reply) {
+ gboolean ret =
+ (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);
+
+ if (ret) {
+ dbus_int64_t pid_from_runner;
+ if (dbus_message_get_args (reply, &err,
+ DBUS_TYPE_INT64, &pid_from_runner,
+ DBUS_TYPE_INVALID)) {
+ if (cb != NULL) {
+ RunningProcess *rp;
+ rp = g_new0 (RunningProcess, 1);
+ rp->pid = (GPid) pid_from_runner;
+ rp->cb = cb;
+ rp->device = device;
+ rp->data1 = data1;
+ rp->data2 = data2;
+
+ g_hash_table_insert (running_processes, (gpointer) rp->pid, rp);
+ }
+ } else {
+ HAL_ERROR (("Error extracting out_pid from runner's Start()"));
+ }
+ }
+
+ dbus_message_unref(reply);
+ dbus_message_unref(msg);
+ return ret;
+ }
+
+error:
+ dbus_message_unref(msg);
+ return FALSE;
+}
+
+static void
+call_notify(DBusPendingCall *pending, void *user_data)
+{
+ HelperData *hb = (HelperData *)user_data;
+ dbus_uint32_t exitt = HALD_RUN_SUCCESS;
+ dbus_int32_t return_code = 0;
+ DBusMessage *m;
+ GArray *error = NULL;
+ DBusMessageIter iter;
+
+ error = g_array_new(TRUE, FALSE, sizeof(char *));
+
+ m = dbus_pending_call_steal_reply(pending);
+ if (dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
+ goto malformed;
+
+ if (!dbus_message_iter_init(m, &iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
+ goto malformed;
+ dbus_message_iter_get_basic(&iter, &exitt);
+
+ if (!dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
+ goto malformed;
+ dbus_message_iter_get_basic(&iter, &return_code);
+
+ while (dbus_message_iter_next(&iter) &&
+ dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
+ const char *value;
+ dbus_message_iter_get_basic(&iter, &value);
+ g_array_append_vals(error, &value, 1);
+ }
+
+ hb->cb(hb->d, exitt, return_code,
+ (gchar **)error->data, hb->data1, hb->data2);
+
+ g_object_unref (hb->d);
+
+ dbus_message_unref(m);
+ dbus_pending_call_unref (pending);
+ g_array_free(error, TRUE);
+
+ return;
+malformed:
+ /* Send a Fail callback on malformed messages */
+ HAL_ERROR (("Malformed or unexpected reply message"));
+ hb->cb(hb->d, HALD_RUN_FAILED, return_code, NULL, hb->data1, hb->data2);
+
+ g_object_unref (hb->d);
+
+ dbus_message_unref(m);
+ dbus_pending_call_unref (pending);
+ g_array_free(error, TRUE);
+}
+
+/* Run a helper program using the commandline, with input as infomation on
+ * stdin */
+void
+hald_runner_run_method(HalDevice *device,
+ const gchar *command_line, char **extra_env,
+ gchar *input, gboolean error_on_stderr,
+ guint32 timeout,
+ HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2) {
+ DBusMessage *msg;
+ DBusMessageIter iter;
+ DBusPendingCall *call;
+ HelperData *hd = NULL;
+ msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
+ "/org/freedesktop/HalRunner",
+ "org.freedesktop.HalRunner",
+ "Run");
+ if (msg == NULL)
+ DIE(("No memory"));
+ dbus_message_iter_init_append(msg, &iter);
+
+ if (!add_first_part(&iter, device, command_line, extra_env))
+ goto error;
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &input);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &error_on_stderr);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &timeout);
+
+ if (!dbus_connection_send_with_reply(runner_connection,
+ msg, &call, INT_MAX))
+ DIE (("No memory"));
+
+ hd = malloc(sizeof(HelperData));
+ hd->d = device;
+ hd->cb = cb;
+ hd->data1 = data1;
+ hd->data2 = data2;
+
+ g_object_ref (device);
+
+ dbus_pending_call_set_notify(call, call_notify, hd, free);
+ dbus_message_unref(msg);
+ return;
+error:
+ dbus_message_unref(msg);
+ free(hd);
+ cb(device, HALD_RUN_FAILED, 0, NULL, data1, data2);
+}
+
+void
+hald_runner_run(HalDevice *device,
+ const gchar *command_line, char **extra_env,
+ guint timeout,
+ HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2) {
+ hald_runner_run_method(device, command_line, extra_env,
+ "", FALSE, timeout, cb, data1, data2);
+}
+
+
+
+void
+hald_runner_kill_device(HalDevice *device) {
+ DBusMessage *msg, *reply;
+ DBusError err;
+ DBusMessageIter iter;
+ const char *udi;
+
+ running_processes_remove_device (device);
+
+ msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
+ "/org/freedesktop/HalRunner",
+ "org.freedesktop.HalRunner",
+ "Kill");
+ if (msg == NULL)
+ DIE(("No memory"));
+ dbus_message_iter_init_append(msg, &iter);
+ udi = hal_device_get_udi(device);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &udi);
+
+ /* Wait for the reply, should be almost instantanious */
+ dbus_error_init(&err);
+ reply =
+ dbus_connection_send_with_reply_and_block(runner_connection, msg, -1, &err);
+ if (reply) {
+ dbus_message_unref(reply);
+ }
+
+ dbus_message_unref(msg);
+}
+
+void
+hald_runner_kill_all(HalDevice *device) {
+ DBusMessage *msg, *reply;
+ DBusError err;
+
+ running_processes_remove_device (device);
+
+ msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
+ "/org/freedesktop/HalRunner",
+ "org.freedesktop.HalRunner",
+ "KillAll");
+ if (msg == NULL)
+ DIE(("No memory"));
+
+ /* Wait for the reply, should be almost instantanious */
+ dbus_error_init(&err);
+ reply =
+ dbus_connection_send_with_reply_and_block(runner_connection,
+ msg, -1, &err);
+ if (reply) {
+ dbus_message_unref(reply);
+ }
+
+ dbus_message_unref(msg);
+}
diff --git a/usr/src/cmd/hal/hald/hald_runner.h b/usr/src/cmd/hal/hald/hald_runner.h
new file mode 100644
index 0000000000..ca055733c7
--- /dev/null
+++ b/usr/src/cmd/hal/hald/hald_runner.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ *
+ * CVSID: $Id$
+ *
+ * hald_runner.h - Interface to the hal runner helper daemon
+ *
+ * Copyright (C) 2006 Sjoerd Simons <sjoerd@luon.net>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef HALD_RUNNER_H
+#define HALD_RUNNER_H
+
+#include "device.h"
+
+/* Successful run of the program */
+#define HALD_RUN_SUCCESS 0x0
+/* Process was killed because of running too long */
+#define HALD_RUN_TIMEOUT 0x1
+/* Failed to start for some reason */
+#define HALD_RUN_FAILED 0x2
+/* Killed on purpose, e.g. hal_runner_kill_device */
+#define HALD_RUN_KILLED 0x4
+
+/* Default sane timeout */
+#define HAL_HELPER_TIMEOUT 10000
+
+typedef void (*HalRunTerminatedCB) (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2);
+
+/* Start the runner daemon */
+gboolean
+hald_runner_start_runner(void);
+
+/* Start a helper, returns true on a successfull start.
+ * cb will be called on abnormal or premature termination
+ * only
+ */
+gboolean
+hald_runner_start (HalDevice *device, const gchar *command_line, char **extra_env,
+ HalRunTerminatedCB cb, gpointer data1, gpointer data2);
+
+/* Run a helper program using the commandline, with input as infomation on
+ * stdin */
+void
+hald_runner_run(HalDevice *device,
+ const gchar *command_line, char **extra_env,
+ guint32 timeout,
+ HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2);
+void
+hald_runner_run_method(HalDevice *device,
+ const gchar *command_line, char **extra_env,
+ gchar *input, gboolean error_on_stderr,
+ guint32 timeout,
+ HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2);
+
+void hald_runner_kill_device(HalDevice *device);
+void hald_runner_kill_all();
+
+/* called by the core to tell the runner a device was finalized */
+void runner_device_finalized (HalDevice *device);
+
+#endif
diff --git a/usr/src/cmd/hal/hald/ids.c b/usr/src/cmd/hal/hald/ids.c
new file mode 100644
index 0000000000..f1fbf54658
--- /dev/null
+++ b/usr/src/cmd/hal/hald/ids.c
@@ -0,0 +1,996 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * ids.c : Lookup names from hardware identifiers
+ *
+ * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
+#include "logger.h"
+
+#include "ids.h"
+
+/** Pointer to where the pci.ids file is loaded */
+static char *pci_ids = NULL;
+
+/** Length of data store at at pci_ids */
+static unsigned int pci_ids_len;
+
+/** Iterator position into pci_ids */
+static unsigned int pci_ids_iter_pos;
+
+/** Initialize the pci.ids line iterator to the beginning of the file */
+static void
+pci_ids_line_iter_init ()
+{
+ pci_ids_iter_pos = 0;
+}
+
+/** Maximum length of lines in pci.ids */
+#define PCI_IDS_MAX_LINE_LEN 512
+
+/** Get the next line from pci.ids
+ *
+ * @param line_len Pointer to where number of bytes in line will
+ * be stored
+ * @return Pointer to the line; only valid until the
+ * next invocation of this function
+ */
+static char *
+pci_ids_line_iter_get_line (unsigned int *line_len)
+{
+ unsigned int i;
+ static char line[PCI_IDS_MAX_LINE_LEN];
+
+ for (i = 0;
+ pci_ids_iter_pos < pci_ids_len &&
+ i < PCI_IDS_MAX_LINE_LEN - 1 &&
+ pci_ids[pci_ids_iter_pos] != '\n'; i++, pci_ids_iter_pos++) {
+ line[i] = pci_ids[pci_ids_iter_pos];
+ }
+
+ line[i] = '\0';
+ if (line_len != NULL)
+ *line_len = i;
+
+ pci_ids_iter_pos++;
+
+ return line;
+}
+
+/** See if there are more lines to process in pci.ids
+ *
+ * @return #TRUE iff there are more lines to process
+ */
+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
+ * function.
+ *
+ * @param vendor_id PCI vendor id or 0 if unknown
+ * @param product_id PCI product id or 0 if unknown
+ * @param subsys_vendor_id PCI subsystem vendor id or 0 if unknown
+ * @param subsys_product_id PCI subsystem product id or 0 if unknown
+ * @param vendor_name Set to pointer of result or NULL
+ * @param product_name Set to pointer of result or NULL
+ * @param subsys_vendor_name Set to pointer of result or NULL
+ * @param subsys_product_name Set to pointer of result or NULL
+ */
+void
+ids_find_pci (int vendor_id, int product_id,
+ int subsys_vendor_id, int subsys_product_id,
+ char **vendor_name, char **product_name,
+ char **subsys_vendor_name, char **subsys_product_name)
+{
+ char *line;
+ unsigned int i;
+ unsigned int line_len;
+ unsigned int num_tabs;
+ char rep_vi[8];
+ char rep_pi[8];
+ char rep_svi[8];
+ char rep_spi[8];
+ dbus_bool_t vendor_matched = FALSE;
+ dbus_bool_t product_matched = FALSE;
+ static char store_vn[PCI_IDS_MAX_LINE_LEN];
+ static char store_pn[PCI_IDS_MAX_LINE_LEN];
+ static char store_svn[PCI_IDS_MAX_LINE_LEN];
+ static char store_spn[PCI_IDS_MAX_LINE_LEN];
+
+ snprintf (rep_vi, 8, "%04x", vendor_id);
+ snprintf (rep_pi, 8, "%04x", product_id);
+ snprintf (rep_svi, 8, "%04x", subsys_vendor_id);
+ snprintf (rep_spi, 8, "%04x", subsys_product_id);
+
+ *vendor_name = NULL;
+ *product_name = NULL;
+ *subsys_vendor_name = NULL;
+ *subsys_product_name = NULL;
+
+ for (pci_ids_line_iter_init (); pci_ids_line_iter_has_more ();) {
+ line = pci_ids_line_iter_get_line (&line_len);
+
+ /* skip lines with no content */
+ if (line_len < 4)
+ continue;
+
+ /* skip comments */
+ if (line[0] == '#')
+ continue;
+
+ /* count number of tabs */
+ num_tabs = 0;
+ for (i = 0; i < line_len; i++) {
+ if (line[i] != '\t')
+ break;
+ num_tabs++;
+ }
+
+ switch (num_tabs) {
+ case 0:
+ /* vendor names */
+ vendor_matched = FALSE;
+
+ /* first check subsys_vendor_id, if haven't done
+ * already */
+ if (*subsys_vendor_name == NULL
+ && subsys_vendor_id != 0) {
+ if ((*((dbus_uint32_t *) line)) ==
+ (*((dbus_uint32_t *) rep_svi))) {
+ /* found it */
+ for (i = 4; i < line_len; i++) {
+ if (!isspace (line[i]))
+ break;
+ }
+ strncpy (store_svn, line + i,
+ PCI_IDS_MAX_LINE_LEN);
+ *subsys_vendor_name = store_svn;
+ }
+ }
+
+ /* check vendor_id */
+ if (vendor_id != 0) {
+ if (memcmp (line, rep_vi, 4) == 0) {
+ /* found it */
+ vendor_matched = TRUE;
+
+ for (i = 4; i < line_len; i++) {
+ if (!isspace (line[i]))
+ break;
+ }
+ strncpy (store_vn, line + i,
+ PCI_IDS_MAX_LINE_LEN);
+ *vendor_name = store_vn;
+ }
+ }
+
+ break;
+
+ case 1:
+ product_matched = FALSE;
+
+ /* product names */
+ if (!vendor_matched)
+ continue;
+
+ /* check product_id */
+ if (product_id != 0) {
+ if (memcmp (line + 1, rep_pi, 4) == 0) {
+ /* found it */
+
+ product_matched = TRUE;
+
+ for (i = 5; i < line_len; i++) {
+ if (!isspace (line[i]))
+ break;
+ }
+ strncpy (store_pn, line + i,
+ PCI_IDS_MAX_LINE_LEN);
+ *product_name = store_pn;
+ }
+ }
+ break;
+
+ case 2:
+ /* subsystem_vendor subsystem_product */
+ if (!vendor_matched || !product_matched)
+ continue;
+
+ /* check product_id */
+ if (subsys_vendor_id != 0
+ && subsys_product_id != 0) {
+ if (memcmp (line + 2, rep_svi, 4) == 0
+ && memcmp (line + 7, rep_spi,
+ 4) == 0) {
+ /* found it */
+ for (i = 11; i < line_len; i++) {
+ if (!isspace (line[i]))
+ break;
+ }
+ strncpy (store_spn, line + i,
+ PCI_IDS_MAX_LINE_LEN);
+ *subsys_product_name = store_spn;
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ }
+}
+
+/** Free resources used by to store the PCI database
+ *
+ * @param #FALSE if the PCI database wasn't loaded
+ */
+static dbus_bool_t
+pci_ids_free ()
+{
+ if (pci_ids != NULL) {
+ free (pci_ids);
+ pci_ids = NULL;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/** Load the PCI database used for mapping vendor, product, subsys_vendor
+ * and subsys_product numbers into names.
+ *
+ * @param path Path of the pci.ids file, e.g.
+ * /usr/share/hwdata/pci.ids
+ * @return #TRUE if the file was succesfully loaded
+ */
+static dbus_bool_t
+pci_ids_load (const char *path)
+{
+ FILE *fp;
+ unsigned int num_read;
+
+ fp = fopen (path, "r");
+ if (fp == NULL) {
+ HAL_ERROR (("couldn't open PCI database at %s,", path));
+ return FALSE;
+ }
+
+ fseek (fp, 0, SEEK_END);
+ pci_ids_len = ftell (fp);
+ fseek (fp, 0, SEEK_SET);
+
+ pci_ids = malloc (pci_ids_len);
+ if (pci_ids == NULL) {
+ DIE (("Couldn't allocate %d bytes for PCI database file\n",
+ pci_ids_len));
+ }
+
+ num_read = fread (pci_ids, sizeof (char), pci_ids_len, fp);
+ if (pci_ids_len != num_read) {
+ HAL_ERROR (("Error loading PCI database file"));
+ pci_ids_free();
+ fclose(fp);
+ return FALSE;
+ }
+
+ fclose(fp);
+ return TRUE;
+}
+
+/*==========================================================================*/
+
+/** Pointer to where the usb.ids file is loaded */
+static char *usb_ids = NULL;
+
+/** Length of data store at at usb_ids */
+static unsigned int usb_ids_len;
+
+/** Iterator position into usb_ids */
+static unsigned int usb_ids_iter_pos;
+
+/** Initialize the usb.ids line iterator to the beginning of the file */
+static void
+usb_ids_line_iter_init ()
+{
+ usb_ids_iter_pos = 0;
+}
+
+/** Maximum length of lines in usb.ids */
+#define USB_IDS_MAX_LINE_LEN 512
+
+/** Get the next line from usb.ids
+ *
+ * @param line_len Pointer to where number of bytes in line will
+ * be stored
+ * @return Pointer to the line; only valid until the
+ * next invocation of this function
+ */
+static char *
+usb_ids_line_iter_get_line (unsigned int *line_len)
+{
+ unsigned int i;
+ static char line[USB_IDS_MAX_LINE_LEN];
+
+ for (i = 0;
+ usb_ids_iter_pos < usb_ids_len &&
+ i < USB_IDS_MAX_LINE_LEN - 1 &&
+ usb_ids[usb_ids_iter_pos] != '\n'; i++, usb_ids_iter_pos++) {
+ line[i] = usb_ids[usb_ids_iter_pos];
+ }
+
+ line[i] = '\0';
+ if (line_len != NULL)
+ *line_len = i;
+
+ usb_ids_iter_pos++;
+
+ return line;
+}
+
+/** See if there are more lines to process in usb.ids
+ *
+ * @return #TRUE iff there are more lines to process
+ */
+static dbus_bool_t
+usb_ids_line_iter_has_more ()
+{
+ return usb_ids_iter_pos < usb_ids_len;
+}
+
+/** Find the names for a USB device.
+ *
+ * The pointers returned are only valid until the next invocation of this
+ * function.
+ *
+ * @param vendor_id USB vendor id or 0 if unknown
+ * @param product_id USB product id or 0 if unknown
+ * @param vendor_name Set to pointer of result or NULL
+ * @param product_name Set to pointer of result or NULL
+ */
+void
+ids_find_usb (int vendor_id, int product_id,
+ char **vendor_name, char **product_name)
+{
+ char *line;
+ unsigned int i;
+ unsigned int line_len;
+ unsigned int num_tabs;
+ char rep_vi[8];
+ char rep_pi[8];
+ static char store_vn[USB_IDS_MAX_LINE_LEN];
+ static char store_pn[USB_IDS_MAX_LINE_LEN];
+ dbus_bool_t vendor_matched = FALSE;
+
+ snprintf (rep_vi, 8, "%04x", vendor_id);
+ snprintf (rep_pi, 8, "%04x", product_id);
+
+ *vendor_name = NULL;
+ *product_name = NULL;
+
+ for (usb_ids_line_iter_init (); usb_ids_line_iter_has_more ();) {
+ line = usb_ids_line_iter_get_line (&line_len);
+
+ /* skip lines with no content */
+ if (line_len < 4)
+ continue;
+
+ /* skip comments */
+ if (line[0] == '#')
+ continue;
+
+ /* count number of tabs */
+ num_tabs = 0;
+ for (i = 0; i < line_len; i++) {
+ if (line[i] != '\t')
+ break;
+ num_tabs++;
+ }
+
+ switch (num_tabs) {
+ case 0:
+ /* vendor names */
+ vendor_matched = FALSE;
+
+ /* check vendor_id */
+ if (vendor_id != 0) {
+ if (memcmp (line, rep_vi, 4) == 0) {
+ /* found it */
+ vendor_matched = TRUE;
+
+ for (i = 4; i < line_len; i++) {
+ if (!isspace (line[i]))
+ break;
+ }
+ strncpy (store_vn, line + i,
+ USB_IDS_MAX_LINE_LEN);
+ *vendor_name = store_vn;
+ }
+ }
+ break;
+
+ case 1:
+ /* product names */
+ if (!vendor_matched)
+ continue;
+
+ /* check product_id */
+ if (product_id != 0) {
+ if (memcmp (line + 1, rep_pi, 4) == 0) {
+ /* found it */
+ for (i = 5; i < line_len; i++) {
+ if (!isspace (line[i]))
+ break;
+ }
+ strncpy (store_pn, line + i,
+ USB_IDS_MAX_LINE_LEN);
+ *product_name = store_pn;
+
+ /* no need to continue the search */
+ return;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ }
+}
+
+/** Free resources used by to store the USB database
+ *
+ * @param #FALSE if the USB database wasn't loaded
+ */
+static dbus_bool_t
+usb_ids_free ()
+{
+ if (usb_ids != NULL) {
+ free (usb_ids);
+ usb_ids = NULL;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/** Load the USB database used for mapping vendor, product, subsys_vendor
+ * and subsys_product numbers into names.
+ *
+ * @param path Path of the usb.ids file, e.g.
+ * /usr/share/hwdata/usb.ids
+ * @return #TRUE if the file was succesfully loaded
+ */
+static dbus_bool_t
+usb_ids_load (const char *path)
+{
+ FILE *fp;
+ unsigned int num_read;
+
+ fp = fopen (path, "r");
+ if (fp == NULL) {
+ printf ("couldn't open USB database at %s,", path);
+ return FALSE;
+ }
+
+ fseek (fp, 0, SEEK_END);
+ usb_ids_len = ftell (fp);
+ fseek (fp, 0, SEEK_SET);
+
+ usb_ids = malloc (usb_ids_len);
+ if (usb_ids == NULL) {
+ printf
+ ("Couldn't allocate %d bytes for USB database file\n",
+ usb_ids_len);
+ fclose(fp);
+ return FALSE;
+ }
+
+ num_read = fread (usb_ids, sizeof (char), usb_ids_len, fp);
+ if (usb_ids_len != num_read) {
+ printf ("Error loading USB database file\n");
+ usb_ids_free ();
+ fclose(fp);
+ return FALSE;
+ }
+
+ fclose(fp);
+ return TRUE;
+}
+
+
+void
+ids_init (void)
+{
+ /* Load /usr/share/hwdata/pci.ids */
+ pci_ids_load (HWDATA_DIR "/pci.ids");
+
+ /* Load /usr/share/hwdata/usb.ids */
+ usb_ids_load (HWDATA_DIR "/usb.ids");
+}
+
+
+/* This, somewhat incomplete, list is from this sources:
+ * http://www.plasma-online.de/english/identify/serial/pnp_id_pnp.html
+ * http://www-pc.uni-regensburg.de/hardware/TECHNIK/PCI_PNP/pnpid.txt
+ *
+ * Keep this sorted!
+ */
+struct pnp_id {
+ char *id;
+ char *desc;
+} static pnp_ids_list[] = {
+ /* Crystal Semiconductor devices */
+ {"CSC0000", "Crystal Semiconductor CS423x sound -- SB/WSS/OPL3 emulation"},
+ {"CSC0001", "Crystal Semiconductor CS423x sound -- joystick"},
+ {"CSC0003", "Crystal Semiconductor CS423x sound -- MPU401"},
+ {"CSC0010", "Crystal Semiconductor CS423x sound -- control"},
+ /* IBM devices */
+ {"IBM0071", "IBM infrared communications device"},
+ {"IBM3760", "IBM DSP"},
+ {"IBM3780", "IBM pointing device"},
+ /* FinePoint devices */
+ {"FPI2004", "FinePoint Innovations Tablet"},
+ /* Fujitsu (Siemens Computers) devices */
+ {"FUJ02E5", "Wacom Serial Pen HID Tablet"},
+ {"FUJ02E6", "Fujitsu Serial TouchScreen"},
+ /* interrupt controllers */
+ {"PNP0000", "AT Interrupt Controller"},
+ {"PNP0001", "EISA Interrupt Controller"},
+ {"PNP0002", "MCA Interrupt Controller"},
+ {"PNP0003", "APIC"},
+ {"PNP0004", "Cyrix SLiC MP interrupt controller"},
+ /* timers */
+ {"PNP0100", "AT Timer"},
+ {"PNP0101", "EISA Timer"},
+ {"PNP0102", "MCA Timer"},
+ /* DMA controllers */
+ {"PNP0200", "AT DMA Controller"},
+ {"PNP0201", "EISA DMA Controller"},
+ {"PNP0202", "MCA DMA Controller"},
+ /* keyboards */
+ {"PNP0300", "IBM PC/XT keyboard controller (83-key)"},
+ {"PNP0301", "IBM PC/AT keyboard controller (86-key)"},
+ {"PNP0302", "IBM PC/XT keyboard controller (84-key)"},
+ {"PNP0303", "IBM Enhanced (101/102-key, PS/2 mouse support)"},
+ {"PNP0304", "Olivetti Keyboard (83-key)"},
+ {"PNP0305", "Olivetti Keyboard (102-key)"},
+ {"PNP0306", "Olivetti Keyboard (86-key)"},
+ {"PNP0307", "Microsoft Windows(R) Keyboard"},
+ {"PNP0308", "General Input Device Emulation Interface (GIDEI) legacy"},
+ {"PNP0309", "Olivetti Keyboard (A101/102 key)"},
+ {"PNP030A", "AT&T 302 keyboard"},
+ {"PNP030B", "Reserved by Microsoft"},
+ {"PNP0320", "Japanese 101-key keyboard"},
+ {"PNP0321", "Japanese AX keyboard"},
+ {"PNP0322", "Japanese 106-key keyboard A01"},
+ {"PNP0323", "Japanese 106-key keyboard 002/003"},
+ {"PNP0324", "Japanese 106-key keyboard 001"},
+ {"PNP0325", "Japanese Toshiba Desktop keyboard"},
+ {"PNP0326", "Japanese Toshiba Laptop keyboard"},
+ {"PNP0327", "Japanese Toshiba Notebook keyboard"},
+ {"PNP0340", "Korean 84-key keyboard"},
+ {"PNP0341", "Korean 86-key keyboard"},
+ {"PNP0342", "Korean Enhanced keyboard"},
+ {"PNP0343", "Korean Enhanced keyboard 101b"},
+ {"PNP0343", "Korean Enhanced keyboard 101c"},
+ {"PNP0344", "Korean Enhanced keyboard 103"},
+ /* parallel ports */
+ {"PNP0400", "Standard LPT printer port"},
+ {"PNP0401", "ECP printer port"},
+ /* serial ports */
+ {"PNP0500", "Standard PC COM port"},
+ {"PNP0501", "16550A-compatible COM port"},
+ {"PNP0502", "Multiport serial device (non-intelligent 16550)"},
+ {"PNP0510", "Generic IRDA-compatible device"},
+ {"PNP0511", "Generic IRDA-compatible device"},
+ /* IDE controller */
+ {"PNP0600", "Generic ESDI/IDE/ATA compatible hard disk controller"},
+ {"PNP0601", "Plus Hardcard II"},
+ {"PNP0602", "Plus Hardcard IIXL/EZ"},
+ {"PNP0603", "Generic IDE supporting Microsoft Device Bay Specification"},
+ {"PNP0604", "PC standard floppy disk controller"},
+ {"PNP0605", "HP Omnibook floppy disk controller"},
+ {"PNP0680", "Bus Master E-IDE controller"},
+ {"PNP0700", "PC standard floppy disk controller"},
+ {"PNP0701", "Standard floppy controller supporting MS Device Bay Spec"},
+ /* system devices */
+ {"PNP0800", "AT-style speaker sound"},
+ /* obsolete devices */
+ {"PNP0802", "Microsoft Sound System compatible device (obsolete, use PNPB0xx instead)"},
+ /* display adapters / graphic cards */
+ {"PNP0900", "VGA Compatible"},
+ {"PNP0901", "Video Seven VRAM/VRAM II/1024i"},
+ {"PNP0902", "IBM 8514/A Compatible"},
+ {"PNP0903", "Trident VGA"},
+ {"PNP0904", "Cirrus Logic Laptop VGA"},
+ {"PNP0905", "Cirrus Logic VGA"},
+ {"PNP0906", "Tseng Labs ET4000"},
+ {"PNP0907", "Western Digital VGA"},
+ {"PNP0908", "Western Digital Laptop VGA"},
+ {"PNP0909", "S3 Inc. 911/924"},
+ {"PNP090A", "ATI Ultra Pro/Plus (Mach 32)"},
+ {"PNP090B", "ATI Ultra (Mach 8)"},
+ {"PNP090C", "IBM XGA Compatible"},
+ {"PNP090D", "ATI VGA Wonder"},
+ {"PNP090E", "Weitek P9000 Graphics Adapter"},
+ {"PNP090F", "Oak Technology VGA"},
+ {"PNP0910", "Compaq QVision"},
+ {"PNP0911", "IBM XGA/2"},
+ {"PNP0912", "Tseng Labs ET4000 W32/W32i/W32p"},
+ {"PNP0913", "S3 Inc. 801/928/964"},
+ {"PNP0914", "Cirrus Logic 5429/5434 (memory mapped)"},
+ {"PNP0915", "Compaq Advanced VGA (AVGA)"},
+ {"PNP0916", "ATI Ultra Pro Turbo (Mach64)"},
+ {"PNP0917", "Reserved by Microsoft"},
+ {"PNP0918", "Matrox MGA"},
+ {"PNP0919", "Compaq QVision 2000"},
+ {"PNP091A", "Tseng Labs W128"},
+ {"PNP0930", "Chips & Technologies Super VGA"},
+ {"PNP0931", "Chips & Technologies Accelerator"},
+ {"PNP0940", "NCR 77c22e Super VGA"},
+ {"PNP0941", "NCR 77c32blt"},
+ {"PNP09FF", "Plug and Play Monitors (VESA DDC)"},
+ /* peripheral buses */
+ {"PNP0A00", "ISA Bus"},
+ {"PNP0A01", "EISA Bus"},
+ {"PNP0A02", "MCA Bus"},
+ {"PNP0A03", "PCI Bus"},
+ {"PNP0A04", "VESA/VL Bus"},
+ {"PNP0A05", "Generic ACPI Bus"},
+ {"PNP0A06", "Generic ACPI Extended-IO Bus (EIO bus)"},
+ /* system devices */
+ {"PNP0B00", "AT Real-Time Clock"},
+ {"PNP0C00", "Plug and Play BIOS (only created by the root enumerator)"},
+ {"PNP0C01", "System Board"},
+ {"PNP0C02", "General ID for reserving resources required by PnP motherboard registers. (Not device specific.)"},
+ {"PNP0C03", "Plug and Play BIOS Event Notification Interrupt"},
+ {"PNP0C04", "Math Coprocessor"},
+ {"PNP0C05", "APM BIOS (Version independent)"},
+ {"PNP0C06", "Reserved for identification of early Plug and Play BIOS implementation"},
+ {"PNP0C07", "Reserved for identification of early Plug and Play BIOS implementation"},
+ {"PNP0C08", "ACPI system board hardware"},
+ {"PNP0C09", "ACPI Embedded Controller"},
+ {"PNP0C0A", "ACPI Control Method Battery"},
+ {"PNP0C0B", "ACPI Fan"},
+ {"PNP0C0C", "ACPI power button device"},
+ {"PNP0C0D", "ACPI lid device"},
+ {"PNP0C0E", "ACPI sleep button device"},
+ {"PNP0C0F", "PCI interrupt link device"},
+ {"PNP0C10", "ACPI system indicator device"},
+ {"PNP0C11", "ACPI thermal zone"},
+ {"PNP0C12", "Device Bay Controller"},
+ {"PNP0C13", "Plug and Play BIOS (used when ACPI mode cannot be used)"},
+ {"PNP0CF0", "Compaq LTE Lite Support"},
+ {"PNP0CF1", "Compaq LTE Elite Support"},
+ /* PCMCIA controllers */
+ {"PNP0E00", "Intel 82365-Compatible PCMCIA Controller"},
+ {"PNP0E01", "Cirrus Logic CL-PD6720 PCMCIA Controller"},
+ {"PNP0E02", "VLSI VL82C146 PCMCIA Controller"},
+ {"PNP0E03", "Intel 82365-compatible CardBus controller"},
+ /* mice */
+ {"PNP0F00", "Microsoft Bus Mouse"},
+ {"PNP0F01", "Microsoft Serial Mouse"},
+ {"PNP0F02", "Microsoft InPort Mouse"},
+ {"PNP0F03", "Microsoft PS/2-style Mouse"},
+ {"PNP0F04", "Mouse Systems Mouse"},
+ {"PNP0F05", "Mouse Systems 3-Button Mouse (COM2)"},
+ {"PNP0F06", "Genius Mouse (COM1)"},
+ {"PNP0F07", "Genius Mouse (COM2)"},
+ {"PNP0F08", "Logitech Serial Mouse"},
+ {"PNP0F09", "Microsoft BallPoint Serial Mouse"},
+ {"PNP0F0A", "Microsoft Plug and Play Mouse"},
+ {"PNP0F0B", "Microsoft Plug and Play BallPoint Mouse"},
+ {"PNP0F0C", "Microsoft-compatible Serial Mouse"},
+ {"PNP0F0D", "Microsoft-compatible InPort-compatible Mouse"},
+ {"PNP0F0E", "Microsoft-compatible PS/2-style Mouse"},
+ {"PNP0F0F", "Microsoft-compatible Serial BallPoint-compatible Mouse"},
+ {"PNP0F10", "Texas Instruments QuickPort Mouse"},
+ {"PNP0F11", "Microsoft-compatible Bus Mouse"},
+ {"PNP0F12", "Logitech PS/2-style Mouse"},
+ {"PNP0F13", "PS/2 Port for PS/2-style Mice"},
+ {"PNP0F14", "Microsoft Kids Mouse"},
+ {"PNP0F15", "Logitech bus mouse"},
+ {"PNP0F16", "Logitech SWIFT device"},
+ {"PNP0F17", "Logitech-compatible serial mouse"},
+ {"PNP0F18", "Logitech-compatible bus mouse"},
+ {"PNP0F19", "Logitech-compatible PS/2-style Mouse"},
+ {"PNP0F1A", "Logitech-compatible SWIFT Device"},
+ {"PNP0F1B", "HP Omnibook Mouse"},
+ {"PNP0F1C", "Compaq LTE Trackball PS/2-style Mouse"},
+ {"PNP0F1D", "Compaq LTE Trackball Serial Mouse"},
+ {"PNP0F1E", "Microsoft Kids Trackball Mouse"},
+ {"PNP0F1F", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F20", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F21", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F22", "Reserved by Microsoft Input Device Group"},
+ {"PNP0F23", "Reserved by Microsoft Input Device Group"},
+ {"PNP0FFF", "Reserved by Microsoft Systems"},
+ {"PNP0XXX", "Unknown System Device"},
+ /* network cards */
+ {"PNP8000", "Network Adapter"},
+ {"PNP8001", "Novell/Anthem NE3200"},
+ {"PNP8004", "Compaq NE3200"},
+ {"PNP8006", "Intel EtherExpress/32"},
+ {"PNP8008", "HP EtherTwist EISA LAN Adapter/32 (HP27248A)"},
+ {"PNP8065", "Ungermann-Bass NIUps or NIUps/EOTP"},
+ {"PNP8072", "DEC (DE211) EtherWorks MC/TP"},
+ {"PNP8073", "DEC (DE212) EtherWorks MC/TP_BNC"},
+ {"PNP8074", "HP MC LAN Adapter/16 TP (PC27246)"},
+ {"PNP8078", "DCA 10 Mb MCA"},
+ {"PNP807F", "Racal NI9210"},
+ {"PNP8081", "Pure Data Ethernet"},
+ {"PNP8096", "Thomas-Conrad TC4046"},
+ {"PNP80C9", "IBM Token Ring"},
+ {"PNP80CA", "IBM Token Ring II"},
+ {"PNP80CB", "IBM Token Ring II/Short"},
+ {"PNP80CC", "IBM Token Ring 4/16Mbs"},
+ {"PNP80D3", "Novell/Anthem NE1000"},
+ {"PNP80D4", "Novell/Anthem NE2000"},
+ {"PNP80D5", "NE1000 Compatible"},
+ {"PNP80D6", "NE2000 Compatible"},
+ {"PNP80D7", "Novell/Anthem NE1500T"},
+ {"PNP80D8", "Novell/Anthem NE2100"},
+ {"PNP80D9", "NE2000 Plus"},
+ {"PNP80DD", "SMC ARCNETPC"},
+ {"PNP80DE", "SMC ARCNET PC100, PC200"},
+ {"PNP80DF", "SMC ARCNET PC110, PC210, PC250"},
+ {"PNP80E0", "SMC ARCNET PC130/E"},
+ {"PNP80E1", "SMC ARCNET PC120, PC220, PC260"},
+ {"PNP80E2", "SMC ARCNET PC270/E"},
+ {"PNP80E5", "SMC ARCNET PC600W, PC650W"},
+ {"PNP80E7", "DEC DEPCA"},
+ {"PNP80E8", "DEC (DE100) EtherWorks LC"},
+ {"PNP80E9", "DEC (DE200) EtherWorks Turbo"},
+ {"PNP80EA", "DEC (DE101) EtherWorks LC/TP"},
+ {"PNP80EB", "DEC (DE201) EtherWorks Turbo/TP"},
+ {"PNP80EC", "DEC (DE202) EtherWorks Turbo/TP_BNC"},
+ {"PNP80ED", "DEC (DE102) EtherWorks LC/TP_BNC"},
+ {"PNP80EE", "DEC EE101 (Built-In)"},
+ {"PNP80EF", "DEC PC 433 WS (Built-In)"},
+ {"PNP80F1", "3Com EtherLink Plus"},
+ {"PNP80F3", "3Com EtherLink II or IITP (8 or 16-bit)"},
+ {"PNP80F4", "3Com TokenLink"},
+ {"PNP80F6", "3Com EtherLink 16"},
+ {"PNP80F7", "3Com EtherLink III"},
+ {"PNP80F8", "3Com Generic Etherlink Plug and Play Device"},
+ {"PNP80FB", "Thomas Conrad TC6045"},
+ {"PNP80FC", "Thomas Conrad TC6042"},
+ {"PNP80FD", "Thomas Conrad TC6142"},
+ {"PNP80FE", "Thomas Conrad TC6145"},
+ {"PNP80FF", "Thomas Conrad TC6242"},
+ {"PNP8100", "Thomas Conrad TC6245"},
+ {"PNP8101", "Thomas-Conrad TC4045"},
+ {"PNP8104", "Thomas-Conrad TC4035"},
+ {"PNP8105", "DCA 10 MB"},
+ {"PNP8106", "DCA 10 MB Fiber Optic"},
+ {"PNP8107", "DCA 10 MB Twisted Pair"},
+ {"PNP8113", "Racal NI6510"},
+ {"PNP8114", "Racal NI5210/8 or NI5210/16"},
+ {"PNP8119", "Ungermann-Bass pcNIU"},
+ {"PNP811A", "Ungermann-Bass pcNIU/ex 128K"},
+ {"PNP811B", "Ungermann-Bass pcNIU/ex 512K"},
+ {"PNP811C", "Ungermann-Bass NIUpc"},
+ {"PNP811D", "Ungermann-Bass NIUpc/3270"},
+ {"PNP8120", "Ungermann-Bass NIUpc/EOTP"},
+ {"PNP8123", "SMC StarCard PLUS (WD/8003S)"},
+ {"PNP8124", "SMC StarCard PLUS With On Board Hub (WD/8003SH)"},
+ {"PNP8125", "SMC EtherCard PLUS (WD/8003E)"},
+ {"PNP8126", "SMC EtherCard PLUS With Boot ROM Socket (WD/8003EBT)"},
+ {"PNP8127", "SMC EtherCard PLUS With Boot ROM Socket (WD/8003EB)"},
+ {"PNP8128", "SMC EtherCard PLUS TP (WD/8003WT)"},
+ {"PNP812A", "SMC EtherCard PLUS 16 With Boot ROM Socket (WD/8013EBT)"},
+ {"PNP812D", "Intel EtherExpress 16 or 16TP"},
+ {"PNP812F", "Intel TokenExpress 16/4"},
+ {"PNP8130", "Intel TokenExpress MCA 16/4"},
+ {"PNP8132", "Intel EtherExpress 16 (MCA)"},
+ {"PNP8133", "Compaq Ethernet 16E"},
+ {"PNP8137", "Artisoft AE-1"},
+ {"PNP8138", "Artisoft AE-2 or AE-3"},
+ {"PNP8141", "Amplicard AC 210/XT"},
+ {"PNP8142", "Amplicard AC 210/AT"},
+ {"PNP814B", "Everex SpeedLink /PC16 (EV2027)"},
+ {"PNP8155", "HP PC LAN Adapter/8 TP (HP27245)"},
+ {"PNP8156", "HP PC LAN Adapter/16 TP (HP27247A)"},
+ {"PNP8157", "HP PC LAN Adapter/8 TL (HP27250)"},
+ {"PNP8158", "HP PC LAN Adapter/16 TP Plus (HP27247B)"},
+ {"PNP8159", "HP PC LAN Adapter/16 TL Plus (HP27252)"},
+ {"PNP815F", "National Semiconductor Ethernode *16AT"},
+ {"PNP8160", "National Semiconductor AT/LANTIC EtherNODE 16-AT3"},
+ {"PNP8169", "NCR StarCard"},
+ {"PNP816A", "NCR Token-Ring 4 Mbs ISA"},
+ {"PNP816B", "NCR WaveLAN AT"},
+ {"PNP816C", "NCR WaveLan MC"},
+ {"PNP816D", "NCR Token-Ring 16/4 Mbs ISA"},
+ {"PNP8191", "Olicom 16/4 Token-Ring Adapter"},
+ {"PNP81A5", "Research Machines Ethernet"},
+ {"PNP81B9", "ToshibaLAN (internal)"},
+ {"PNP81C3", "SMC EtherCard PLUS Elite (WD/8003EP)"},
+ {"PNP81C4", "SMC EtherCard PLUS 10T (WD/8003W)"},
+ {"PNP81C5", "SMC EtherCard PLUS Elite 16 (WD/8013EP)"},
+ {"PNP81C6", "SMC EtherCard PLUS Elite 16T (WD/8013W)"},
+ {"PNP81C7", "SMC EtherCard PLUS Elite 16 Combo (WD/8013EW or 8013EWC)"},
+ {"PNP81C8", "SMC EtherElite Ultra 16"},
+ {"PNP81C9", "SMC TigerCard (8216L, 8216LC, 8216LT)"},
+ {"PNP81CA", "SMC EtherEZ (8416)"},
+ {"PNP81D7", "Madge Smart 16/4 PC Ringnode"},
+ {"PNP81D8", "Madge Smart 16/4 Ringnode ISA"},
+ {"PNP81E4", "Pure Data PDI9025-32 (Token Ring)"},
+ {"PNP81E6", "Pure Data PDI508+ (ArcNet)"},
+ {"PNP81E7", "Pure Data PDI516+ (ArcNet)"},
+ {"PNP81EB", "Proteon Token Ring (P1390)"},
+ {"PNP81EC", "Proteon Token Ring (P1392)"},
+ {"PNP81ED", "Proteon Token Ring ISA (P1340)"},
+ {"PNP81EE", "Proteon Token Ring ISA (P1342)"},
+ {"PNP81EF", "Proteon Token Ring ISA (P1346)"},
+ {"PNP81F0", "Proteon Token Ring ISA (P1347)"},
+ {"PNP81FF", "Cabletron E2000 Series DNI"},
+ {"PNP8200", "Cabletron E2100 Series DNI"},
+ {"PNP8201", "Cabletron T2015 4/16 Mbit/s DNI"},
+ {"PNP8209", "Zenith Data Systems Z-Note"},
+ {"PNP820A", "Zenith Data Systems NE2000-Compatible"},
+ {"PNP8213", "Xircom Pocket Ethernet II"},
+ {"PNP8214", "Xircom Pocket Ethernet I"},
+ {"PNP8215", "Xircom Pocket Ethernet III Adapter"},
+ {"PNP821D", "RadiSys EXM-10"},
+ {"PNP8227", "SMC 3000 Series"},
+ {"PNP8228", "SMC 91C2 controller"},
+ {"PNP8231", "AMD AM2100/AM1500T"},
+ {"PNP824F", "RCE 10Base-T (16 bit)"},
+ {"PNP8250", "RCE 10Base-T (8 bit)"},
+ {"PNP8263", "Tulip NCC-16"},
+ {"PNP8277", "Exos 105"},
+ {"PNP828A", "Intel '595 based Ethernet"},
+ {"PNP828B", "TI2000-style Token Ring"},
+ {"PNP828C", "AMD PCNet Family cards"},
+ {"PNP828D", "AMD PCNet32 (VL version)"},
+ {"PNP8294", "IrDA Infrared NDIS driver (Microsoft-supplied)"},
+ {"PNP82BD", "IBM PCMCIA-NIC"},
+ {"PNP82C0", "Eagle Technology NE200T"},
+ {"PNP82C2", "Xircom CE10"},
+ {"PNP82C3", "Xircom CEM2"},
+ {"PNP82C4", "Xircom CE2"},
+ {"PNP8321", "DEC Ethernet (All Types)"},
+ {"PNP8323", "SMC EtherCard (All Types except 8013/A)"},
+ {"PNP8324", "ARCNET Compatible"},
+ {"PNP8325", "SMC TokenCard PLUS (8115T)"},
+ {"PNP8326", "Thomas Conrad (All Arcnet Types)"},
+ {"PNP8327", "IBM Token Ring (All Types)"},
+ {"PNP8328", "Ungermann-Bass NIU"},
+ {"PNP8329", "Proteon ProNET-4/16 ISA Token Ring (P1392+,P1392,1390)"},
+ {"PNP8385", "Remote Network Access [RNA] Driver"},
+ {"PNP8387", "Remote Network Access [RNA] PPP Driver"},
+ {"PNP8388", "Reserved for Microsoft Networking components"},
+ {"PNP8389", "Peer IrLAN infrared driver (Microsoft-supplied)"},
+ {"PNP8390", "Generic network adapter"},
+ {"PNP8XXX", "Unknown Network Adapter"},
+ /* modems */
+ {"PNP9000", "Modem"},
+ /* CD controller */
+ {"PNPA000", "Adaptec 154x compatible SCSI controller"},
+ {"PNPA001", "Adaptec 174x compatible SCSI controller"},
+ {"PNPA002", "Future Domain 16-700 compatible controller"},
+ {"PNPA003", "Mitsumi CD-ROM adapter (Panasonic spec., used on SBPro/SB16)"},
+ {"PNPA01B", "Trantor 128 SCSI Controller"},
+ {"PNPA01D", "Trantor T160 SCSI Controller"},
+ {"PNPA01E", "Trantor T338 Parallel SCSI controller"},
+ {"PNPA01F", "Trantor T348 Parallel SCSI controller"},
+ {"PNPA020", "Trantor Media Vision SCSI controller"},
+ {"PNPA022", "Always IN-2000 SCSI controller"},
+ {"PNPA02B", "Sony proprietary CD-ROM controller"},
+ {"PNPA02D", "Trantor T13b 8-bit SCSI controller"},
+ {"PNPA02F", "Trantor T358 Parallel SCSI controller"},
+ {"PNPA030", "Mitsumi LU-005 Single Speed CD-ROM controller + drive"},
+ {"PNPA031", "Mitsumi FX-001 Single Speed CD-ROM controller + drive"},
+ {"PNPA032", "Mitsumi FX-001 Double Speed CD-ROM controller + drive"},
+ {"PNPAXXX", "Unknown SCSI, Proprietary CD Adapter"},
+ /* multimedia devices */
+ {"PNPB000", "Creative Labs Sound Blaster 1.5 (or compatible sound device)"},
+ {"PNPB001", "Creative Labs Sound Blaster 2.0 (or compatible sound device)"},
+ {"PNPB002", "Creative Labs Sound Blaster Pro (or compatible sound device)"},
+ {"PNPB003", "Creative Labs Sound Blaster 16 (or compatible sound device)"},
+ {"PNPB004", "MediaVision Thunderboard (or compatible sound device)"},
+ {"PNPB005", "Adlib-compatible FM synthesizer device"},
+ {"PNPB006", "MPU401 compatible"},
+ {"PNPB007", "Microsoft Windows Sound System-compatible sound device"},
+ {"PNPB008", "Compaq Business Audio"},
+ {"PNPB009", "Plug and Play Microsoft Windows Sound System Device"},
+ {"PNPB00A", "MediaVision Pro Audio Spectrum (Trantor SCSI enabled, Thunder Chip Disabled)"},
+ {"PNPB00B", "MediaVision Pro Audio 3D"},
+ {"PNPB00C", "MusicQuest MQX-32M"},
+ {"PNPB00D", "MediaVision Pro Audio Spectrum Basic (No Trantor SCSI, Thunder Chip Enabled)"},
+ {"PNPB00E", "MediaVision Pro Audio Spectrum (Trantor SCSI enabled, Thunder Chip Disabled)"},
+ {"PNPB00F", "MediaVision Jazz-16 chipset (OEM Versions)"},
+ {"PNPB010", "Orchid Videola - Auravision VxP500 chipset"},
+ {"PNPB018", "MediaVision Pro Audio Spectrum 8-bit"},
+ {"PNPB019", "MediaVision Pro Audio Spectrum Basic (No Trantor SCSI, Thunder Chip Enabled)"},
+ {"PNPB020", "Yamaha OPL3-compatible FM synthesizer device"},
+ {"PNPB02F", "Joystick/Game port"},
+ {"PNPB077", "OAK Mozart Sound System"},
+ {"PNPB078", "OAK Mozart Sound System MPU-401"},
+ {"PNPBXXX", "Unknown Multimedia Device"},
+ /* modems */
+ {"PNPC000", "Compaq 14400 Modem (TBD)"},
+ {"PNPC001", "Compaq 2400/9600 Modem (TBD)"},
+ {"PNPCXXX", "Unknown Modem"},
+ /* some other network cards */
+ {"PNPD300", "SK-NET TR4/16+ Token-Ring"},
+ {"PNPE000", "SK-NET G16, G16/TP Ethernet"},
+ {"PNPF000", "SK-NET FDDI-FI FDDI LAN"},
+ /* Toshiba devices */
+ {"TOS6200", "Toshiba Notebook Extra HCI driver"},
+ {"TOS6202", "Toshiba Notebook Extra HCI driver"},
+ {"TOS6207", "Toshiba Notebook Extra HCI driver"},
+ {"TOS7400", "Toshiba AcuPoint"},
+ /* Wacom devices */
+ {"WACf004", "Wacom Serial Tablet PC Pen Tablet/Digitizer"},
+ {"WACf005", "Wacom Serial Tablet PC Pen Tablet/Digitizer"},
+ {"WACf006", "Wacom Serial Tablet PC Pen Tablet/Digitizer"}
+};
+
+static int
+ids_comp_pnp(const void *id1, const void *id2) {
+ struct pnp_id *pnp_id1 = (struct pnp_id *) id1;
+ struct pnp_id *pnp_id2 = (struct pnp_id *) id2;
+ return strcasecmp(pnp_id1->id, pnp_id2->id);
+}
+
+void
+ids_find_pnp (const char *pnp_id, char **pnp_description)
+{
+ static gboolean sorted = FALSE;
+ struct pnp_id search, *res;
+
+ if (!sorted) {
+ /* sort the list, to be sure that all is in correc order */
+ qsort(pnp_ids_list, sizeof(pnp_ids_list)/sizeof(pnp_ids_list[0]),
+ sizeof(struct pnp_id), ids_comp_pnp);
+ sorted = TRUE;
+ }
+
+ search.id = (char *) pnp_id;
+ res = bsearch(&search, pnp_ids_list, sizeof(pnp_ids_list)/sizeof(pnp_ids_list[0]),
+ sizeof(struct pnp_id), ids_comp_pnp);
+
+ if (res != NULL)
+ *pnp_description = res->desc;
+ else
+ *pnp_description = NULL;
+ return;
+}
diff --git a/usr/src/cmd/hal/hald/ids.h b/usr/src/cmd/hal/hald/ids.h
new file mode 100644
index 0000000000..c1893202c4
--- /dev/null
+++ b/usr/src/cmd/hal/hald/ids.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * ids.h : Lookup names from hardware identifiers
+ *
+ * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef IDS_H
+#define IDS_H
+
+#include <glib.h>
+
+void ids_init (void);
+
+void
+ids_find_pci (int vendor_id, int product_id,
+ int subsys_vendor_id, int subsys_product_id,
+ char **vendor_name, char **product_name,
+ char **subsys_vendor_name, char **subsys_product_name);
+
+void
+ids_find_usb (int vendor_id, int product_id,
+ char **vendor_name, char **product_name);
+
+void
+ids_find_pnp (const char *pnp_id, char **pnp_description);
+
+
+#endif /* IDS_H */
diff --git a/usr/src/cmd/hal/hald/logger.c b/usr/src/cmd/hal/hald/logger.c
new file mode 100644
index 0000000000..00cf9e2170
--- /dev/null
+++ b/usr/src/cmd/hal/hald/logger.c
@@ -0,0 +1,241 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * logger.c : Logging
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2006 Danny Kukawka, <danny.kukawka@web.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "logger.h"
+
+/**
+ * @defgroup HalDaemonLogging Logging system
+ * @ingroup HalDaemon
+ * @brief Logging system for the HAL daemon
+ * @{
+ */
+
+
+static int priority;
+static const char *file;
+static int line;
+static const char *function;
+
+static int log_pid = 0;
+static int is_enabled = 1;
+static int syslog_enabled = 0;
+
+
+/** Disable all logging
+ *
+ */
+void
+logger_disable (void)
+{
+ is_enabled = 0;
+}
+
+/** Enable all logging
+ *
+ */
+void
+logger_enable (void)
+{
+ is_enabled = 1;
+}
+
+/** enable usage of syslog for logging
+ *
+ */
+void
+logger_enable_syslog (void)
+{
+ syslog_enabled = 1;
+}
+
+/** disable usage of syslog for logging
+ *
+ */
+void
+logger_disable_syslog (void)
+{
+ syslog_enabled = 0;
+}
+
+/** allow setup logger from a addon/prober via the env
+ *
+ */
+void
+setup_logger (void)
+{
+ if ((getenv ("HALD_VERBOSE")) != NULL) {
+ is_enabled = 1;
+ log_pid = 1;
+ }
+ else
+ is_enabled = 0;
+
+ if ((getenv ("HALD_USE_SYSLOG")) != NULL)
+ syslog_enabled = 1;
+ else
+ syslog_enabled = 0;
+}
+
+/** Setup logging entry
+ *
+ * @param priority Logging priority, one of HAL_LOGPRI_*
+ * @param file Name of file where the log entry originated
+ * @param line Line number of file
+ * @param function Name of function
+ */
+void
+logger_setup (int _priority, const char *_file, int _line, const char *_function)
+{
+ priority = _priority;
+ file = _file;
+ line = _line;
+ function = _function;
+}
+
+/** Emit logging entry
+ *
+ * @param format Message format string, printf style
+ * @param ... Parameters for message, printf style
+ */
+void
+logger_emit (const char *format, ...)
+{
+ va_list args;
+ char buf[512];
+ char *pri;
+ char tbuf[256];
+ char logmsg[1024];
+ struct timeval tnow;
+ struct tm *tlocaltime;
+ struct timezone tzone;
+ static pid_t pid = -1;
+
+ if (!is_enabled)
+ return;
+
+ va_start (args, format);
+ vsnprintf (buf, sizeof (buf), format, args);
+
+ switch (priority) {
+ case HAL_LOGPRI_TRACE:
+ pri = "[T]";
+ break;
+ case HAL_LOGPRI_DEBUG:
+ pri = "[D]";
+ break;
+ case HAL_LOGPRI_INFO:
+ pri = "[I]";
+ break;
+ case HAL_LOGPRI_WARNING:
+ pri = "[W]";
+ break;
+ default: /* explicit fallthrough */
+ case HAL_LOGPRI_ERROR:
+ pri = "[E]";
+ break;
+ }
+
+ gettimeofday (&tnow, &tzone);
+ tlocaltime = localtime (&tnow.tv_sec);
+ strftime (tbuf, sizeof (tbuf), "%H:%M:%S", tlocaltime);
+
+ if (log_pid) {
+ if ((int) pid == -1)
+ pid = getpid ();
+ snprintf (logmsg, sizeof(logmsg), "[%d]: %s.%03d %s %s:%d: %s\n", pid, tbuf, (int)(tnow.tv_usec/1000), pri, file, line, buf);
+ } else {
+ snprintf (logmsg, sizeof(logmsg), "%s.%03d %s %s:%d: %s\n", tbuf, (int)(tnow.tv_usec/1000), pri, file, line, buf);
+ }
+
+ /** @todo Make programmatic interface to logging */
+ if (priority != HAL_LOGPRI_TRACE && !syslog_enabled ) {
+ fprintf (stderr, "%s", logmsg );
+ } else if (priority != HAL_LOGPRI_TRACE && syslog_enabled ) {
+ /* use syslog for debug/log messages if HAL started as daemon */
+ switch (priority) {
+ case HAL_LOGPRI_DEBUG:
+ case HAL_LOGPRI_INFO:
+ syslog(LOG_INFO, "%s", logmsg );
+ break;
+ case HAL_LOGPRI_WARNING:
+ syslog(LOG_WARNING, "%s", logmsg );
+ break;
+ default: /* explicit fallthrough */
+ case HAL_LOGPRI_ERROR:
+ syslog(LOG_ERR, "%s", logmsg );
+ break;
+ }
+ }
+
+ va_end (args);
+}
+
+void
+logger_forward_debug (const char *format, ...)
+{
+ va_list args;
+ char buf[512];
+ char tbuf[256];
+ struct timeval tnow;
+ struct tm *tlocaltime;
+ struct timezone tzone;
+ static pid_t pid = -1;
+
+ if (!is_enabled)
+ return;
+
+ if ((int) pid == -1)
+ pid = getpid ();
+
+ va_start (args, format);
+ vsnprintf (buf, sizeof (buf), format, args);
+
+ gettimeofday (&tnow, &tzone);
+ tlocaltime = localtime (&tnow.tv_sec);
+ strftime (tbuf, sizeof (tbuf), "%H:%M:%S", tlocaltime);
+
+ if (syslog_enabled)
+ syslog (LOG_INFO, "%d: %s.%03d: %s", pid, tbuf, (int)(tnow.tv_usec/1000), buf);
+ else
+ fprintf (stderr, "%d: %s.%03d: %s", pid, tbuf, (int)(tnow.tv_usec/1000), buf);
+
+ va_end (args);
+}
+
+/** @} */
diff --git a/usr/src/cmd/hal/hald/logger.h b/usr/src/cmd/hal/hald/logger.h
new file mode 100644
index 0000000000..984753feeb
--- /dev/null
+++ b/usr/src/cmd/hal/hald/logger.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * logger.h : Logging facility
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * @addtogroup HalDaemonLogging
+ *
+ * @{
+ */
+
+
+/** Logging levels for HAL daemon
+ */
+enum {
+ HAL_LOGPRI_TRACE = (1 << 0), /**< function call sequences */
+ HAL_LOGPRI_DEBUG = (1 << 1), /**< debug statements in code */
+ HAL_LOGPRI_INFO = (1 << 2), /**< informational level */
+ HAL_LOGPRI_WARNING = (1 << 3), /**< warnings */
+ HAL_LOGPRI_ERROR = (1 << 4) /**< error */
+};
+
+void logger_setup (int priority, const char *file, int line, const char *function);
+
+void logger_emit (const char *format, ...);
+void logger_forward_debug (const char *format, ...);
+
+void logger_enable (void);
+void logger_disable (void);
+
+void logger_enable_syslog (void);
+void logger_disable_syslog (void);
+
+void setup_logger (void);
+
+#ifdef __SUNPRO_C
+#define __FUNCTION__ __func__
+#endif
+
+/** Trace logging macro */
+#define HAL_TRACE(expr) do {logger_setup(HAL_LOGPRI_TRACE, __FILE__, __LINE__, __FUNCTION__); logger_emit expr; } while(0)
+
+/** Debug information logging macro */
+#define HAL_DEBUG(expr) do {logger_setup(HAL_LOGPRI_DEBUG, __FILE__, __LINE__, __FUNCTION__); logger_emit expr; } while(0)
+
+/** Information level logging macro */
+#define HAL_INFO(expr) do {logger_setup(HAL_LOGPRI_INFO, __FILE__, __LINE__, __FUNCTION__); logger_emit expr; } while(0)
+
+/** Warning level logging macro */
+#define HAL_WARNING(expr) do {logger_setup(HAL_LOGPRI_WARNING, __FILE__, __LINE__, __FUNCTION__); logger_emit expr; } while(0)
+
+/** Error leve logging macro */
+#define HAL_ERROR(expr) do {logger_setup(HAL_LOGPRI_ERROR, __FILE__, __LINE__, __FUNCTION__); logger_emit expr; } while(0)
+
+/** Macro for terminating the program on an unrecoverable error */
+#define DIE(expr) do {printf("*** [DIE] %s:%s():%d : ", __FILE__, __FUNCTION__, __LINE__); printf expr; printf("\n"); exit(1); } while(0)
+
+/** @} */
+
+#endif /* LOGGER_H */
diff --git a/usr/src/cmd/hal/hald/osspec.h b/usr/src/cmd/hal/hald/osspec.h
new file mode 100644
index 0000000000..787a66cbbe
--- /dev/null
+++ b/usr/src/cmd/hal/hald/osspec.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * osspec.h : OS Specific interface
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef OSSPEC_H
+#define OSSPEC_H
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <dbus/dbus.h>
+
+#include "device.h"
+
+/** Initialize the kernel specific parts of the daemon */
+void osspec_init (void);
+
+/** Probe all devices present in the system and build the device list */
+void osspec_probe (void);
+
+/* Called by kernel specific parts when probing is done */
+void osspec_probe_done (void);
+
+gboolean osspec_device_rescan (HalDevice *d);
+
+gboolean osspec_device_reprobe (HalDevice *d);
+
+/* Called to refresh mount state for a device object of capability volume */
+void osspec_refresh_mount_state_for_block_device (HalDevice *d);
+
+/** Called when the org.freedesktop.Hal service receives a messaged that the generic daemon
+ * doesn't handle. Can be used for intercepting messages from kernel or core OS components.
+ *
+ * @param connection D-BUS connection
+ * @param message Message
+ * @param user_data User data
+ * @return What to do with the message
+ */
+DBusHandlerResult osspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data);
+
+#endif /* OSSPEC_H */
diff --git a/usr/src/cmd/hal/hald/property.c b/usr/src/cmd/hal/hald/property.c
new file mode 100644
index 0000000000..2caeb2b24b
--- /dev/null
+++ b/usr/src/cmd/hal/hald/property.c
@@ -0,0 +1,490 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * property.c : HalProperty methods
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2004 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+
+#include "logger.h"
+#include "property.h"
+
+struct _HalProperty {
+ char *key;
+
+ int type;
+ union {
+ char *str_value;
+ dbus_int32_t int_value;
+ dbus_uint64_t uint64_value;
+ dbus_bool_t bool_value;
+ double double_value;
+ GSList *strlist_value;
+ } v;
+ gboolean readonly;
+ gboolean persistence;
+ gboolean callout;
+};
+
+void
+hal_property_free (HalProperty *prop)
+{
+
+ g_free (prop->key);
+
+ if (prop->type == HAL_PROPERTY_TYPE_STRING) {
+ g_free (prop->v.str_value);
+ } else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
+ GSList *i;
+ for (i = prop->v.strlist_value; i != NULL; i = g_slist_next (i)) {
+ g_free (i->data);
+ }
+ g_slist_free (prop->v.strlist_value);
+ }
+
+ g_free (prop);
+}
+
+HalProperty *
+hal_property_new_string (const char *key, const char *value)
+{
+ HalProperty *prop;
+ char *endchar;
+ gboolean validated = TRUE;
+
+ prop = g_new0 (HalProperty, 1);
+
+ prop->type = HAL_PROPERTY_TYPE_STRING;
+ prop->key = g_strdup (key);
+ prop->v.str_value = g_strdup (value != NULL ? value : "");
+
+ while (!g_utf8_validate (prop->v.str_value, -1,
+ (const char **) &endchar)) {
+ validated = FALSE;
+ *endchar = '?';
+ }
+
+ if (!validated) {
+ HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
+ key, prop->v.str_value));
+ }
+
+ return prop;
+}
+
+HalProperty *
+hal_property_new_int (const char *key, dbus_int32_t value)
+{
+ HalProperty *prop;
+
+ prop = g_new0 (HalProperty, 1);
+
+ prop->type = HAL_PROPERTY_TYPE_INT32;
+ prop->key = g_strdup (key);
+ prop->v.int_value = value;
+
+ return prop;
+}
+
+HalProperty *
+hal_property_new_uint64 (const char *key, dbus_uint64_t value)
+{
+ HalProperty *prop;
+
+ prop = g_new0 (HalProperty, 1);
+
+ prop->type = HAL_PROPERTY_TYPE_UINT64;
+ prop->key = g_strdup (key);
+ prop->v.uint64_value = value;
+
+ return prop;
+}
+
+HalProperty *
+hal_property_new_bool (const char *key, dbus_bool_t value)
+{
+ HalProperty *prop;
+
+ prop = g_new0 (HalProperty, 1);
+
+ prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
+ prop->key = g_strdup (key);
+ prop->v.bool_value = value;
+
+ return prop;
+}
+
+HalProperty *
+hal_property_new_double (const char *key, double value)
+{
+ HalProperty *prop;
+
+ prop = g_new0 (HalProperty, 1);
+
+ prop->type = HAL_PROPERTY_TYPE_DOUBLE;
+ prop->key = g_strdup (key);
+ prop->v.double_value = value;
+
+ return prop;
+}
+
+const char *
+hal_property_get_key (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, NULL);
+
+ return prop->key;
+}
+
+int
+hal_property_get_type (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_INVALID);
+
+ return prop->type;
+}
+
+const char *
+hal_property_get_string (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, NULL);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
+
+ return prop->v.str_value;
+}
+
+dbus_int32_t
+hal_property_get_int (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, -1);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
+
+ return prop->v.int_value;
+}
+
+dbus_uint64_t
+hal_property_get_uint64 (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, -1);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
+
+ return prop->v.uint64_value;
+}
+
+dbus_bool_t
+hal_property_get_bool (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
+
+ return prop->v.bool_value;
+}
+
+char *
+hal_property_to_string (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, NULL);
+
+ switch (prop->type) {
+ case HAL_PROPERTY_TYPE_STRING:
+ return g_strdup (prop->v.str_value);
+ case HAL_PROPERTY_TYPE_INT32:
+ return g_strdup_printf ("%d", prop->v.int_value);
+ case HAL_PROPERTY_TYPE_UINT64:
+ return g_strdup_printf ("%llu", (long long unsigned int) prop->v.uint64_value);
+ case HAL_PROPERTY_TYPE_BOOLEAN:
+ /* FIXME: Maybe use 1 and 0 here instead? */
+ return g_strdup (prop->v.bool_value ? "true" : "false");
+ case HAL_PROPERTY_TYPE_DOUBLE:
+ return g_strdup_printf ("%f", prop->v.double_value);
+ case HAL_PROPERTY_TYPE_STRLIST:
+ {
+ GSList *iter;
+ guint i;
+ char buf[256];
+
+ i = 0;
+ buf[0] = '\0';
+ for (iter = hal_property_get_strlist (prop);
+ iter != NULL && i < sizeof(buf);
+ iter = g_slist_next (iter)) {
+ guint len;
+ const char *str;
+
+ str = (const char *) iter->data;
+ len = strlen (str);
+ strncpy (buf + i, str, sizeof(buf) - i);
+ i += len;
+
+ if (g_slist_next (iter) != NULL && i < sizeof(buf)) {
+ buf[i] = '\t';
+ i++;
+ }
+ }
+ return g_strdup (buf);
+ }
+
+ default:
+ return NULL;
+ }
+}
+
+double
+hal_property_get_double (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, -1.0);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE, -1.0);
+
+ return prop->v.double_value;
+}
+
+void
+hal_property_set_string (HalProperty *prop, const char *value)
+{
+ char *endchar;
+ gboolean validated = TRUE;
+
+ g_return_if_fail (prop != NULL);
+ g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING ||
+ prop->type == HAL_PROPERTY_TYPE_INVALID);
+
+ prop->type = HAL_PROPERTY_TYPE_STRING;
+ if (prop->v.str_value != NULL)
+ g_free (prop->v.str_value);
+ prop->v.str_value = g_strdup (value);
+
+ while (!g_utf8_validate (prop->v.str_value, -1,
+ (const char **) &endchar)) {
+ validated = FALSE;
+ *endchar = '?';
+ }
+
+ if (!validated) {
+ HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
+ prop->key, value));
+ }
+}
+
+void
+hal_property_set_int (HalProperty *prop, dbus_int32_t value)
+{
+ g_return_if_fail (prop != NULL);
+ g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
+ prop->type == HAL_PROPERTY_TYPE_INVALID);
+
+ prop->type = HAL_PROPERTY_TYPE_INT32;
+ prop->v.int_value = value;
+}
+
+void
+hal_property_set_uint64 (HalProperty *prop, dbus_uint64_t value)
+{
+ g_return_if_fail (prop != NULL);
+ g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
+ prop->type == HAL_PROPERTY_TYPE_INVALID);
+
+ prop->type = HAL_PROPERTY_TYPE_UINT64;
+ prop->v.uint64_value = value;
+}
+
+void
+hal_property_set_bool (HalProperty *prop, dbus_bool_t value)
+{
+ g_return_if_fail (prop != NULL);
+ g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
+ prop->type == HAL_PROPERTY_TYPE_INVALID);
+
+ prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
+ prop->v.bool_value = value;
+}
+
+void
+hal_property_set_double (HalProperty *prop, double value)
+{
+ g_return_if_fail (prop != NULL);
+ g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
+ prop->type == HAL_PROPERTY_TYPE_INVALID);
+
+ prop->type = HAL_PROPERTY_TYPE_DOUBLE;
+ prop->v.double_value = value;
+}
+
+void
+hal_property_set_attribute (HalProperty *prop,
+ enum PropertyAttribute attr,
+ gboolean val)
+{
+ g_return_if_fail (prop != NULL);
+
+ switch (attr) {
+ case READONLY:
+ prop->readonly = val;
+ break;
+ case PERSISTENCE:
+ prop->persistence = val;
+ break;
+ case CALLOUT:
+ prop->callout = val;
+ break;
+ }
+}
+
+gboolean
+hal_property_get_attribute (HalProperty *prop,
+ enum PropertyAttribute attr)
+{
+ g_return_val_if_fail (prop != NULL, -1);
+
+ switch (attr) {
+ case READONLY:
+ return prop->readonly;
+ case PERSISTENCE:
+ return prop->persistence;
+ case CALLOUT:
+ return prop->callout;
+ default:
+ return -1;
+ }
+}
+
+HalProperty *
+hal_property_new_strlist (const char *key)
+{
+ HalProperty *prop;
+
+ prop = g_new0 (HalProperty, 1);
+
+ prop->type = HAL_PROPERTY_TYPE_STRLIST;
+ prop->key = g_strdup (key);
+ prop->v.strlist_value = NULL;
+
+ return prop;
+}
+
+GSList *
+hal_property_get_strlist (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, NULL);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, NULL);
+
+ return prop->v.strlist_value;
+}
+
+gboolean
+hal_property_strlist_append (HalProperty *prop, const char *value)
+{
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+ prop->v.strlist_value = g_slist_append (prop->v.strlist_value, g_strdup (value));
+
+ return TRUE;
+}
+
+gboolean
+hal_property_strlist_prepend (HalProperty *prop, const char *value)
+{
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+ prop->v.strlist_value = g_slist_prepend (prop->v.strlist_value, g_strdup (value));
+
+ return TRUE;
+}
+
+gboolean
+hal_property_strlist_remove_elem (HalProperty *prop, guint index)
+{
+ GSList *elem;
+
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+ if (prop->v.strlist_value == NULL)
+ return FALSE;
+
+ elem = g_slist_nth (prop->v.strlist_value, index);
+ if (elem == NULL)
+ return FALSE;
+
+ g_free (elem->data);
+ prop->v.strlist_value = g_slist_delete_link (prop->v.strlist_value, elem);
+ return TRUE;
+}
+
+
+gboolean
+hal_property_strlist_add (HalProperty *prop, const char *value)
+{
+ GSList *elem;
+
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+ for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
+ if (strcmp (elem->data, value) == 0) {
+ return FALSE;
+ }
+ }
+
+ return hal_property_strlist_append (prop, value);
+}
+
+gboolean
+hal_property_strlist_remove (HalProperty *prop, const char *value)
+{
+ guint i;
+ GSList *elem;
+
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+ for (elem = prop->v.strlist_value, i = 0; elem != NULL; elem = g_slist_next (elem), i++) {
+ if (strcmp (elem->data, value) == 0) {
+ return hal_property_strlist_remove_elem (prop, i);
+ }
+ }
+
+ return FALSE;
+}
+
+gboolean
+hal_property_strlist_clear (HalProperty *prop)
+{
+ GSList *elem;
+
+ g_return_val_if_fail (prop != NULL, FALSE);
+ g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+ for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
+ g_free (elem->data);
+ }
+ g_slist_free (prop->v.strlist_value);
+
+ return FALSE;
+}
diff --git a/usr/src/cmd/hal/hald/property.h b/usr/src/cmd/hal/hald/property.h
new file mode 100644
index 0000000000..b5afa25da7
--- /dev/null
+++ b/usr/src/cmd/hal/hald/property.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * property.c : HalProperty methods
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2004 Novell, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef PROPERTY_H
+#define PROPERTY_H
+
+#include <dbus/dbus.h>
+
+typedef struct _HalProperty HalProperty;
+
+#define HAL_PROPERTY_TYPE_INVALID DBUS_TYPE_INVALID
+#define HAL_PROPERTY_TYPE_INT32 DBUS_TYPE_INT32
+#define HAL_PROPERTY_TYPE_UINT64 DBUS_TYPE_UINT64
+#define HAL_PROPERTY_TYPE_DOUBLE DBUS_TYPE_DOUBLE
+#define HAL_PROPERTY_TYPE_BOOLEAN DBUS_TYPE_BOOLEAN
+#define HAL_PROPERTY_TYPE_STRING DBUS_TYPE_STRING
+#define HAL_PROPERTY_TYPE_STRLIST ((int) (DBUS_TYPE_STRING<<8)+('l'))
+
+enum PropertyAttribute {
+ READONLY,
+ PERSISTENCE,
+ CALLOUT
+};
+
+void hal_property_free (HalProperty *prop);
+
+HalProperty *hal_property_new_string (const char *key,
+ const char *value);
+HalProperty *hal_property_new_int (const char *key,
+ dbus_int32_t value);
+HalProperty *hal_property_new_uint64 (const char *key,
+ dbus_uint64_t value);
+HalProperty *hal_property_new_bool (const char *key,
+ dbus_bool_t value);
+HalProperty *hal_property_new_double (const char *key,
+ double value);
+HalProperty *hal_property_new_strlist (const char *key);
+
+const char *hal_property_get_key (HalProperty *prop);
+int hal_property_get_type (HalProperty *prop);
+char *hal_property_to_string (HalProperty *prop);
+
+const char *hal_property_get_string (HalProperty *prop);
+dbus_int32_t hal_property_get_int (HalProperty *prop);
+dbus_uint64_t hal_property_get_uint64 (HalProperty *prop);
+dbus_bool_t hal_property_get_bool (HalProperty *prop);
+double hal_property_get_double (HalProperty *prop);
+GSList *hal_property_get_strlist (HalProperty *prop);
+
+void hal_property_set_string (HalProperty *prop,
+ const char *value);
+void hal_property_set_int (HalProperty *prop,
+ dbus_int32_t value);
+void hal_property_set_uint64 (HalProperty *prop,
+ dbus_uint64_t value);
+void hal_property_set_bool (HalProperty *prop,
+ dbus_bool_t value);
+void hal_property_set_double (HalProperty *prop,
+ double value);
+gboolean hal_property_strlist_append (HalProperty *prop,
+ const char *value);
+gboolean hal_property_strlist_prepend (HalProperty *prop,
+ const char *value);
+gboolean hal_property_strlist_remove_elem (HalProperty *prop,
+ guint index);
+
+gboolean hal_property_strlist_add (HalProperty *prop,
+ const char *value);
+gboolean hal_property_strlist_remove (HalProperty *prop,
+ const char *value);
+gboolean hal_property_strlist_clear (HalProperty *prop);
+
+
+void hal_property_set_attribute (HalProperty *prop,
+ enum PropertyAttribute attr,
+ gboolean val);
+gboolean hal_property_get_attribute (HalProperty *prop,
+ enum PropertyAttribute attr);
+
+#endif /* PROPERTY_H */
diff --git a/usr/src/cmd/hal/hald/solaris/Makefile b/usr/src/cmd/hal/hald/solaris/Makefile
new file mode 100644
index 0000000000..cd30e01370
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/Makefile
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+OBJS = devinfo.o devinfo_ieee1394.o devinfo_misc.o devinfo_pci.o \
+ devinfo_storage.o devinfo_usb.o hotplug.o osspec.o sysevent.o
+
+SRCS = $(OBJS:%.o=%.c)
+
+MANIFEST = hal.xml
+SVCMETHOD = svc-hal
+
+include ../../../Makefile.cmd
+include ../../Makefile.hal
+
+ROOTMANIFESTDIR = $(ROOTSVCSYSTEM)
+$(ROOTMANIFEST) := FILEMODE = 444
+$(ROOTLIBSVCMETHOD)/svc-hal:= FILEMODE = 555
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I/usr/sfw/include
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(OBJS)
+
+install: all $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+check: $(CHKMANIFEST)
+
+clean:
+ $(RM) $(OBJS)
+
+FRC:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo.c b/usr/src/cmd/hal/hald/solaris/devinfo.c
new file mode 100644
index 0000000000..733d90efc9
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo.c
@@ -0,0 +1,376 @@
+/***************************************************************************
+ *
+ * devinfo.c : main file for libdevinfo-based device enumeration
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <libdevinfo.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../hald_runner.h"
+#include "osspec_solaris.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_pci.h"
+#include "devinfo_storage.h"
+#include "devinfo_ieee1394.h"
+#include "devinfo_usb.h"
+#include "devinfo_misc.h"
+
+void devinfo_add_subtree(HalDevice *parent, di_node_t node, gboolean is_root);
+HalDevice *devinfo_add_node(HalDevice *parent, di_node_t node);
+
+void
+devinfo_add(HalDevice *parent, gchar *path)
+{
+ di_node_t root;
+
+ if (strcmp (path, "/") == 0) {
+ if ((root = di_init(path, DINFOCACHE)) == DI_NODE_NIL) {
+ HAL_INFO (("di_init() failed %d", errno));
+ return;
+ }
+ } else {
+ if ((root = di_init(path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("di_init() failed %d", errno));
+ return;
+ }
+ }
+
+ devinfo_add_subtree(parent, root, TRUE);
+
+ di_fini (root);
+}
+
+void
+devinfo_add_subtree(HalDevice *parent, di_node_t node, gboolean is_root)
+{
+ HalDevice *d;
+ di_node_t root_node, child_node;
+
+ HAL_INFO (("add_subtree: %s", di_node_name (node)));
+
+ root_node = node;
+ do {
+ d = devinfo_add_node (parent, node);
+
+ if ((d != NULL) &&
+ (child_node = di_child_node (node)) != DI_NODE_NIL) {
+ devinfo_add_subtree (d, child_node, FALSE);
+ }
+
+ node = di_sibling_node (node);
+ } while ((node != DI_NODE_NIL) &&
+ (!is_root || di_parent_node (node) == root_node));
+}
+
+void
+devinfo_set_default_properties (HalDevice *d, HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ char *driver_name, *s;
+ const char *s1;
+ char udi[HAL_PATH_MAX];
+
+ if (parent != NULL) {
+ hal_device_property_set_string (d, "info.parent", parent->udi);
+ } else {
+ hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/local");
+ }
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "/org/freedesktop/Hal/devices%s_%d",
+ devfs_path,
+ di_instance (node));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+
+ if (di_prop_lookup_strings (DDI_DEV_T_ANY, node, "model", &s) > 0) {
+ hal_device_property_set_string (d, "info.product", s);
+ } else {
+ hal_device_property_set_string (d, "info.product", di_node_name (node));
+ }
+
+ hal_device_property_set_string (d, "solaris.devfs_path", devfs_path);
+
+ if ((driver_name = di_driver_name (node)) != NULL) {
+ hal_device_property_set_string (d, "info.solaris.driver",
+ driver_name);
+ }
+
+
+ /* inherit parent's claim attributes */
+ if (hal_device_property_get_bool (parent, "info.claimed")) {
+ s1 = hal_device_property_get_string (parent, "info.claimed.service");
+ if (s1 != NULL) {
+ hal_device_property_set_bool (d, "info.claimed", TRUE);
+ hal_device_property_set_string (d, "info.claimed.service", s1);
+ }
+ }
+}
+
+/* device handlers, ordered specific to generic */
+static DevinfoDevHandler *devinfo_handlers[] = {
+ &devinfo_computer_handler,
+ &devinfo_cpu_handler,
+ &devinfo_ide_handler,
+ &devinfo_scsi_handler,
+ &devinfo_floppy_handler,
+ &devinfo_usb_handler,
+ &devinfo_ieee1394_handler,
+ &devinfo_pci_handler,
+ &devinfo_lofi_handler,
+ &devinfo_default_handler,
+ NULL
+};
+
+HalDevice *
+devinfo_add_node(HalDevice *parent, di_node_t node)
+{
+ HalDevice *d = NULL;
+ char *devfs_path;
+ char *device_type = NULL;
+ DevinfoDevHandler *handler;
+ int i;
+
+ devfs_path = di_devfs_path (node);
+
+ (void) di_prop_lookup_strings (DDI_DEV_T_ANY, node, "device_type",
+ &device_type);
+
+ for (i = 0; (d == NULL) && (devinfo_handlers[i] != NULL); i++) {
+ handler = devinfo_handlers[i];
+ d = handler->add (parent, node, devfs_path, device_type);
+ }
+
+ di_devfs_path_free(devfs_path);
+
+ HAL_INFO (("add_node: %s", d ? d->udi : "none"));
+ return (d);
+}
+
+void
+devinfo_hotplug_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler, int action, int front)
+{
+ HotplugEvent *hotplug_event;
+
+ hotplug_event = g_new0 (HotplugEvent, 1);
+ hotplug_event->action = action;
+ hotplug_event->type = HOTPLUG_EVENT_DEVFS;
+ hotplug_event->d = d;
+ strlcpy (hotplug_event->un.devfs.devfs_path, devfs_path,
+ sizeof (hotplug_event->un.devfs.devfs_path));
+ hotplug_event->un.devfs.handler = handler;
+
+ hotplug_event_enqueue (hotplug_event, front);
+}
+
+void
+devinfo_add_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler)
+{
+ devinfo_hotplug_enqueue (d, devfs_path, handler, HOTPLUG_ACTION_ADD, 0);
+}
+
+void
+devinfo_add_enqueue_at_front(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler)
+{
+ devinfo_hotplug_enqueue (d, devfs_path, handler, HOTPLUG_ACTION_ADD, 1);
+}
+
+void
+devinfo_remove_enqueue(gchar *devfs_path, DevinfoDevHandler *handler)
+{
+ devinfo_hotplug_enqueue (NULL, devfs_path, handler, HOTPLUG_ACTION_REMOVE, 0);
+}
+
+void
+devinfo_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ /* Move from temporary to global device store */
+ hal_device_store_remove (hald_get_tdl (), d);
+ hal_device_store_add (hald_get_gdl (), d);
+
+ hotplug_event_end (end_token);
+}
+
+void
+devinfo_callouts_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ /* Discard device if probing reports failure */
+ if (exit_type != HALD_RUN_SUCCESS || (return_code != 0)) {
+ HAL_INFO (("Probing for %s failed %d", d->udi, return_code));
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ /* Merge properties from .fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
+ di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY);
+
+ hal_util_callout_device_add (d, devinfo_callouts_add_done, end_token, NULL);
+}
+
+void
+devinfo_callouts_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ DevinfoDevHandler *handler = (DevinfoDevHandler *) userdata2;
+ void (*probing_done) (HalDevice *, guint32, gint, char **, gpointer, gpointer);
+ const gchar *prober;
+ int prober_timeout;
+
+ if (hal_device_property_get_bool (d, "info.ignore")) {
+ HAL_INFO (("Preprobing merged info.ignore==TRUE"));
+
+ /* Leave device with info.ignore==TRUE so we won't pick up children */
+ hal_device_property_remove (d, "info.category");
+ hal_device_property_remove (d, "info.capabilities");
+
+ hal_device_store_remove (hald_get_tdl (), d);
+ hal_device_store_add (hald_get_gdl (), d);
+
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ if (handler != NULL && handler->get_prober != NULL) {
+ prober = handler->get_prober (d, &prober_timeout);
+ } else {
+ prober = NULL;
+ }
+
+ if (handler->probing_done != NULL) {
+ probing_done = handler->probing_done;
+ } else {
+ probing_done = devinfo_callouts_probing_done;
+ }
+
+ if (prober != NULL) {
+ /* probe the device */
+ HAL_INFO(("Probing udi=%s", d->udi));
+ hald_runner_run (d,
+ prober, NULL,
+ prober_timeout,
+ probing_done,
+ (gpointer) end_token, (gpointer) handler);
+ } else {
+ probing_done (d, 0, 0, NULL, userdata1, userdata2);
+ }
+}
+
+/* This is the beginning of hotplug even handling */
+void
+hotplug_event_begin_add_devinfo (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
+{
+ HAL_INFO(("Preprobing udi=%s", d->udi));
+
+ if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) {
+ HAL_INFO (("Ignoring device since parent has info.ignore==TRUE"));
+
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ /* add to TDL so preprobing callouts and prober can access it */
+ hal_device_store_add (hald_get_tdl (), d);
+
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+
+ /* Run preprobe callouts */
+ hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler);
+}
+
+void
+devinfo_remove (gchar *devfs_path)
+{
+ devinfo_remove_enqueue ((gchar *)devfs_path, NULL);
+}
+
+/* generate hotplug event for each device in this branch */
+void
+devinfo_remove_branch (gchar *devfs_path, HalDevice *d)
+{
+ GSList *i;
+ GSList *children;
+ HalDevice *child;
+ char *child_devfs_path;
+
+ if (d == NULL) {
+ d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", devfs_path);
+ if (d == NULL)
+ return;
+ }
+
+ HAL_INFO (("remove_branch: %s %s\n", devfs_path, d->udi));
+
+ /* first remove children */
+ children = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
+ "info.parent", d->udi);
+ for (i = children; i != NULL; i = g_slist_next (i)) {
+ child = HAL_DEVICE (i->data);
+ HAL_INFO (("remove_branch: child %s\n", child->udi));
+ devinfo_remove_branch ((gchar *)hal_device_property_get_string (child, "solaris.devfs_path"), child);
+ }
+ g_slist_free (children);
+ HAL_INFO (("remove_branch: done with children"));
+
+ /* then remove self */
+ HAL_INFO (("remove_branch: queueing %s", devfs_path));
+ devinfo_remove_enqueue (devfs_path, NULL);
+}
+
+void
+devinfo_callouts_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+
+ if (!hal_device_store_remove (hald_get_gdl (), d)) {
+ HAL_WARNING (("Error removing device"));
+ }
+ g_object_unref (d);
+
+ hotplug_event_end (end_token);
+}
+
+void
+hotplug_event_begin_remove_devinfo (HalDevice *d, gchar *devfs_path, void *end_token)
+{
+ if (hal_device_has_capability (d, "volume")) {
+ devinfo_volume_hotplug_begin_remove (d, devfs_path, end_token);
+ } else {
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+ }
+}
+
+gboolean
+devinfo_device_rescan (HalDevice *d)
+{
+ if (hal_device_has_capability (d, "block")) {
+ return (devinfo_storage_device_rescan (d));
+ } else {
+ return (FALSE);
+ }
+}
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo.h b/usr/src/cmd/hal/hald/solaris/devinfo.h
new file mode 100644
index 0000000000..d51a0f53f8
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *
+ * devinfo.h : definitions for libdevinfo-based device enumeration
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_H
+#define DEVINFO_H
+
+#include <glib.h>
+#include <libdevinfo.h>
+
+#include "../hald.h"
+#include "../device_info.h"
+
+typedef struct DevinfoDevHandler_s
+{
+ HalDevice *(*add) (HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+
+ /* yet unused */
+ void (*remove) (char *devfs_path);
+
+ void (*hotplug_begin_add) (HalDevice *d, HalDevice *parent, struct DevinfoDevHandler_s *handler, void *end_token);
+
+ void (*hotplug_begin_remove) (HalDevice *d, struct DevinfoDevHandler_s *handler, void *end_token);
+
+ void (*probing_done) (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2);
+
+ const gchar *(*get_prober) (HalDevice *d, int *timeout);
+} DevinfoDevHandler;
+
+#define PROP_INT(d, node, v, diprop, halprop) \
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, diprop, &(v)) > 0) { \
+ hal_device_property_set_int (d, halprop, *(v)); \
+ }
+
+#define PROP_STR(d, node, v, diprop, halprop) \
+ if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, diprop, &(v)) > 0) { \
+ hal_device_property_set_string (d, halprop, v); \
+ }
+
+#define PROP_BOOL(d, node, v, diprop, halprop) \
+ hal_device_property_set_bool (d, halprop, \
+ (di_prop_lookup_ints(DDI_DEV_T_ANY, node, diprop, &(v)) >= 0));
+
+#define NELEM(a) (sizeof (a) / sizeof (*(a)))
+
+void devinfo_add (HalDevice *parent, gchar *path);
+void devinfo_set_default_properties (HalDevice *d, HalDevice *parent, di_node_t node, char *devfs_path);
+void devinfo_callouts_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2);
+void devinfo_callouts_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error,
+ gpointer userdata1, gpointer userdata2);
+void devinfo_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2);
+void devinfo_callouts_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2);
+void hotplug_event_begin_add_devinfo (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
+void devinfo_remove (gchar *path);
+void devinfo_remove_branch (gchar *path, HalDevice *d);
+void hotplug_event_begin_remove_devinfo (HalDevice *d, gchar *devfs_path, void *end_token);
+void devinfo_hotplug_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler, int action, int front);
+void devinfo_add_enqueue(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler);
+void devinfo_add_enqueue_at_front(HalDevice *d, gchar *devfs_path, DevinfoDevHandler *handler);
+void devinfo_remove_enqueue(gchar *devfs_path, DevinfoDevHandler *handler);
+gboolean devinfo_device_rescan (HalDevice *d);
+
+#endif /* DEVINFO_H */
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.c b/usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.c
new file mode 100644
index 0000000000..32566ea8c4
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.c
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *
+ * devinfo_ieee1394.c : IEEE 1394/FireWire devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <libdevinfo.h>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_ieee1394.h"
+
+HalDevice *devinfo_ieee1394_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_scsa1394_add(HalDevice *d, di_node_t node, gchar *devfs_path);
+
+DevinfoDevHandler devinfo_ieee1394_handler = {
+ devinfo_ieee1394_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *
+devinfo_ieee1394_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d = NULL;
+ char *compat;
+ char *driver_name;
+
+ /*
+ * we distinguish 1394 devices by compatible name
+ * starting with 'firewire'
+ */
+ if ((di_compatible_names (node, &compat) < 1) ||
+ (strncmp (compat, "firewire", sizeof ("firewire") - 1) != 0)) {
+ return (NULL);
+ }
+
+ if ((driver_name = di_driver_name (node)) == NULL) {
+ return (NULL);
+ }
+
+ if (strcmp (driver_name, "scsa1394") == 0) {
+ d = devinfo_scsa1394_add (parent, node, devfs_path);
+ }
+
+ return (d);
+}
+
+static HalDevice *
+devinfo_scsa1394_add(HalDevice *parent, di_node_t node, gchar *devfs_path)
+{
+ HalDevice *d = NULL;
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.bus", "ieee1394");
+ hal_device_property_set_string (d, "info.product", "FireWire SBP-2 device");
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_ieee1394_handler);
+
+ return (d);
+}
+
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.h b/usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.h
new file mode 100644
index 0000000000..b149af5bb5
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_ieee1394.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *
+ * devinfo_ieee1394.h : definitions for IEEE 1394 devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_IEEE1394_H
+#define DEVINFO_IEEE1394_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_ieee1394_handler;
+
+#endif /* DEVINFO_IEEE1394_H */
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_misc.c b/usr/src/cmd/hal/hald/solaris/devinfo_misc.c
new file mode 100644
index 0000000000..34c5638501
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_misc.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ *
+ * devinfo_misc : misc devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <libdevinfo.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "devinfo_misc.h"
+
+static HalDevice *devinfo_computer_add(HalDevice *, di_node_t, char *, char *);
+static HalDevice *devinfo_cpu_add(HalDevice *, di_node_t, char *,char *);
+static HalDevice *devinfo_default_add(HalDevice *, di_node_t, char *, char *);
+
+DevinfoDevHandler devinfo_computer_handler = {
+ devinfo_computer_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_cpu_handler = {
+ devinfo_cpu_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_default_handler = {
+ devinfo_default_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static HalDevice *
+devinfo_computer_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d, *local_d;
+ struct utsname un;
+
+ if (strcmp (devfs_path, "/") != 0) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ hal_device_property_set_string (d, "info.bus", "unknown");
+ hal_device_property_set_string (d, "info.product", "Computer");
+ hal_device_property_set_string (d, "info.udi", "/org/freedesktop/Hal/devices/computer");
+ hal_device_set_udi (d, "/org/freedesktop/Hal/devices/computer");
+ hal_device_property_set_string (d, "solaris.devfs_path", devfs_path);
+
+ if (uname (&un) >= 0) {
+ hal_device_property_set_string (d, "system.kernel.name", un.sysname);
+ hal_device_property_set_string (d, "system.kernel.version", un.release);
+ hal_device_property_set_string (d, "system.kernel.machine", un.machine);
+ }
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_computer_handler);
+
+ /* all devinfo devices belong to the 'local' branch */
+ local_d = hal_device_new ();
+
+ hal_device_property_set_string (local_d, "info.parent", d->udi);
+ hal_device_property_set_string (local_d, "info.bus", "unknown");
+ hal_device_property_set_string (local_d, "info.product", "Local devices");
+ hal_device_property_set_string (local_d, "info.udi", "/org/freedesktop/Hal/devices/local");
+ hal_device_set_udi (local_d, "/org/freedesktop/Hal/devices/local");
+ hal_device_property_set_string (local_d, "solaris.devfs_path", "/local");
+
+ devinfo_add_enqueue (local_d, "/local", &devinfo_default_handler);
+
+ return (local_d);
+}
+
+static HalDevice *
+devinfo_cpu_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+
+ if ((device_type == NULL) || (strcmp(device_type, "cpu") != 0)) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_add_capability (d, "processor");
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_cpu_handler);
+
+ return (d);
+}
+
+static HalDevice *
+devinfo_default_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ char *driver_name;
+ const char *parent_path;
+ HalDevice *d;
+
+ /* ignore all children of the 'pseudo' node except lofi */
+ if (parent != NULL) {
+ parent_path = hal_device_property_get_string(parent, "solaris.devfs_path");
+ if ((parent_path != NULL) &&
+ (strcmp (parent_path, "/pseudo") == 0)) {
+ driver_name = di_driver_name (node);
+ if ((driver_name != NULL) &&
+ (strcmp (driver_name, "lofi") != 0)) {
+ return (NULL);
+ }
+ }
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_default_handler);
+
+ return (d);
+}
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_misc.h b/usr/src/cmd/hal/hald/solaris/devinfo_misc.h
new file mode 100644
index 0000000000..ce515ba14b
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_misc.h
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *
+ * devinfo_misc.h : definitions for misc devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_MISC_H
+#define DEVINFO_MISC_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_cpu_handler;
+extern DevinfoDevHandler devinfo_computer_handler;
+extern DevinfoDevHandler devinfo_default_handler;
+
+#endif /* DEVINFO_MISC_H */
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_pci.c b/usr/src/cmd/hal/hald/solaris/devinfo_pci.c
new file mode 100644
index 0000000000..981caf0dec
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_pci.c
@@ -0,0 +1,118 @@
+/***************************************************************************
+ *
+ * devinfo_pci.c : PCI devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <libdevinfo.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "devinfo_pci.h"
+
+HalDevice *devinfo_pci_add (HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+
+DevinfoDevHandler devinfo_pci_handler = {
+ devinfo_pci_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *devinfo_pci_add (HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d;
+ char *s;
+ int *i;
+ int vid, pid, svid, spid;
+
+ if ((device_type == NULL) ||
+ ((strcmp (device_type, "pci") != 0) &&
+ (strcmp (device_type, "pci-ide") != 0))) {
+ if (parent == NULL) {
+ return (NULL);
+ } else {
+ s = (char *)hal_device_property_get_string (parent, "info.bus");
+ if ((s == NULL) || (strcmp (s, "pci") != 0)) {
+ return (NULL);
+ }
+ }
+ }
+
+ d = hal_device_new ();
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+
+ hal_device_property_set_string (d, "info.bus", "pci");
+
+ vid = pid = svid = spid = 0;
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "vendor-id", &i) > 0) {
+ vid = i[0];
+ }
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "device-id", &i) > 0) {
+ pid = i[0];
+ }
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "subsystem-vendor-id", &i) > 0) {
+ svid = i[0];
+ }
+ if (di_prop_lookup_ints (DDI_DEV_T_ANY, node, "subsystem-id", &i) > 0) {
+ spid = i[0];
+ }
+ hal_device_property_set_int (d, "pci.vendor_id", vid);
+ hal_device_property_set_int (d, "pci.product_id", pid);
+ hal_device_property_set_int (d, "pci.subsys_vendor_id", svid);
+ hal_device_property_set_int (d, "pci.subsys_product_id", spid);
+
+ {
+ char *vendor_name;
+ char *product_name;
+ char *subsys_vendor_name;
+ char *subsys_product_name;
+
+ ids_find_pci (hal_device_property_get_int (d, "pci.vendor_id"),
+ hal_device_property_get_int (d, "pci.product_id"),
+ hal_device_property_get_int (d, "pci.subsys_vendor_id"),
+ hal_device_property_get_int (d, "pci.subsys_product_id"),
+ &vendor_name, &product_name, &subsys_vendor_name,
+&subsys_product_name);
+
+ if (vendor_name != NULL) {
+ hal_device_property_set_string (d, "pci.vendor", vendor_name);
+ hal_device_property_set_string (d, "info.vendor", vendor_name);
+ }
+
+ if (product_name != NULL) {
+ hal_device_property_set_string (d, "pci.product", product_name);
+ hal_device_property_set_string (d, "info.product", product_name);
+ }
+
+ if (subsys_vendor_name != NULL) {
+ hal_device_property_set_string (d, "pci.subsys_vendor",
+subsys_vendor_name);
+ }
+
+ if (subsys_product_name != NULL) {
+ hal_device_property_set_string (d, "pci.subsys_product", subsys_product_name);
+ }
+ }
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_pci_handler);
+
+ return (d);
+}
+
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_pci.h b/usr/src/cmd/hal/hald/solaris/devinfo_pci.h
new file mode 100644
index 0000000000..441e6f45da
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_pci.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *
+ * devinfo_pci.h : definitions for PCI devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_PCI_H
+#define DEVINFO_PCI_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_pci_handler;
+
+#endif /* DEVINFO_PCI_H */
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_storage.c b/usr/src/cmd/hal/hald/solaris/devinfo_storage.c
new file mode 100644
index 0000000000..164e2d9185
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_storage.c
@@ -0,0 +1,1669 @@
+/***************************************************************************
+ *
+ * devinfo_storage.c : storage devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <libdevinfo.h>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../hald_runner.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_misc.h"
+#include "devinfo_storage.h"
+#include "osspec_solaris.h"
+
+#ifdef sparc
+#define WHOLE_DISK "s2"
+#else
+#define WHOLE_DISK "p0"
+#endif
+
+/* some devices,especially CDROMs, may take a while to be probed (values in ms) */
+#define DEVINFO_PROBE_STORAGE_TIMEOUT 60000
+#define DEVINFO_PROBE_VOLUME_TIMEOUT 60000
+
+typedef struct devinfo_storage_minor {
+ char *devpath;
+ char *devlink;
+ char *slice;
+ dev_t dev;
+ int dosnum; /* dos disk number or -1 */
+} devinfo_storage_minor_t;
+
+HalDevice *devinfo_ide_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_ide_host_add(HalDevice *parent, di_node_t node, char *devfs_path);
+static HalDevice *devinfo_ide_device_add(HalDevice *parent, di_node_t node, char *devfs_path);
+static HalDevice *devinfo_ide_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path);
+HalDevice *devinfo_scsi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_scsi_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path);
+HalDevice *devinfo_floppy_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static void devinfo_floppy_add_volume(HalDevice *parent, di_node_t node);
+static HalDevice *devinfo_lofi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static void devinfo_lofi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, char *devlink, dev_t dev);
+static int walk_devlinks(di_devlink_t devlink, void *arg);
+static char *get_devlink(di_devlink_handle_t devlink_hdl, char *path);
+static void devinfo_storage_minors(HalDevice *parent, di_node_t node, gchar *devfs_path, gboolean);
+static struct devinfo_storage_minor *devinfo_storage_new_minor(char *maindev_path, char *slice,
+ char *devlink, dev_t dev, int dosnum);
+static void devinfo_storage_free_minor(struct devinfo_storage_minor *m);
+HalDevice *devinfo_volume_add(HalDevice *parent, di_node_t node, devinfo_storage_minor_t *m);
+static void devinfo_volume_preprobing_done(HalDevice *d, gpointer userdata1, gpointer userdata2);
+static void devinfo_volume_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
+static void devinfo_storage_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token);
+static void devinfo_storage_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2);
+const gchar *devinfo_volume_get_prober (HalDevice *d, int *timeout);
+const gchar *devinfo_storage_get_prober (HalDevice *d, int *timeout);
+
+static char *devinfo_scsi_dtype2str(int dtype);
+static char *devinfo_volume_get_slice_name (char *devlink);
+static gboolean dos_to_dev(char *path, char **devpath, int *partnum);
+static gboolean is_dos_path(char *path, int *partnum);
+
+static void devinfo_storage_set_nicknames (HalDevice *d);
+
+DevinfoDevHandler devinfo_ide_handler = {
+ devinfo_ide_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_scsi_handler = {
+ devinfo_scsi_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_floppy_handler = {
+ devinfo_floppy_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_lofi_handler = {
+ devinfo_lofi_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+DevinfoDevHandler devinfo_storage_handler = {
+ NULL,
+ NULL,
+ devinfo_storage_hotplug_begin_add,
+ NULL,
+ devinfo_storage_probing_done,
+ devinfo_storage_get_prober
+};
+DevinfoDevHandler devinfo_volume_handler = {
+ NULL,
+ NULL,
+ devinfo_volume_hotplug_begin_add,
+ NULL,
+ NULL,
+ devinfo_volume_get_prober
+};
+
+/* IDE */
+
+HalDevice *
+devinfo_ide_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ char *s;
+
+ if ((device_type != NULL) && (strcmp(device_type, "ide") == 0)) {
+ return (devinfo_ide_host_add(parent, node, devfs_path));
+ }
+
+ if ((di_prop_lookup_strings (DDI_DEV_T_ANY, node, "class", &s) > 0) &&
+ (strcmp (s, "dada") == 0)) {
+ return (devinfo_ide_device_add(parent, node, devfs_path));
+ }
+
+ return (NULL);
+}
+
+static HalDevice *
+devinfo_ide_host_add(HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.product", "IDE host controller");
+ hal_device_property_set_string (d, "info.bus", "ide_host");
+ hal_device_property_set_int (d, "ide_host.number", 0); /* XXX */
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_ide_handler);
+
+ return (d);
+}
+
+static HalDevice *
+devinfo_ide_device_add(HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+
+ d = hal_device_new();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (parent, "info.product", "IDE device");
+ hal_device_property_set_string (parent, "info.bus", "ide");
+ hal_device_property_set_int (parent, "ide.host", 0); /* XXX */
+ hal_device_property_set_int (parent, "ide.channel", 0);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_ide_handler);
+
+ return (devinfo_ide_storage_add (parent, d, node, devfs_path));
+}
+
+static HalDevice *
+devinfo_ide_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+ char *s;
+ int *i;
+ char *driver_name;
+ char udi[HAL_PATH_MAX];
+
+ if ((driver_name = di_driver_name (node)) == NULL) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/%s%d", parent->udi, driver_name, di_instance (node));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+ PROP_STR(d, node, s, "devid", "info.product");
+
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "storage.bus", "ide");
+ hal_device_property_set_int (d, "storage.lun", 0);
+ hal_device_property_set_string (d, "storage.drive_type", "disk");
+
+ PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
+ PROP_BOOL(d, node, i, "removable-media", "storage.removable");
+
+ hal_device_property_set_bool (d, "storage.media_check_enabled", FALSE);
+
+ /* XXX */
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+
+ hal_device_add_capability (d, "block");
+
+ devinfo_storage_minors (d, node, (char *)devfs_path, FALSE);
+
+ return (d);
+}
+
+/* SCSI */
+
+HalDevice *
+devinfo_scsi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ int *i;
+ char *driver_name;
+ HalDevice *d;
+ char udi[HAL_PATH_MAX];
+
+ driver_name = di_driver_name (node);
+ if ((driver_name == NULL) || (strcmp (driver_name, "sd") != 0)) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.bus", "scsi");
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/%s%d", parent->udi, di_node_name(node), di_instance (node));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+
+ hal_device_property_set_int (d, "scsi.host",
+ hal_device_property_get_int (parent, "scsi_host.host"));
+ hal_device_property_set_int (d, "scsi.bus", 0);
+ PROP_INT(d, node, i, "target", "scsi.target");
+ PROP_INT(d, node, i, "lun", "scsi.lun");
+ hal_device_property_set_string (d, "info.product", "SCSI Device");
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_scsi_handler);
+
+ return (devinfo_scsi_storage_add (parent, d, node, devfs_path));
+}
+
+static HalDevice *
+devinfo_scsi_storage_add(HalDevice *grampa, HalDevice *parent, di_node_t node, char *devfs_path)
+{
+ HalDevice *d;
+ int *i;
+ char *s;
+ char udi[HAL_PATH_MAX];
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/sd%d", parent->udi, di_instance (node));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+ PROP_STR(d, node, s, "inquiry-product-id", "info.product");
+
+ hal_device_add_capability (d, "storage");
+
+ hal_device_property_set_int (d, "storage.lun",
+ hal_device_property_get_int (parent, "scsi.lun"));
+ PROP_BOOL(d, node, i, "hotpluggable", "storage.hotpluggable");
+ PROP_BOOL(d, node, i, "removable-media", "storage.removable");
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+
+ /*
+ * We have to enable polling not only for drives with removable media,
+ * but also for hotpluggable devices, because when a disk is
+ * unplugged while busy/mounted, there is not sysevent generated.
+ * Instead, the HBA driver (scsa2usb, scsa1394) will notify sd driver
+ * and the latter will report DKIO_DEV_GONE via DKIOCSTATE ioctl.
+ * So we have to enable media check so that hald-addon-storage notices
+ * the "device gone" condition and unmounts all associated volumes.
+ */
+ hal_device_property_set_bool (d, "storage.media_check_enabled",
+ ((di_prop_lookup_ints(DDI_DEV_T_ANY, node, "removable-media", &i) >= 0) ||
+ (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "hotpluggable", &i) >= 0)));
+
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
+ &i) > 0) {
+ s = devinfo_scsi_dtype2str (*i);
+ hal_device_property_set_string (d, "storage.drive_type", s);
+
+ if (strcmp (s, "cdrom") == 0) {
+ hal_device_add_capability (d, "storage.cdrom");
+ hal_device_property_set_bool (d, "storage.no_partitions_hint", TRUE);
+ hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
+ }
+ }
+
+ hal_device_add_capability (d, "block");
+
+ devinfo_storage_minors (d, node, devfs_path, FALSE);
+
+ return (d);
+}
+
+static char *devinfo_scsi_dtype2str(int dtype)
+{
+ char *dtype2str[] = {
+ "disk" , /* DTYPE_DIRECT 0x00 */
+ "tape" , /* DTYPE_SEQUENTIAL 0x01 */
+ "printer", /* DTYPE_PRINTER 0x02 */
+ "processor", /* DTYPE_PROCESSOR 0x03 */
+ "worm" , /* DTYPE_WORM 0x04 */
+ "cdrom" , /* DTYPE_RODIRECT 0x05 */
+ "scanner", /* DTYPE_SCANNER 0x06 */
+ "cdrom" , /* DTYPE_OPTICAL 0x07 */
+ "changer", /* DTYPE_CHANGER 0x08 */
+ "comm" , /* DTYPE_COMM 0x09 */
+ "scsi" , /* DTYPE_??? 0x0A */
+ "scsi" , /* DTYPE_??? 0x0B */
+ "array_ctrl", /* DTYPE_ARRAY_CTRL 0x0C */
+ "esi" , /* DTYPE_ESI 0x0D */
+ "disk" /* DTYPE_RBC 0x0E */
+ };
+
+ if (dtype < NELEM(dtype2str)) {
+ return (dtype2str[dtype]);
+ } else {
+ return ("scsi");
+ }
+
+}
+
+/* floppy */
+
+HalDevice *
+devinfo_floppy_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ char *driver_name;
+ char *raw;
+ char udi[HAL_PATH_MAX];
+ di_devlink_handle_t devlink_hdl;
+ int major;
+ di_minor_t minor;
+ dev_t dev;
+ HalDevice *d = NULL;
+ char *minor_path = NULL;
+ char *devlink = NULL;
+
+ driver_name = di_driver_name (node);
+ if ((driver_name == NULL) || (strcmp (driver_name, "fd") != 0)) {
+ return (NULL);
+ }
+
+ /*
+ * The only minor node we're interested in is /dev/diskette*
+ */
+ major = di_driver_major(node);
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ return (NULL);
+ }
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ dev = di_minor_devt(minor);
+ if ((major != major(dev)) ||
+ (di_minor_type(minor) != DDM_MINOR) ||
+ (di_minor_spectype(minor) != S_IFBLK) ||
+ ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
+ continue;
+ }
+ if (((devlink = get_devlink(devlink_hdl, minor_path)) != NULL) &&
+ (strncmp (devlink, "/dev/diskette", sizeof ("/dev/diskette") - 1) == 0)) {
+ break;
+ }
+ di_devfs_path_free (minor_path);
+ minor_path = NULL;
+ free(devlink);
+ devlink = NULL;
+ }
+ di_devlink_fini (&devlink_hdl);
+
+ if ((devlink == NULL) || (minor_path == NULL)) {
+ HAL_INFO (("floppy devlink not found %s", devfs_path));
+ goto out;
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "storage.bus", "platform");
+ hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
+ hal_device_property_set_bool (d, "storage.removable", TRUE);
+ hal_device_property_set_bool (d, "storage.requires_eject", TRUE);
+ hal_device_property_set_bool (d, "storage.media_check_enabled", FALSE);
+ hal_device_property_set_string (d, "storage.drive_type", "floppy");
+
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_bool (d, "block.is_volume", FALSE);
+ hal_device_property_set_int (d, "block.major", major(dev));
+ hal_device_property_set_int (d, "block.minor", minor(dev));
+ hal_device_property_set_string (d, "block.device", devlink);
+ raw = dsk_to_rdsk (devlink);
+ hal_device_property_set_string (d, "block.solaris.raw_device", raw);
+ free (raw);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_storage_handler);
+
+ /* trigger initial probe-volume */
+ devinfo_floppy_add_volume(d, node);
+
+out:
+ di_devfs_path_free (minor_path);
+ free(devlink);
+
+ return (d);
+}
+
+static void
+devinfo_floppy_add_volume(HalDevice *parent, di_node_t node)
+{
+ char *devlink;
+ char *devfs_path;
+ int minor, major;
+ dev_t dev;
+ struct devinfo_storage_minor *m;
+
+ devfs_path = (char *)hal_device_property_get_string (parent, "solaris.devfs_path");
+ devlink = (char *)hal_device_property_get_string (parent, "block.device");
+ major = hal_device_property_get_int (parent, "block.major");
+ minor = hal_device_property_get_int (parent, "block.minor");
+ dev = makedev (major, minor);
+
+ m = devinfo_storage_new_minor (devfs_path, WHOLE_DISK, devlink, dev, -1);
+ devinfo_volume_add (parent, node, m);
+ devinfo_storage_free_minor (m);
+}
+
+/*
+ * After reprobing storage, reprobe its volumes.
+ */
+static void
+devinfo_floppy_rescan_probing_done (HalDevice *d, guint32 exit_type, gint return_code,
+ char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ const char *devfs_path;
+ di_node_t node;
+ HalDevice *v;
+
+ if (!hal_device_property_get_bool (d, "storage.removable.media_available")) {
+ HAL_INFO (("no floppy media", d->udi));
+
+ /* remove child (can only be single volume) */
+ if (((v = hal_device_store_match_key_value_string (hald_get_gdl(),
+ "info.parent", d->udi)) != NULL) &&
+ ((devfs_path = hal_device_property_get_string (v,
+ "solaris.devfs_path")) != NULL)) {
+ devinfo_remove_enqueue ((char *)devfs_path, NULL);
+ }
+ } else {
+ HAL_INFO (("floppy media found", d->udi));
+
+ if ((devfs_path = hal_device_property_get_string(d, "solaris.devfs_path")) == NULL) {
+ HAL_INFO (("no devfs_path", d->udi));
+ hotplug_event_process_queue ();
+ return;
+ }
+ if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("di_init %s failed %d", devfs_path, errno));
+ hotplug_event_process_queue ();
+ return;
+ }
+
+ devinfo_floppy_add_volume (d, node);
+
+ di_fini (node);
+ }
+
+ hotplug_event_process_queue ();
+}
+
+/* lofi */
+
+HalDevice *
+devinfo_lofi_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ return (devinfo_lofi_add_major(parent,node, devfs_path, device_type, FALSE, NULL));
+}
+
+HalDevice *
+devinfo_lofi_add_major(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type,
+ gboolean rescan, HalDevice *lofi_d)
+{
+ char *driver_name;
+ HalDevice *d = NULL;
+ char udi[HAL_PATH_MAX];
+ di_devlink_handle_t devlink_hdl;
+ int major;
+ di_minor_t minor;
+ dev_t dev;
+ char *minor_path = NULL;
+ char *devpath, *devlink;
+
+ driver_name = di_driver_name (node);
+ if ((driver_name == NULL) || (strcmp (driver_name, "lofi") != 0)) {
+ return (NULL);
+ }
+
+ if (!rescan) {
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.bus", "pseudo");
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/%s%d", parent->udi, di_node_name(node), di_instance (node));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_lofi_handler);
+ } else {
+ d = lofi_d;
+ }
+
+ /*
+ * Unlike normal storage, as in devinfo_storage_minors(), where
+ * sd instance -> HAL storage, sd minor node -> HAL volume,
+ * lofi always has one instance, lofi minor -> HAL storage.
+ * lofi storage never has slices, but it can have
+ * embedded pcfs partitions that fstyp would recognize
+ */
+ major = di_driver_major(node);
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ return (d);
+ }
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ dev = di_minor_devt(minor);
+ if ((major != major(dev)) ||
+ (di_minor_type(minor) != DDM_MINOR) ||
+ (di_minor_spectype(minor) != S_IFBLK) ||
+ ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
+ continue;
+ }
+ if ((devlink = get_devlink(devlink_hdl, minor_path)) == NULL) {
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ if (!rescan ||
+ (hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", minor_path) == NULL)) {
+ devinfo_lofi_add_minor(d, node, minor_path, devlink, dev);
+ }
+
+ di_devfs_path_free (minor_path);
+ free(devlink);
+ }
+ di_devlink_fini (&devlink_hdl);
+
+ return (d);
+}
+
+static void
+devinfo_lofi_add_minor(HalDevice *parent, di_node_t node, char *minor_path, char *devlink, dev_t dev)
+{
+ HalDevice *d;
+ char *raw;
+ char *doslink;
+ char dospath[64];
+ struct devinfo_storage_minor *m;
+ int i;
+
+ /* add storage */
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, minor_path);
+ hal_device_property_set_string (d, "info.category", "storage");
+ hal_device_add_capability (d, "storage");
+ hal_device_property_set_string (d, "storage.bus", "lofi");
+ hal_device_property_set_bool (d, "storage.hotpluggable", TRUE);
+ hal_device_property_set_bool (d, "storage.removable", FALSE);
+ hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
+ hal_device_property_set_string (d, "storage.drive_type", "disk");
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_int (d, "block.major", major(dev));
+ hal_device_property_set_int (d, "block.minor", minor(dev));
+ hal_device_property_set_string (d, "block.device", devlink);
+ raw = dsk_to_rdsk (devlink);
+ hal_device_property_set_string (d, "block.solaris.raw_device", raw);
+ free (raw);
+ hal_device_property_set_bool (d, "block.is_volume", FALSE);
+
+ devinfo_add_enqueue (d, minor_path, &devinfo_storage_handler);
+
+ /* add volumes: one on main device and a few pcfs candidates */
+ m = devinfo_storage_new_minor(minor_path, WHOLE_DISK, devlink, dev, -1);
+ devinfo_volume_add (d, node, m);
+ devinfo_storage_free_minor (m);
+
+ doslink = (char *)calloc (1, strlen (devlink) + sizeof (":NNN") + 1);
+ if (doslink != NULL) {
+ for (i = 1; i < 16; i++) {
+ snprintf(dospath, sizeof (dospath), WHOLE_DISK":%d", i);
+ sprintf(doslink, "%s:%d", devlink, i);
+ m = devinfo_storage_new_minor(minor_path, dospath, doslink, dev, i);
+ devinfo_volume_add (d, node, m);
+ devinfo_storage_free_minor (m);
+ }
+ free (doslink);
+ }
+}
+
+void
+devinfo_lofi_remove_minor(char *parent_devfs_path, char *name)
+{
+ GSList *i;
+ GSList *devices;
+ HalDevice *d = NULL;
+ const char *devfs_path;
+
+ devices = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
+ "block.solaris.raw_device", name);
+ for (i = devices; i != NULL; i = g_slist_next (i)) {
+ if (hal_device_has_capability (HAL_DEVICE (i->data), "storage")) {
+ d = HAL_DEVICE (i->data);
+ break;
+ }
+ }
+ g_slist_free (devices);
+
+ if (d == NULL) {
+ HAL_INFO (("device not found %s", name));
+ return;
+ }
+
+ if ((devfs_path = hal_device_property_get_string (d,
+ "solaris.devfs_path")) == NULL) {
+ HAL_INFO (("devfs_path not found %s", d->udi));
+ return;
+ }
+
+ if (d != NULL) {
+ devinfo_remove_branch ((char *)devfs_path, d);
+ }
+}
+
+/* common storage */
+
+static int
+walk_devlinks(di_devlink_t devlink, void *arg)
+{
+ char **path= (char **)arg;
+
+ *path = strdup(di_devlink_path(devlink));
+
+ return (DI_WALK_TERMINATE);
+}
+
+static char *
+get_devlink(di_devlink_handle_t devlink_hdl, char *path)
+{
+ char *devlink_path = NULL;
+
+ (void) di_devlink_walk(devlink_hdl, NULL, path,
+ DI_PRIMARY_LINK, &devlink_path, walk_devlinks);
+
+ return (devlink_path);
+}
+
+static void
+devinfo_storage_free_minor(struct devinfo_storage_minor *m)
+{
+ if (m != NULL) {
+ free (m->slice);
+ free (m->devlink);
+ free (m->devpath);
+ free (m);
+ }
+}
+
+static struct devinfo_storage_minor *
+devinfo_storage_new_minor(char *maindev_path, char *slice, char *devlink, dev_t dev, int dosnum)
+{
+ struct devinfo_storage_minor *m;
+ int pathlen;
+ char *devpath;
+
+ m = (struct devinfo_storage_minor *)calloc (sizeof (struct devinfo_storage_minor), 1);
+ if (m != NULL) {
+ /*
+ * For volume's devfs_path we'll use minor_path/slice instead of
+ * minor_path which we use for parent storage device.
+ */
+ pathlen = strlen (maindev_path) + strlen (slice) + 2;
+ devpath = (char *)calloc (1, pathlen);
+ snprintf(devpath, pathlen, "%s/%s", maindev_path, slice);
+
+ m->devpath = devpath;
+ m->devlink = strdup (devlink);
+ m->slice = strdup (slice);
+ m->dev = dev;
+ m->dosnum = dosnum;
+ if ((m->devpath == NULL) || (m->devlink == NULL)) {
+ devinfo_storage_free_minor (m);
+ m = NULL;
+ }
+ }
+ return (m);
+}
+
+/*
+ * Storage minor nodes are potential "volume" objects.
+ * This function also completes building the parent object (main storage device).
+ */
+static void
+devinfo_storage_minors(HalDevice *parent, di_node_t node, gchar *devfs_path, gboolean rescan)
+{
+ di_devlink_handle_t devlink_hdl;
+ gboolean is_cdrom;
+ const char *whole_disk;
+ int major;
+ di_minor_t minor;
+ dev_t dev;
+ char *minor_path = NULL;
+ char *maindev_path = NULL;
+ char *devpath, *devlink;
+ int doslink_len;
+ char *doslink;
+ char dospath[64];
+ char *slice;
+ int pathlen;
+ int i;
+ char *raw;
+ boolean_t maindev_is_d0;
+ GQueue *mq;
+ HalDevice *volume;
+ struct devinfo_storage_minor *m;
+ struct devinfo_storage_minor *maindev = NULL;
+
+ /* for cdroms whole disk is always s2 */
+ is_cdrom = hal_device_has_capability (parent, "storage.cdrom");
+ whole_disk = is_cdrom ? "s2" : WHOLE_DISK;
+
+ major = di_driver_major(node);
+
+ /* the "whole disk" p0/s2/d0 node must come first in the hotplug queue
+ * so we put other minor nodes on the local queue and move to the
+ * hotplug queue up in the end
+ */
+ if ((mq = g_queue_new()) == NULL) {
+ goto err;
+ }
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ g_queue_free (mq);
+ goto err;
+ }
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ dev = di_minor_devt(minor);
+ if ((major != major(dev)) ||
+ (di_minor_type(minor) != DDM_MINOR) ||
+ (di_minor_spectype(minor) != S_IFBLK) ||
+ ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
+ continue;
+ }
+ if ((devlink = get_devlink(devlink_hdl, minor_path)) == NULL) {
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ slice = devinfo_volume_get_slice_name (devlink);
+ if (strlen (slice) < 2) {
+ free (devlink);
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ /* ignore p1..N - we'll use p0:N instead */
+ if ((strlen (slice) > 1) && (slice[0] == 'p') && isdigit(slice[1]) &&
+ ((atol(&slice[1])) > 0)) {
+ free (devlink);
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ m = devinfo_storage_new_minor(minor_path, slice, devlink, dev, -1);
+ if (m == NULL) {
+ free (devlink);
+ di_devfs_path_free (minor_path);
+ continue;
+ }
+
+ /* main device is either s2/p0 or d0, the latter taking precedence */
+ if ((strcmp (slice, "d0") == 0) ||
+ (((strcmp (slice, whole_disk) == 0) && (maindev == NULL)))) {
+ if (maindev_path != NULL) {
+ di_devfs_path_free (maindev_path);
+ }
+ maindev_path = minor_path;
+ maindev = m;
+ g_queue_push_head (mq, maindev);
+ } else {
+ di_devfs_path_free (minor_path);
+ g_queue_push_tail (mq, m);
+ }
+
+ free (devlink);
+ }
+ di_devlink_fini (&devlink_hdl);
+
+ if (maindev == NULL) {
+ /* shouldn't typically happen */
+ while (!g_queue_is_empty (mq)) {
+ devinfo_storage_free_minor (g_queue_pop_head (mq));
+ }
+ goto err;
+ }
+
+ /* first enqueue main storage device */
+ if (!rescan) {
+ hal_device_property_set_int (parent, "block.major", major);
+ hal_device_property_set_int (parent, "block.minor", minor(maindev->dev));
+ hal_device_property_set_string (parent, "block.device", maindev->devlink);
+ raw = dsk_to_rdsk (maindev->devlink);
+ hal_device_property_set_string (parent, "block.solaris.raw_device", raw);
+ free (raw);
+ hal_device_property_set_bool (parent, "block.is_volume", FALSE);
+ hal_device_property_set_string (parent, "solaris.devfs_path", maindev_path);
+ devinfo_add_enqueue (parent, maindev_path, &devinfo_storage_handler);
+ }
+
+ /* add virtual dos volumes to enable pcfs probing */
+ if (!is_cdrom) {
+ doslink_len = strlen (maindev->devlink) + sizeof (":NNN") + 1;
+ if ((doslink = (char *)calloc (1, doslink_len)) != NULL) {
+ for (i = 1; i < 16; i++) {
+ snprintf(dospath, sizeof (dospath), "%s:%d", maindev->slice, i);
+ snprintf(doslink, doslink_len, "%s:%d", maindev->devlink, i);
+ m = devinfo_storage_new_minor(maindev_path, dospath, doslink, maindev->dev, i);
+ g_queue_push_tail (mq, m);
+ }
+ free (doslink);
+ }
+ }
+
+ maindev_is_d0 = (strcmp (maindev->slice, "d0") == 0);
+
+ /* enqueue all volumes */
+ while (!g_queue_is_empty (mq)) {
+ m = g_queue_pop_head (mq);
+
+ /* if main device is d0, we'll throw away s2/p0 */
+ if (maindev_is_d0 && (strcmp (m->slice, whole_disk) == 0)) {
+ devinfo_storage_free_minor (m);
+ continue;
+ }
+ /* don't do p0 on cdrom */
+ if (is_cdrom && (strcmp (m->slice, "p0") == 0)) {
+ devinfo_storage_free_minor (m);
+ continue;
+ }
+ if (rescan) {
+ /* in rescan mode, don't reprobe existing volumes */
+ /* XXX detect volume removal? */
+ volume = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", m->devpath);
+ if ((volume == NULL) || !hal_device_has_capability(volume, "volume")) {
+ devinfo_volume_add (parent, node, m);
+ } else {
+ HAL_INFO(("rescan volume exists %s", m->devpath));
+ }
+ } else {
+ devinfo_volume_add (parent, node, m);
+ }
+ devinfo_storage_free_minor (m);
+ }
+
+ if (maindev_path != NULL) {
+ di_devfs_path_free (maindev_path);
+ }
+
+ return;
+
+err:
+ if (maindev_path != NULL) {
+ di_devfs_path_free (maindev_path);
+ }
+ if (!rescan) {
+ devinfo_add_enqueue (parent, devfs_path, &devinfo_storage_handler);
+ }
+}
+
+HalDevice *
+devinfo_volume_add(HalDevice *parent, di_node_t node, devinfo_storage_minor_t *m)
+{
+ HalDevice *d;
+ char *raw;
+ char udi[HAL_PATH_MAX];
+ char *devfs_path = m->devpath;
+ char *devlink = m->devlink;
+ dev_t dev = m->dev;
+ int dosnum = m->dosnum;
+ char *slice = m->slice;
+
+ HAL_INFO (("volume_add: devfs_path=%s devlink=%s", devfs_path, devlink));
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.category", "volume");
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/%s", parent->udi, slice);
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+ hal_device_property_set_string (d, "info.product", slice);
+
+ hal_device_add_capability (d, "volume");
+ hal_device_add_capability (d, "block");
+ hal_device_property_set_int (d, "block.major", major (dev));
+ hal_device_property_set_int (d, "block.minor", minor (dev));
+ hal_device_property_set_string (d, "block.device", devlink);
+ raw = dsk_to_rdsk (devlink);
+ hal_device_property_set_string (d, "block.solaris.raw_device", raw);
+ free (raw);
+ hal_device_property_set_string (d, "block.solaris.slice", slice);
+ hal_device_property_set_bool (d, "block.is_volume", TRUE); /* XXX */
+
+ hal_device_property_set_string (d, "block.storage_device", parent->udi);
+
+ /* set volume defaults */
+ hal_device_property_set_string (d, "volume.fstype", "");
+ hal_device_property_set_string (d, "volume.fsusage", "");
+ hal_device_property_set_string (d, "volume.fsversion", "");
+ hal_device_property_set_string (d, "volume.uuid", "");
+ hal_device_property_set_string (d, "volume.label", "");
+ hal_device_property_set_string (d, "volume.mount_point", "");
+ hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
+ if (strcmp (hal_device_property_get_string (parent, "storage.drive_type"), "cdrom") == 0) {
+ hal_device_property_set_bool (d, "volume.is_disc", TRUE);
+ hal_device_add_capability (d, "volume.disc");
+ } else {
+ hal_device_property_set_bool (d, "volume.is_disc", FALSE);
+ }
+
+ if (dosnum > 0) {
+ hal_device_property_set_bool (d, "volume.is_partition", TRUE);
+ hal_device_property_set_int (d, "volume.partition.number", dosnum);
+ } else {
+ hal_device_property_set_bool (d, "volume.is_partition", FALSE);
+ }
+
+ /* prober may override these */
+ hal_device_property_set_int (d, "volume.block_size", 512);
+
+ devinfo_add_enqueue (d, devfs_path, &devinfo_volume_handler);
+
+ return (d);
+}
+
+static void
+devinfo_volume_preprobing_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ char *whole_disk;
+ char *block_device;
+ const char *storage_udi;
+ HalDevice *storage_d;
+ const char *slice;
+ int dos_num;
+
+ if (hal_device_property_get_bool (d, "info.ignore")) {
+ HAL_INFO (("Preprobing merged info.ignore==TRUE %s", d->udi));
+ goto skip;
+ }
+
+ /*
+ * Optimizations: only probe if there's a chance to find something
+ */
+ block_device = (char *)hal_device_property_get_string (d, "block.device");
+ storage_udi = hal_device_property_get_string (d, "block.storage_device");
+ slice = hal_device_property_get_string(d, "block.solaris.slice");
+ if ((block_device == NULL) || (storage_udi == NULL) ||
+ (slice == NULL) || (strlen (slice) < 2)) {
+ HAL_INFO (("Malformed volume properties %s", d->udi));
+ goto skip;
+ }
+ storage_d = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", storage_udi);
+ if (storage_d == NULL) {
+ HAL_INFO (("Storage device not found %s", d->udi));
+ goto skip;
+ }
+
+ whole_disk = hal_device_has_capability (storage_d,
+ "storage.cdrom") ? "s2" : WHOLE_DISK;
+
+ if (is_dos_path(block_device, &dos_num)) {
+ /* don't probe more dos volumes than probe-storage found */
+ if ((hal_device_property_get_bool (storage_d, "storage.no_partitions_hint") ||
+ (dos_num > hal_device_property_get_int (storage_d, "storage.solaris.num_dos_partitions")))) {
+ HAL_INFO (("%d > %d %s", dos_num, hal_device_property_get_int (storage_d,
+ "storage.solaris.num_dos_partitions"), storage_d->udi));
+ goto skip;
+ }
+ } else {
+ /* if no VTOC slices found, don't probe slices except s2 */
+ if ((slice[0] == 's') && (isdigit(slice[1])) && ((strcmp (slice, whole_disk)) != 0) &&
+ !hal_device_property_get_bool (storage_d, "storage.solaris.vtoc_slices")) {
+ HAL_INFO (("Not probing slice %s", d->udi));
+ goto skip;
+ }
+ }
+
+ HAL_INFO(("Probing udi=%s", d->udi));
+ hald_runner_run (d,
+ "hald-probe-volume", NULL,
+ DEVINFO_PROBE_VOLUME_TIMEOUT,
+ devinfo_callouts_probing_done,
+ (gpointer) end_token, userdata2);
+
+ return;
+
+skip:
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+}
+
+static void
+devinfo_volume_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
+{
+ HAL_INFO(("Preprobing volume udi=%s", d->udi));
+
+ if (hal_device_property_get_bool (parent, "info.ignore")) {
+ HAL_INFO (("Ignoring volume: parent's info.ignore is TRUE"));
+ goto skip;
+ }
+
+ /* add to TDL so preprobing callouts and prober can access it */
+ hal_device_store_add (hald_get_tdl (), d);
+
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+
+ /* Run preprobe callouts */
+ hal_util_callout_device_preprobe (d, devinfo_volume_preprobing_done, end_token, handler);
+
+ return;
+
+skip:
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+}
+
+void
+devinfo_storage_hotplug_begin_add (HalDevice *d, HalDevice *parent, DevinfoDevHandler *handler, void *end_token)
+{
+ const char *drive_type;
+ const char *p_udi;
+ HalDevice *p_d;
+ HalDevice *phys_d = NULL;
+ const char *phys_bus;
+ const char *bus;
+ static const char *busses[] = { "usb", "ide", "scsi", "ieee1394",
+ "pseudo" };
+ int i;
+
+ HAL_INFO (("Preprobing udi=%s", d->udi));
+
+ if (parent == NULL) {
+ HAL_INFO (("no parent %s", d->udi));
+ goto error;
+ }
+
+ /*
+ * figure out physical device and bus, except for floppy
+ */
+ drive_type = hal_device_property_get_string (d, "storage.drive_type");
+ if ((drive_type != NULL) && (strcmp (drive_type, "floppy") == 0)) {
+ goto skip_bus;
+ }
+
+ p_d = parent;
+ for (;;) {
+ bus = hal_device_property_get_string (p_d, "info.bus");
+ if (bus != NULL) {
+ for (i = 0; i < NELEM(busses); i++) {
+ if (strcmp(bus, busses[i]) == 0) {
+ phys_d = p_d;
+ phys_bus = busses[i];
+ break;
+ }
+ }
+ }
+ /* up the tree */
+ p_udi = hal_device_property_get_string (p_d, "info.parent");
+ if (p_udi == NULL) {
+ break;
+ }
+ p_d = hal_device_store_find (hald_get_gdl (), p_udi);
+ }
+ if (phys_d == NULL) {
+ HAL_INFO (("no physical device %s", d->udi));
+ goto error;
+ }
+ hal_device_property_set_string (d, "storage.physical_device", phys_d->udi);
+ hal_device_property_set_string (d, "storage.bus", phys_bus);
+
+skip_bus:
+
+ /* add to TDL so preprobing callouts and prober can access it */
+ hal_device_store_add (hald_get_tdl (), d);
+
+ /* Process preprobe fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_PREPROBE);
+
+ /* Run preprobe callouts */
+ hal_util_callout_device_preprobe (d, devinfo_callouts_preprobing_done, end_token, handler);
+
+ return;
+
+error:
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+}
+
+static void
+devinfo_storage_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+
+ HAL_INFO (("devinfo_storage_probing_done %s", d->udi));
+
+ /* Discard device if probing reports failure */
+ if (exit_type != HALD_RUN_SUCCESS || return_code != 0) {
+ HAL_INFO (("devinfo_storage_probing_done returning exit_type=%d return_code=%d", exit_type, return_code));
+ hal_device_store_remove (hald_get_tdl (), d);
+ g_object_unref (d);
+ hotplug_event_end (end_token);
+ return;
+ }
+
+ devinfo_storage_set_nicknames (d);
+
+ /* Merge properties from .fdi files */
+ di_search_and_merge (d, DEVICE_INFO_TYPE_INFORMATION);
+ di_search_and_merge (d, DEVICE_INFO_TYPE_POLICY);
+
+ hal_util_callout_device_add (d, devinfo_callouts_add_done, end_token, NULL);
+}
+
+const gchar *
+devinfo_storage_get_prober (HalDevice *d, int *timeout)
+{
+ *timeout = DEVINFO_PROBE_STORAGE_TIMEOUT;
+ return "hald-probe-storage";
+}
+
+const gchar *
+devinfo_volume_get_prober (HalDevice *d, int *timeout)
+{
+ *timeout = DEVINFO_PROBE_VOLUME_TIMEOUT;
+ return "hald-probe-volume";
+}
+
+/*
+ * After reprobing storage, reprobe its volumes.
+ */
+static void
+devinfo_storage_rescan_probing_done (HalDevice *d, guint32 exit_type, gint return_code, char **error, gpointer userdata1, gpointer userdata2)
+{
+ void *end_token = (void *) userdata1;
+ const char *devfs_path_orig = NULL;
+ char *devfs_path = NULL;
+ char *p;
+ di_node_t node;
+
+ HAL_INFO (("devinfo_storage_rescan_probing_done %s", d->udi));
+
+ devfs_path_orig = hal_device_property_get_string (d, "solaris.devfs_path");
+ if (devfs_path_orig == NULL) {
+ HAL_INFO (("device has no solaris.devfs_path"));
+ hotplug_event_process_queue ();
+ return;
+ }
+
+ /* strip trailing minor part if any */
+ if (strrchr(devfs_path_orig, ':') != NULL) {
+ if ((devfs_path = strdup (devfs_path_orig)) != NULL) {
+ p = strrchr(devfs_path, ':');
+ *p = '\0';
+ }
+ } else {
+ devfs_path = (char *)devfs_path_orig;
+ }
+
+ if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("di_init %s failed %d %s", devfs_path, errno, d->udi));
+ hotplug_event_process_queue ();
+ return;
+ } else {
+ devinfo_storage_minors (d, node, (char *)devfs_path, TRUE);
+ di_fini (node);
+ }
+
+ if (devfs_path != devfs_path_orig) {
+ free (devfs_path);
+ }
+
+ hotplug_event_process_queue ();
+}
+
+/*
+ * For removable media devices, check for "storage.removable.media_available".
+ * For non-removable media devices, assume media is always there.
+ *
+ * If media is gone, enqueue remove events for all children volumes.
+ * If media is there, first reprobe storage, then probe for new volumes (but leave existing volumes alone).
+ */
+gboolean
+devinfo_storage_device_rescan (HalDevice *d)
+{
+ GSList *i;
+ GSList *volumes;
+ HalDevice *v;
+ gchar *v_devfs_path;
+ const char *drive_type;
+ gboolean is_floppy;
+ gboolean media_available;
+
+ HAL_INFO (("devinfo_storage_device_rescan udi=%s", d->udi));
+
+ if (hal_device_property_get_bool (d, "block.is_volume")) {
+ HAL_INFO (("nothing to do for volume"));
+ return (FALSE);
+ }
+
+ drive_type = hal_device_property_get_string (d, "storage.drive_type");
+ is_floppy = (drive_type != NULL) && (strcmp (drive_type, "floppy") == 0);
+
+ media_available = !hal_device_property_get_bool (d, "storage.removable") ||
+ hal_device_property_get_bool (d, "storage.removable.media_available");
+
+ if (!media_available && !is_floppy) {
+ HAL_INFO (("media gone %s", d->udi));
+
+ volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl(),
+ "block.storage_device", d->udi);
+ for (i = volumes; i != NULL; i = g_slist_next (i)) {
+ v = HAL_DEVICE (i->data);
+ v_devfs_path = (gchar *)hal_device_property_get_string (v, "solaris.devfs_path");
+ HAL_INFO (("child volume %s", v->udi));
+ if ((v_devfs_path != NULL) && hal_device_has_capability (v, "volume")) {
+ HAL_INFO (("removing volume %s", v->udi));
+ devinfo_remove_enqueue (v_devfs_path, NULL);
+ } else {
+ HAL_INFO (("not a volume %s", v->udi));
+ }
+ }
+ g_slist_free (volumes);
+
+ hotplug_event_process_queue ();
+ } else if (is_floppy) {
+ HAL_INFO (("rescanning floppy %s", d->udi));
+
+ hald_runner_run (d,
+ "hald-probe-storage --only-check-for-media", NULL,
+ DEVINFO_PROBE_STORAGE_TIMEOUT,
+ devinfo_floppy_rescan_probing_done,
+ NULL, NULL);
+ } else {
+ HAL_INFO (("media available %s", d->udi));
+
+ hald_runner_run (d,
+ "hald-probe-storage --only-check-for-media", NULL,
+ DEVINFO_PROBE_STORAGE_TIMEOUT,
+ devinfo_storage_rescan_probing_done,
+ NULL, NULL);
+ }
+
+ return TRUE;
+}
+
+static char *
+devinfo_volume_get_slice_name (char *devlink)
+{
+ char *part, *slice, *disk;
+ char *s = NULL;
+ char *p;
+
+ if ((p = strstr(devlink, "/lofi/")) != 0) {
+ return (p + sizeof ("/lofi/") - 1);
+ }
+
+ part = strrchr(devlink, 'p');
+ slice = strrchr(devlink, 's');
+ disk = strrchr(devlink, 'd');
+
+ if ((part != NULL) && (part > slice) && (part > disk)) {
+ s = part;
+ } else if ((slice != NULL) && (slice > disk)) {
+ s = slice;
+ } else {
+ s = disk;
+ }
+ if ((s != NULL) && isdigit(s[1])) {
+ return (s);
+ } else {
+ return ("");
+ }
+}
+
+static gboolean
+is_dos_path(char *path, int *partnum)
+{
+ char *p;
+
+ if ((p = strrchr (path, ':')) == NULL) {
+ return (FALSE);
+ }
+ return ((*partnum = atoi(p + 1)) != 0);
+}
+
+static gboolean
+dos_to_dev(char *path, char **devpath, int *partnum)
+{
+ char *p;
+
+ if ((p = strrchr (path, ':')) == NULL) {
+ return (FALSE);
+ }
+ if ((*partnum = atoi(p + 1)) == 0) {
+ return (FALSE);
+ }
+ p[0] = '\0';
+ *devpath = strdup(path);
+ p[0] = ':';
+ return (*devpath != NULL);
+}
+
+static void
+devinfo_storage_cleanup_mountpoint_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ char *mount_point = (char *) data1;
+
+ HAL_INFO (("Cleaned up mount point '%s'", mount_point));
+ g_free (mount_point);
+}
+
+
+void
+devinfo_storage_mnttab_event (HalDevice *hal_volume)
+{
+ FILE *fp = NULL;
+ struct extmnttab m;
+ HalDevice *d;
+ unsigned int major;
+ unsigned int minor;
+ GSList *volumes = NULL;
+ GSList *v;
+ char *mount_point;
+ dbus_bool_t is_partition;
+ const char *fstype;
+ int partition_number;
+
+ if (hal_volume != NULL) {
+ volumes = g_slist_append (NULL, hal_volume);
+ } else {
+ volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.category", "volume");
+ }
+ if (volumes == NULL) {
+ return;
+ }
+
+ if ((fp = fopen(MNTTAB, "r")) == NULL) {
+ HAL_ERROR (("Open failed %s errno %d", MNTTAB, errno));
+ return;
+ }
+
+ while (getextmntent(fp, &m, 1) == 0) {
+ for (v = volumes; v != NULL; v = g_slist_next (v)) {
+ d = HAL_DEVICE (v->data);
+ major = hal_device_property_get_int (d, "block.major");
+ minor = hal_device_property_get_int (d, "block.minor");
+
+ /*
+ * special handling for pcfs, which encodes logical
+ * drive number into the 6 upper bits of the minor
+ */
+ is_partition = hal_device_property_get_bool (d, "volume.is_partition");
+ partition_number = hal_device_property_get_int (d, "volume.partition.number");
+ fstype = hal_device_property_get_string (d, "volume.fstype");
+
+ if (is_partition && (partition_number > 0) && (strcmp (fstype, "pcfs") == 0)) {
+ minor |= partition_number << 12;
+ }
+
+ if (m.mnt_major != major || m.mnt_minor != minor) {
+ continue;
+ }
+
+ /* this volume matches the mnttab entry */
+ device_property_atomic_update_begin ();
+ hal_device_property_set_bool (d, "volume.is_mounted", TRUE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only",
+ hasmntopt ((struct mnttab *)&m, "ro") ? TRUE : FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", m.mnt_mountp);
+ device_property_atomic_update_end ();
+
+ HAL_INFO (("set %s to be mounted at %s",
+ hal_device_get_udi (d), m.mnt_mountp));
+ volumes = g_slist_delete_link (volumes, v);
+ }
+ }
+
+ /* all remaining volumes are not mounted */
+ for (v = volumes; v != NULL; v = g_slist_next (v)) {
+ d = HAL_DEVICE (v->data);
+ mount_point = g_strdup (hal_device_property_get_string (d, "volume.mount_point"));
+ if (mount_point == NULL || strlen (mount_point) == 0) {
+ g_free (mount_point);
+ continue;
+ }
+
+ device_property_atomic_update_begin ();
+ hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
+ hal_device_property_set_bool (d, "volume.is_mounted_read_only", FALSE);
+ hal_device_property_set_string (d, "volume.mount_point", "");
+ device_property_atomic_update_end ();
+
+ HAL_INFO (("set %s to unmounted", hal_device_get_udi (d)));
+
+ /* cleanup if was mounted by us */
+ if (hal_util_is_mounted_by_hald (mount_point)) {
+ char *cleanup_stdin;
+ char *extra_env[2];
+
+ HAL_INFO (("Cleaning up '%s'", mount_point));
+
+ extra_env[0] = g_strdup_printf ("HALD_CLEANUP=%s", mount_point);
+ extra_env[1] = NULL;
+ cleanup_stdin = "\n";
+
+ hald_runner_run_method (d,
+ "hal-storage-cleanup-mountpoint",
+ extra_env,
+ cleanup_stdin, TRUE,
+ 0,
+ devinfo_storage_cleanup_mountpoint_cb,
+ g_strdup (mount_point), NULL);
+
+ g_free (extra_env[0]);
+ }
+
+ g_free (mount_point);
+ }
+ g_slist_free (volumes);
+
+ (void) fclose (fp);
+}
+
+static void
+devinfo_volume_force_unmount_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ void *end_token = (void *) data1;
+
+ HAL_INFO (("devinfo_volume_force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", d->udi, exit_type, return_code));
+
+ if (exit_type == HALD_RUN_SUCCESS && error != NULL &&
+ error[0] != NULL && error[1] != NULL) {
+ char *exp_name = NULL;
+ char *exp_detail = NULL;
+
+ exp_name = error[0];
+ if (error[0] != NULL) {
+ exp_detail = error[1];
+ }
+ HAL_INFO (("failed with '%s' '%s'", exp_name, exp_detail));
+ }
+
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+}
+
+static void
+devinfo_volume_force_unmount (HalDevice *d, void *end_token)
+{
+ const char *device_file;
+ const char *mount_point;
+ char *unmount_stdin;
+ char *extra_env[2];
+ extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
+ extra_env[1] = NULL;
+
+ device_file = hal_device_property_get_string (d, "block.device");
+ mount_point = hal_device_property_get_string (d, "volume.mount_point");
+
+ if (mount_point == NULL || strlen (mount_point) == 0 || !hal_util_is_mounted_by_hald (mount_point)) {
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+ return;
+ }
+
+ HAL_INFO (("devinfo_volume_force_unmount for udi='%s'", d->udi));
+
+ unmount_stdin = "\n";
+
+ hald_runner_run_method (d,
+ "hal-storage-unmount",
+ extra_env,
+ unmount_stdin, TRUE,
+ 0,
+ devinfo_volume_force_unmount_cb,
+ end_token, NULL);
+}
+
+void
+devinfo_volume_hotplug_begin_remove (HalDevice *d, char *devfs_path, void *end_token)
+{
+ if (hal_device_property_get_bool (d, "volume.is_mounted")) {
+ devinfo_volume_force_unmount (d, end_token);
+ } else {
+ hal_util_callout_device_remove (d, devinfo_callouts_remove_done, end_token, NULL);
+ }
+}
+
+
+enum {
+ LEGACY_CDROM,
+ LEGACY_FLOPPY,
+ LEGACY_RMDISK
+};
+
+static const char *legacy_media_str[] = {
+ "cdrom",
+ "floppy",
+ "rmdisk"
+};
+
+struct enum_nick {
+ const char *type;
+ GSList *nums;
+};
+
+static int
+devinfo_storage_get_legacy_media(HalDevice *d)
+{
+ const char *drive_type;
+
+ if (hal_device_has_capability (d, "storage.cdrom")) {
+ return (LEGACY_CDROM);
+ } else if (((drive_type = hal_device_property_get_string (d,
+ "storage.drive_type")) != NULL) && (strcmp (drive_type, "floppy") == 0)) {
+ return (LEGACY_FLOPPY);
+ } else if (hal_device_property_get_bool (d, "storage.removable") ||
+ hal_device_property_get_bool (d, "storage.hotpluggable")) {
+ return (LEGACY_RMDISK);
+ } else {
+ return (-1);
+ }
+}
+
+static gboolean
+devinfo_storage_foreach_nick (HalDeviceStore *store, HalDevice *d, gpointer user_data)
+{
+ struct enum_nick *en = (struct enum_nick *) user_data;
+ const char *media_type;
+ int media_num;
+
+ media_type = hal_device_property_get_string (d, "storage.solaris.legacy.media_type");
+ media_num = hal_device_property_get_int (d, "storage.solaris.legacy.media_num");
+ if ((media_type != NULL) && (strcmp (media_type, en->type) == 0) &&
+ (media_num >= 0)) {
+ en->nums = g_slist_prepend (en->nums, GINT_TO_POINTER(media_num));
+ }
+ return TRUE;
+}
+
+static void
+devinfo_storage_append_nickname (HalDevice *d, const char *media_type, int media_num)
+{
+ char buf[64];
+
+ if (media_num == 0) {
+ hal_device_property_strlist_append (d, "storage.solaris.nicknames", media_type);
+ }
+ snprintf(buf, sizeof (buf), "%s%d", media_type, media_num);
+ hal_device_property_strlist_append (d, "storage.solaris.nicknames", buf);
+}
+
+static void
+devinfo_storage_set_nicknames (HalDevice *d)
+{
+ int media;
+ const char *media_type;
+ int media_num;
+ GSList *i;
+ struct enum_nick en;
+ char buf[64];
+
+ if ((media = devinfo_storage_get_legacy_media (d)) < 0) {
+ return;
+ }
+ media_type = legacy_media_str[media];
+
+ /* enumerate all storage devices of this media type */
+ en.type = media_type;
+ en.nums = NULL;
+ hal_device_store_foreach (hald_get_gdl (), devinfo_storage_foreach_nick, &en);
+
+ /* find a free number */
+ for (media_num = 0; ; media_num++) {
+ for (i = en.nums; i != NULL; i = g_slist_next (i)) {
+ if (GPOINTER_TO_INT (i->data) == media_num) {
+ break;
+ }
+ }
+ if (i == NULL) {
+ break;
+ }
+ }
+ g_slist_free (en.nums);
+
+ hal_device_property_set_string (d, "storage.solaris.legacy.media_type", media_type);
+ hal_device_property_set_int (d, "storage.solaris.legacy.media_num", media_num);
+
+ /* primary nickname, and also vold-style symdev */
+ snprintf(buf, sizeof (buf), "%s%d", media_type, media_num);
+ hal_device_property_set_string (d, "storage.solaris.legacy.symdev", buf);
+ devinfo_storage_append_nickname(d, media_type, media_num);
+
+ /* additional nicknames */
+ if (media == LEGACY_CDROM) {
+ devinfo_storage_append_nickname(d, "cd", media_num);
+ devinfo_storage_append_nickname(d, "sr", media_num);
+ } else if (media == LEGACY_FLOPPY) {
+ devinfo_storage_append_nickname(d, "fd", media_num);
+ devinfo_storage_append_nickname(d, "diskette", media_num);
+ devinfo_storage_append_nickname(d, "rdiskette", media_num);
+ }
+}
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_storage.h b/usr/src/cmd/hal/hald/solaris/devinfo_storage.h
new file mode 100644
index 0000000000..3c2f6115c9
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_storage.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ *
+ * devinfo_storage.h : definitions for storage devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_STORAGE_H
+#define DEVINFO_STORAGE_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_ide_handler;
+extern DevinfoDevHandler devinfo_scsi_handler;
+extern DevinfoDevHandler devinfo_floppy_handler;
+extern DevinfoDevHandler devinfo_lofi_handler;
+
+gboolean devinfo_storage_device_rescan (HalDevice *d);
+HalDevice *devinfo_lofi_add_major(HalDevice *parent, di_node_t node, char *devfs_path,
+ char *device_type, gboolean rescan, HalDevice *lofi_d);
+void devinfo_lofi_remove_minor(char *parent_devfs_path, char *name);
+void devinfo_storage_mnttab_event (HalDevice *hal_volume);
+void devinfo_volume_hotplug_begin_remove (HalDevice *d, char *devfs_path, void *end_token);
+
+#endif /* DEVINFO_STORAGE_H */
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_usb.c b/usr/src/cmd/hal/hald/solaris/devinfo_usb.c
new file mode 100644
index 0000000000..9cd854aa33
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_usb.c
@@ -0,0 +1,227 @@
+/***************************************************************************
+ *
+ * devinfo_usb.h : USB devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <libdevinfo.h>
+#include <sys/types.h>
+#include <sys/mkdev.h>
+#include <sys/stat.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_usb.h"
+
+HalDevice *devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
+static HalDevice *devinfo_usb_if_add(HalDevice *d, di_node_t node, gchar *devfs_path, int ifnum);
+static HalDevice *devinfo_usb_scsa2usb_add(HalDevice *d, di_node_t node, gchar *devfs_path);
+
+DevinfoDevHandler devinfo_usb_handler = {
+ devinfo_usb_add,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+HalDevice *
+devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
+{
+ HalDevice *d, *nd = NULL;
+ char *s;
+ int *i, *vid;
+ char *driver_name, *binding_name;
+ char if_devfs_path[HAL_PATH_MAX];
+
+ /*
+ * we distinguish USB devices by presence of "usb-vendor-id"
+ * property. should USB devices have "device_type"?
+ */
+ if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "usb-vendor-id", &vid) <= 0) {
+ return (NULL);
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.bus", "usb_device");
+ PROP_STR(d, node, s, "usb-product-name", "info.product");
+ PROP_STR(d, node, s, "usb-product-name", "usb_device.product");
+ PROP_STR(d, node, s, "usb-vendor-name", "usb_device.vendor");
+ PROP_INT(d, node, i, "usb-vendor-id", "usb_device.vendor_id");
+ PROP_INT(d, node, i, "usb-product-id", "usb_device.product_id");
+ PROP_INT(d, node, i, "usb-revision-id", "usb_device.device_revision_bcd");
+ PROP_INT(d, node, i, "usb-release-id", "usb_device.version_bcd");
+ PROP_STR(d, node, s, "usb-serialno", "usb_device.serial");
+
+ /* class, subclass */
+ /* hal_device_property_set_int (d, "usb_device.device_class", 8); */
+
+ /* binding name tells us if driver is bound to interface or device */
+ if (((binding_name = di_binding_name(node)) != NULL) &&
+ (strncmp(binding_name, "usbif,", sizeof ("usbif,") - 1) == 0)) {
+ snprintf(if_devfs_path, sizeof (if_devfs_path), "%s:if%d", devfs_path, 0);
+ if ((nd = devinfo_usb_if_add(d, node, if_devfs_path, 0)) != NULL) {
+ d = nd;
+ nd = NULL;
+ devfs_path = if_devfs_path;
+ }
+ }
+
+ /* driver specific */
+ driver_name = di_driver_name (node);
+ if ((driver_name != NULL) && (strcmp (driver_name, "scsa2usb") == 0)) {
+ nd = devinfo_usb_scsa2usb_add (d, node, devfs_path);
+ } else {
+ devinfo_add_enqueue (d, devfs_path, &devinfo_usb_handler);
+ }
+
+out:
+ if (nd != NULL) {
+ return (nd);
+ } else {
+ return (d);
+ }
+}
+
+static HalDevice *
+devinfo_usb_if_add(HalDevice *parent, di_node_t node, gchar *devfs_path, int ifnum)
+{
+ HalDevice *d = NULL;
+ char udi[HAL_PATH_MAX];
+
+ devinfo_add_enqueue (parent, devfs_path, &devinfo_usb_handler);
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, parent, node, devfs_path);
+ hal_device_property_set_string (d, "info.bus", "usb");
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s_if%d", parent->udi, ifnum);
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+ hal_device_property_set_string (d, "info.product", "USB Device Interface");
+
+ /* copy parent's usb_device.* properties */
+ hal_device_merge_with_rewrite (d, parent, "usb.", "usb_device.");
+
+ return (d);
+}
+
+static int
+walk_devlinks(di_devlink_t devlink, void *arg)
+{
+ char **path = (char **)arg;
+
+ *path = strdup(di_devlink_path(devlink));
+
+ return (DI_WALK_TERMINATE);
+}
+
+static char *
+get_devlink(di_devlink_handle_t devlink_hdl, char *path)
+{
+ char *devlink = NULL;
+
+ (void) di_devlink_walk(devlink_hdl, NULL, path,
+ DI_PRIMARY_LINK, &devlink, walk_devlinks);
+
+ return (devlink);
+}
+
+static HalDevice *
+devinfo_usb_scsa2usb_add(HalDevice *usbd, di_node_t node, gchar *devfs_path)
+{
+ HalDevice *d = NULL;
+ di_devlink_handle_t devlink_hdl;
+ int major;
+ di_minor_t minor;
+ dev_t devt;
+ char *minor_path = NULL;
+ char *devlink = NULL;
+ char udi[HAL_PATH_MAX];
+
+ devinfo_add_enqueue (usbd, devfs_path, &devinfo_usb_handler);
+
+ if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
+ printf("di_devlink_init() failed\n");
+ return (NULL);
+ }
+
+ major = di_driver_major(node);
+ minor = DI_MINOR_NIL;
+ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
+ devt = di_minor_devt(minor);
+ if (major != major(devt)) {
+ continue;
+ }
+ if ((minor_path = di_devfs_minor_path(minor)) == NULL) {
+ continue;
+ }
+ if (di_minor_type(minor) != DDM_MINOR) {
+ continue;
+ }
+ if (strcmp (di_minor_nodetype(minor),
+ "ddi_ctl:devctl:scsi") == 0) {
+ devlink = get_devlink(devlink_hdl, minor_path);
+ if (devlink == NULL) {
+ devlink = strdup("");
+ }
+ break;
+ }
+ di_devfs_path_free (minor_path);
+ minor_path = NULL;
+ }
+
+ di_devlink_fini (&devlink_hdl);
+
+ if (devlink == NULL) {
+ goto out;
+ }
+
+ d = hal_device_new ();
+
+ devinfo_set_default_properties (d, usbd, node, minor_path);
+ hal_device_property_set_string (d, "scsi_host.solaris.device", devlink);
+ hal_device_property_set_string (d, "info.category", "scsi_host");
+ hal_device_property_set_int (d, "scsi_host.host", 0);
+
+ hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+ "%s/scsi_host%d", usbd->udi,
+ hal_device_property_get_int (d, "scsi_host.host"));
+ hal_device_set_udi (d, udi);
+ hal_device_property_set_string (d, "info.udi", udi);
+ hal_device_property_set_string (d, "info.product", "SCSI Host Adapter");
+
+ devinfo_add_enqueue (d, minor_path, &devinfo_usb_handler);
+
+out:
+ if (devlink) {
+ free(devlink);
+ }
+ if (minor_path) {
+ di_devfs_path_free (minor_path);
+ }
+
+ return (d);
+}
+
diff --git a/usr/src/cmd/hal/hald/solaris/devinfo_usb.h b/usr/src/cmd/hal/hald/solaris/devinfo_usb.h
new file mode 100644
index 0000000000..233512b14f
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/devinfo_usb.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *
+ * devinfo_usb.h : definitions for USB devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef DEVINFO_USB_H
+#define DEVINFO_USB_H
+
+#include "devinfo.h"
+
+extern DevinfoDevHandler devinfo_usb_handler;
+
+#endif /* DEVINFO_USB_H */
diff --git a/usr/src/cmd/hal/hald/solaris/hal.xml b/usr/src/cmd/hal/hald/solaris/hal.xml
new file mode 100644
index 0000000000..1a6fe79ae5
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/hal.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ Licensed under the Academic Free License version 2.1
+
+ ident "%Z%%M% %I% %E% SMI"
+
+ NOTE: This service manifest is not editable; its contents will
+ be overwritten by package or patch operations, including
+ operating system upgrade. Make customizations in a different
+ file.
+
+ Service manifest for HAL.
+-->
+
+<service_bundle type='manifest' name='SUNWhalr:hal'>
+
+<service
+ name='system/hal'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='false' />
+
+ <single_instance />
+
+ <dependency name='usr'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/local' />
+ </dependency>
+
+ <dependency
+ name='devices'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/system/device/local' />
+ </dependency>
+
+ <dependency name='dbus'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/dbus' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-hal start'
+ timeout_seconds='600'>
+ <method_context>
+ <method_credential user='root' group='root' />
+ </method_context>
+ </exec_method>
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':kill'
+ timeout_seconds='30' />
+
+ <property_group name='startd' type='framework'>
+ <!-- sub-process core dumps shouldn't restart session -->
+ <propval name='ignore_error' type='astring'
+ value='core,signal' />
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ Hardware Abstraction Layer daemon
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='hal' section='1M' manpath='/usr/man' />
+ </documentation>
+ </template>
+
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/hal/hald/solaris/hotplug.c b/usr/src/cmd/hal/hald/solaris/hotplug.c
new file mode 100644
index 0000000000..b802b6eadf
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/hotplug.c
@@ -0,0 +1,193 @@
+/***************************************************************************
+ *
+ * hotplug.c : HAL-internal hotplug events
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../device_info.h"
+
+#include "osspec_solaris.h"
+#include "hotplug.h"
+#include "devinfo.h"
+
+/** Queue of ordered hotplug events */
+GQueue *hotplug_event_queue;
+
+/** List of HotplugEvent objects we are currently processing */
+GSList *hotplug_events_in_progress = NULL;
+
+static void hotplug_event_begin (HotplugEvent *hotplug_event);
+
+void
+hotplug_event_end (void *end_token)
+{
+ HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
+
+ hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
+ g_free (hotplug_event);
+ hotplug_event_process_queue ();
+}
+
+static void
+hotplug_event_begin_devfs_add (HotplugEvent *hotplug_event, HalDevice *d)
+{
+ HalDevice *parent;
+ const gchar *parent_udi;
+ void (*begin_add_func) (HalDevice *, HalDevice *, DevinfoDevHandler *, void *);
+
+ if (d != NULL) {
+ /* XXX */
+ HAL_ERROR (("devpath %s already present in store, ignore event", hotplug_event->un.devfs.devfs_path));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+
+ /* find parent */
+ parent_udi = hal_device_property_get_string (hotplug_event->d, "info.parent");
+ if (parent_udi == NULL || strlen(parent_udi) == 0) {
+ parent = NULL;
+ } else {
+ parent = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", parent_udi);
+ }
+ /* only root node is allowed to be orphan */
+ if (parent == NULL) {
+ if (strcmp(hotplug_event->un.devfs.devfs_path, "/") != 0) {
+ HAL_ERROR (("Parent is NULL devfs_path=%s parent_udi=%s", hotplug_event->un.devfs.devfs_path, parent_udi ? parent_udi : "<null>"));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+ }
+
+ /* children of ignored parent should be ignored */
+ if (hal_device_property_get_bool (parent, "info.ignore")) {
+ HAL_INFO (("parent ignored %s", parent_udi));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+
+ /* custom or generic add function */
+ begin_add_func = hotplug_event->un.devfs.handler->hotplug_begin_add;
+ if (begin_add_func == NULL) {
+ begin_add_func = hotplug_event_begin_add_devinfo;
+ }
+ begin_add_func (hotplug_event->d,
+ parent,
+ hotplug_event->un.devfs.handler,
+ (void *) hotplug_event);
+}
+
+static void
+hotplug_event_begin_devfs_remove (HotplugEvent *hotplug_event, HalDevice *d)
+{
+ if (d == NULL) {
+ HAL_ERROR (("devpath %s not present in store, ignore event", hotplug_event->un.devfs.devfs_path));
+ hotplug_event_end ((void *) hotplug_event);
+ return;
+ }
+ HAL_INFO (("hotplug_event_begin_devfs_remove %s", d->udi));
+
+ hotplug_event_begin_remove_devinfo(d,
+ hotplug_event->un.devfs.devfs_path,
+ (void *) hotplug_event);
+}
+
+static void
+hotplug_event_begin_devfs (HotplugEvent *hotplug_event)
+{
+ HalDevice *d;
+
+ HAL_INFO (("hotplug_event_begin_devfs: %s", hotplug_event->un.devfs.devfs_path));
+ d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path",
+ hotplug_event->un.devfs.devfs_path);
+
+ if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
+ hotplug_event_begin_devfs_add (hotplug_event, d);
+ } else if (hotplug_event->action == HOTPLUG_ACTION_REMOVE) {
+ hotplug_event_begin_devfs_remove (hotplug_event, d);
+ } else {
+ hotplug_event_end ((void *) hotplug_event);
+ }
+}
+
+static void
+hotplug_event_begin (HotplugEvent *hotplug_event)
+{
+ switch (hotplug_event->type) {
+
+ case HOTPLUG_EVENT_DEVFS:
+ hotplug_event_begin_devfs (hotplug_event);
+ break;
+
+ default:
+ HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type));
+ hotplug_event_end ((void *) hotplug_event);
+ break;
+ }
+}
+
+void
+hotplug_event_enqueue (HotplugEvent *hotplug_event, int front)
+{
+ if (hotplug_event_queue == NULL)
+ hotplug_event_queue = g_queue_new ();
+
+ if (front) {
+ g_queue_push_head (hotplug_event_queue, hotplug_event);
+ } else {
+ g_queue_push_tail (hotplug_event_queue, hotplug_event);
+ }
+}
+
+void
+hotplug_event_process_queue (void)
+{
+ HotplugEvent *hotplug_event;
+
+ if (hotplug_events_in_progress == NULL &&
+ (hotplug_event_queue == NULL || g_queue_is_empty (hotplug_event_queue))) {
+ hotplug_queue_now_empty ();
+ goto out;
+ }
+
+ /* do not process events if some other event is in progress */
+ if (hotplug_events_in_progress != NULL && g_slist_length (hotplug_events_in_progress) > 0)
+ goto out;
+
+ hotplug_event = g_queue_pop_head (hotplug_event_queue);
+ if (hotplug_event == NULL)
+ goto out;
+
+ hotplug_events_in_progress = g_slist_append (hotplug_events_in_progress, hotplug_event);
+ hotplug_event_begin (hotplug_event);
+
+out:
+ ;
+}
diff --git a/usr/src/cmd/hal/hald/solaris/hotplug.h b/usr/src/cmd/hal/hald/solaris/hotplug.h
new file mode 100644
index 0000000000..ae8752bb8f
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/hotplug.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ *
+ * hotplug.h : definitions for HAL-internal hotplug events
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef HOTPLUG_H
+#define HOTPLUG_H
+
+#include <glib.h>
+
+#include "../device.h"
+#include "../util.h"
+
+#include "devinfo.h"
+
+typedef enum {
+ HOTPLUG_ACTION_ADD,
+ HOTPLUG_ACTION_REMOVE,
+} HotplugActionType;
+
+typedef enum {
+ HOTPLUG_EVENT_DEVFS = 0,
+} HotplugEventType;
+
+/** Data structure representing a hotplug event; also used for
+ * coldplugging.
+ */
+typedef struct
+{
+ HotplugActionType action; /**< Whether the event is add or remove */
+ HotplugEventType type; /**< Type of hotplug event */
+
+ HalDevice *d;
+
+ union {
+ struct {
+ char devfs_path[HAL_PATH_MAX];
+ DevinfoDevHandler *handler;
+ } devfs;
+ } un;
+
+} HotplugEvent;
+
+void hotplug_event_enqueue (HotplugEvent *event, int front);
+
+void hotplug_event_process_queue (void);
+
+void hotplug_event_end (void *end_token);
+
+void hotplug_queue_now_empty (void);
+
+#endif /* HOTPLUG_H */
diff --git a/usr/src/cmd/hal/hald/solaris/osspec.c b/usr/src/cmd/hal/hald/solaris/osspec.c
new file mode 100644
index 0000000000..ffeef4d0b6
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/osspec.c
@@ -0,0 +1,235 @@
+/***************************************************************************
+ *
+ * osspec.c : Solaris HAL backend entry points
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+#include <port.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "../ids.h"
+#include "osspec_solaris.h"
+#include "hotplug.h"
+#include "sysevent.h"
+#include "devinfo.h"
+#include "devinfo_storage.h"
+
+static void mnttab_event_init ();
+static gboolean mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data);
+
+void
+osspec_init (void)
+{
+ ids_init ();
+ sysevent_init ();
+ mnttab_event_init ();
+}
+
+void
+hotplug_queue_now_empty (void)
+{
+ if (hald_is_initialising) {
+ osspec_probe_done ();
+ }
+}
+
+void
+osspec_probe (void)
+{
+ /* add entire device tree */
+ devinfo_add (NULL, "/");
+
+ /* start processing events */
+ hotplug_event_process_queue ();
+}
+
+gboolean
+osspec_device_rescan (HalDevice *d)
+{
+ return (devinfo_device_rescan (d));
+}
+
+gboolean
+osspec_device_reprobe (HalDevice *d)
+{
+ return FALSE;
+}
+
+DBusHandlerResult
+osspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+/** Find the closest ancestor by looking at devfs paths
+ *
+ * @param devfs_path Path into devfs, e.g. /pci@0,0/pci1025,57@10,2/storage@1
+ * @return Parent Hal Device Object or #NULL if there is none
+ */
+HalDevice *
+hal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path)
+{
+ gchar buf[512];
+ gchar c;
+ HalDevice *parent;
+
+ parent = NULL;
+
+ strncpy (buf, devfs_path, sizeof (buf));
+ do {
+ char *p;
+
+ p = strrchr (buf, '/');
+ if (p == NULL)
+ break;
+ c = *p;
+ *p = '\0';
+
+ parent = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path",
+ buf);
+ if (parent != NULL) {
+ if (ancestor_devfs_path != NULL) {
+ *ancestor_devfs_path = g_strdup (buf);
+ }
+ if (hotplug_devfs_path != NULL) {
+ *p = c;
+ *hotplug_devfs_path = g_strdup (buf);
+ }
+ break;
+ }
+
+ } while (TRUE);
+
+ return parent;
+}
+
+char *
+dsk_to_rdsk(char *dsk)
+{
+ int len, pos;
+ char *p;
+ char *rdsk;
+
+ if ((len = strlen (dsk)) < sizeof ("/dev/dsk/cN") - 1) {
+ return (strdup(""));
+ }
+ if ((p = strstr (dsk, "/dsk/")) == NULL) {
+ if ((p = strstr (dsk, "/lofi/")) == NULL) {
+ p = strstr (dsk, "/diskette");
+ }
+ }
+ if (p == NULL) {
+ return (strdup(""));
+ }
+
+ pos = (uintptr_t)p - (uintptr_t)dsk;
+ if ((rdsk = (char *)calloc (len + 2, 1)) != NULL) {
+ strncpy (rdsk, dsk, pos + 1);
+ rdsk[pos + 1] = 'r';
+ strcpy (rdsk + pos + 2, dsk + pos + 1);
+ }
+
+ return (rdsk);
+}
+
+/*
+ * Setup to watch mnttab changes
+ *
+ * When mnttab changes, POLLRDBAND is set. However, glib does not
+ * support POLLRDBAND, so we use Solaris ports (see port_create(3C))
+ * to "map" POLLRDBAND to POLLIN:
+ *
+ * - create a port
+ * - associate the port with mnttab file descriptor and POLLRDBAND
+ * - now polling for POLLIN on the port descriptor will unblock when
+ * the associated file descriptor receives POLLRDBAND
+ */
+static int mnttab_fd;
+static int mnttab_port;
+static GIOChannel *mnttab_channel;
+
+static void
+mnttab_event_init ()
+{
+ char buf[81];
+
+ if ((mnttab_fd = open (MNTTAB, O_RDONLY)) < 0) {
+ return;
+ }
+ if ((mnttab_port = port_create ()) < 0) {
+ (void) close (mnttab_fd);
+ return;
+ }
+ if (port_associate (mnttab_port, PORT_SOURCE_FD, mnttab_fd, POLLRDBAND,
+ NULL) != 0) {
+ (void) close (mnttab_port);
+ (void) close (mnttab_fd);
+ return;
+ }
+
+ /* suppress initial event */
+ (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1));
+ (void) lseek(mnttab_fd, 0, SEEK_SET);
+
+ mnttab_channel = g_io_channel_unix_new (mnttab_port);
+ g_io_add_watch (mnttab_channel, G_IO_IN, mnttab_event, NULL);
+}
+
+static gboolean
+mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data)
+{
+ port_event_t pe;
+ timespec_t timeout;
+ char buf[81];
+
+ /* if (cond & ~G_IO_ERR)
+ return TRUE;
+ */
+ HAL_INFO (("mnttab event"));
+
+ /* we have to re-associate port with fd every time */
+ timeout.tv_sec = timeout.tv_nsec = 0;
+ (void) port_get(mnttab_port, &pe, &timeout);
+ (void) port_associate(mnttab_port, PORT_SOURCE_FD,
+ mnttab_fd, POLLRDBAND, NULL);
+
+ if (!hald_is_initialising) {
+ devinfo_storage_mnttab_event (NULL);
+ }
+
+ (void) lseek(mnttab_fd, 0, SEEK_SET);
+ (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1));
+
+ return TRUE;
+}
+
+void
+osspec_refresh_mount_state_for_block_device (HalDevice *d)
+{
+ devinfo_storage_mnttab_event (d);
+}
diff --git a/usr/src/cmd/hal/hald/solaris/osspec_solaris.h b/usr/src/cmd/hal/hald/solaris/osspec_solaris.h
new file mode 100644
index 0000000000..d796522bd0
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/osspec_solaris.h
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *
+ * osspec_solaris.h : definitions for Solaris HAL backend
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef OSSPEC_SOLARIS_H
+#define OSSPEC_SOLARIS_H
+
+#include <glib.h>
+
+void hotplug_queue_now_empty (void);
+HalDevice *hal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path);
+char *dsk_to_rdsk(char *);
+
+#endif /* OSSPEC_SOLARIS_H */
diff --git a/usr/src/cmd/hal/hald/solaris/svc-hal b/usr/src/cmd/hal/hald/solaris/svc-hal
new file mode 100755
index 0000000000..ba63771b5d
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/svc-hal
@@ -0,0 +1,39 @@
+#!/sbin/sh
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Licensed under the Academic Free License version 2.1
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+case "$1" in
+'start')
+ if smf_is_nonglobalzone; then
+ /usr/sbin/svcadm disable $SMF_FMRI
+ echo "$SMF_FMRI is not supported in a local zone"
+ sleep 5 &
+ exit $SMF_EXIT_OK
+ fi
+
+ [ ! -x /usr/lib/hal/hald ] && exit $SMF_EXIT_ERR_CONFIG
+
+ [ ! -d /var/run/hald ] && /usr/bin/mkdir -m 755 /var/run/hald
+ [ ! -d /media ] && /usr/bin/mkdir -m 755 /media
+
+ /usr/lib/hal/hald --daemon=yes
+ err=$?
+ if [ $err -ne 0 ]; then
+ echo "hal failed to start: error $err"
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+ ;;
+*)
+ echo "Usage: $0 { start }"
+ exit $SMF_EXIT_ERR_FATAL
+ ;;
+esac
+
+exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/hal/hald/solaris/sysevent.c b/usr/src/cmd/hal/hald/solaris/sysevent.c
new file mode 100644
index 0000000000..e13a4411d8
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/sysevent.c
@@ -0,0 +1,291 @@
+/***************************************************************************
+ *
+ * sysevent.c : Solaris sysevents
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/dkio.h>
+#include <sys/stat.h>
+#include <libdevinfo.h>
+#include <libsysevent.h>
+#include <sys/sysevent/dev.h>
+#include <glib.h>
+
+#include "../osspec.h"
+#include "../logger.h"
+#include "../hald.h"
+#include "../hald_dbus.h"
+#include "../device_info.h"
+#include "../util.h"
+#include "osspec_solaris.h"
+#include "hotplug.h"
+#include "devinfo.h"
+#include "devinfo_storage.h"
+#include "sysevent.h"
+
+#ifndef ESC_LOFI
+#define ESC_LOFI "lofi"
+#endif
+
+static void sysevent_dev_handler(sysevent_t *);
+static gboolean sysevent_iochannel_data(GIOChannel *, GIOCondition, gpointer);
+static void sysevent_dev_add(gchar *, gchar *);
+static void sysevent_dev_remove(gchar *, gchar *);
+static void sysevent_dev_branch(gchar *);
+static void sysevent_lofi_add(gchar *, gchar *);
+static void sysevent_lofi_remove(gchar *, gchar *);
+
+static sysevent_handle_t *shp;
+
+static int sysevent_pipe_fds[2];
+static GIOChannel *sysevent_iochannel;
+static guint sysevent_source_id;
+
+gboolean
+sysevent_init(void)
+{
+ GError *err = NULL;
+ const char *subcl[2];
+
+ /*
+ * pipe used to serialize sysevents through the main loop
+ */
+ if (pipe (sysevent_pipe_fds) != 0) {
+ HAL_INFO (("pipe() failed errno=%d", errno));
+ return (FALSE);
+ }
+ sysevent_iochannel = g_io_channel_unix_new (sysevent_pipe_fds[0]);
+ if (sysevent_iochannel == NULL) {
+ HAL_INFO (("g_io_channel_unix_new failed"));
+ return (FALSE);
+ }
+ g_io_channel_set_flags (sysevent_iochannel, G_IO_FLAG_NONBLOCK, &err);
+ sysevent_source_id = g_io_add_watch (
+ sysevent_iochannel, G_IO_IN, sysevent_iochannel_data, NULL);
+
+ shp = sysevent_bind_handle(sysevent_dev_handler);
+ if (shp == NULL) {
+ HAL_INFO (("sysevent_bind_handle failed %d", errno));
+ return (FALSE);
+ }
+
+ subcl[0] = ESC_DISK;
+ subcl[1] = ESC_LOFI;
+ if (sysevent_subscribe_event(shp, EC_DEV_ADD, subcl, 2) != 0) {
+ HAL_INFO (("subscribe(dev_add) failed %d", errno));
+ sysevent_unbind_handle(shp);
+ return (FALSE);
+ }
+ if (sysevent_subscribe_event(shp, EC_DEV_REMOVE, subcl, 2) != 0) {
+ HAL_INFO (("subscribe(dev_remove) failed %d", errno));
+ sysevent_unbind_handle(shp);
+ return (FALSE);
+ }
+
+ subcl[0] = ESC_DEV_BRANCH_REMOVE;
+ if (sysevent_subscribe_event(shp, EC_DEV_BRANCH, subcl, 1) != 0) {
+ HAL_INFO (("subscribe(dev_branch) failed %d", errno));
+ sysevent_unbind_handle(shp);
+ return (FALSE);
+ }
+
+ return (B_TRUE);
+}
+
+void
+sysevent_fini(void)
+{
+ sysevent_unbind_handle(shp);
+ shp = NULL;
+}
+
+static void
+sysevent_dev_handler(sysevent_t *ev)
+{
+ char *class;
+ char *subclass;
+ nvlist_t *attr_list;
+ char *phys_path;
+ char *dev_name;
+ char s[1024];
+ ssize_t nwritten;
+
+ if ((class = sysevent_get_class_name(ev)) == NULL)
+ return;
+
+ if ((subclass = sysevent_get_subclass_name(ev)) == NULL)
+ return;
+
+ if (sysevent_get_attr_list(ev, &attr_list) != 0)
+ return;
+
+ if (nvlist_lookup_string(attr_list, DEV_PHYS_PATH, &phys_path) != 0)
+ goto out;
+
+ if (nvlist_lookup_string(attr_list, DEV_NAME, &dev_name) != 0)
+ dev_name = "";
+
+ snprintf(s, sizeof (s), "%s %s %s %s\n",
+ class, subclass, phys_path, dev_name);
+ nwritten = write(sysevent_pipe_fds[1], s, strlen(s) + 1);
+
+ HAL_INFO (("sysevent_dev_handler: wrote %d bytes", nwritten));
+
+out:
+ nvlist_free(attr_list);
+}
+
+static gboolean
+sysevent_iochannel_data (GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ GError *err = NULL;
+ gchar *s = NULL;
+ gsize len;
+ int matches;
+ gchar class[1024];
+ gchar subclass[1024];
+ gchar phys_path[1024];
+ gchar dev_name[1024];
+
+ HAL_INFO (("sysevent_iochannel_data"));
+
+ while (g_io_channel_read_line (sysevent_iochannel, &s, &len, NULL,
+ &err) == G_IO_STATUS_NORMAL) {
+ if (len == 0) {
+ break;
+ }
+
+ class[0] = subclass[0] = phys_path[0] = dev_name[0] = '\0';
+ matches = sscanf(s, "%s %s %s %s", class, subclass, phys_path, dev_name);
+ g_free (s);
+ s = NULL;
+ if (matches < 3) {
+ continue;
+ }
+ HAL_INFO (("sysevent: class=%s, sub=%s", class, subclass));
+
+ if (strcmp(class, EC_DEV_ADD) == 0) {
+ if (strcmp(subclass, ESC_DISK) == 0) {
+ sysevent_dev_add(phys_path, dev_name);
+ } else if (strcmp(subclass, ESC_LOFI) == 0) {
+ sysevent_lofi_add(phys_path, dev_name);
+ }
+ } else if (strcmp(class, EC_DEV_REMOVE) == 0) {
+ if (strcmp(subclass, ESC_DISK) == 0) {
+ sysevent_dev_remove(phys_path, dev_name);
+ } else if (strcmp(subclass, ESC_LOFI) == 0) {
+ sysevent_lofi_remove(phys_path, dev_name);
+ }
+ } else if (strcmp(class, EC_DEV_BRANCH) == 0) {
+ sysevent_dev_branch(phys_path);
+ }
+ }
+
+ if (err) {
+ g_error_free (err);
+ }
+
+ return (TRUE);
+}
+
+static void
+sysevent_dev_add(gchar *devfs_path, gchar *name)
+{
+ gchar *parent_devfs_path, *hotplug_devfs_path;
+ HalDevice *parent;
+
+ HAL_INFO (("dev_add: %s %s", name, devfs_path));
+
+ parent = hal_util_find_closest_ancestor (devfs_path, &parent_devfs_path, &hotplug_devfs_path);
+ if (parent == NULL) {
+ return;
+ }
+
+ HAL_INFO (("dev_add: parent=%s", parent_devfs_path));
+ HAL_INFO (("dev_add: real=%s", hotplug_devfs_path));
+
+ devinfo_add (parent, hotplug_devfs_path);
+
+ g_free (parent_devfs_path);
+ g_free (hotplug_devfs_path);
+
+ hotplug_event_process_queue ();
+}
+
+static void
+sysevent_dev_remove(gchar *devfs_path, gchar *name)
+{
+ HAL_INFO (("dev_remove: %s %s", name, devfs_path));
+
+ devinfo_remove_branch (devfs_path, NULL);
+ hotplug_event_process_queue ();
+}
+
+static void
+sysevent_dev_branch(gchar *devfs_path)
+{
+ HAL_INFO (("branch_remove: %s", devfs_path));
+
+ devinfo_remove_branch (devfs_path, NULL);
+ hotplug_event_process_queue ();
+}
+
+static void
+sysevent_lofi_add(gchar *devfs_path, gchar *name)
+{
+ di_node_t node;
+ const char *parent_udi;
+ HalDevice *d, *parent;
+
+ HAL_INFO (("lofi_add: %s %s", name, devfs_path));
+
+ if ((d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "solaris.devfs_path", devfs_path)) == NULL) {
+ HAL_INFO (("device not found in GDL %s", devfs_path));
+ return;
+ }
+ parent_udi = hal_device_property_get_string (d, "info.parent");
+ if ((parent_udi == NULL) || (strlen(parent_udi) == 0)) {
+ HAL_INFO (("parent not found in GDL %s", parent_udi));
+ return;
+ }
+ if ((parent = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "info.udi", parent_udi)) == NULL) {
+ HAL_INFO (("parent not found in GDL %s", parent_udi));
+ return;
+ }
+
+ if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
+ HAL_INFO (("device not found in devinfo %s", devfs_path));
+ return;
+ }
+
+ HAL_INFO (("device %s parent %s", d->udi, parent_udi));
+ devinfo_lofi_add_major (parent, node, devfs_path, NULL, TRUE, d);
+
+ di_fini (node);
+
+ hotplug_event_process_queue ();
+}
+
+static void
+sysevent_lofi_remove(gchar *parent_devfs_path, gchar *name)
+{
+ devinfo_lofi_remove_minor(parent_devfs_path, name);
+ hotplug_event_process_queue ();
+}
diff --git a/usr/src/cmd/hal/hald/solaris/sysevent.h b/usr/src/cmd/hal/hald/solaris/sysevent.h
new file mode 100644
index 0000000000..291030f7f7
--- /dev/null
+++ b/usr/src/cmd/hal/hald/solaris/sysevent.h
@@ -0,0 +1,22 @@
+/***************************************************************************
+ *
+ * sysevent.h : definitions for Solaris sysevents
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef SYSEVENT_H
+#define SYSEVENT_H
+
+#include <glib.h>
+
+gboolean sysevent_init(void);
+void sysevent_fini(void);
+
+#endif /* SYSEVENT_H */
diff --git a/usr/src/cmd/hal/hald/util.c b/usr/src/cmd/hal/hald/util.c
new file mode 100644
index 0000000000..002b03510e
--- /dev/null
+++ b/usr/src/cmd/hal/hald/util.c
@@ -0,0 +1,1097 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * util.c - Various utilities
+ *
+ * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <ctype.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/file.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+
+#include "osspec.h"
+#include "logger.h"
+#include "hald.h"
+#include "hald_runner.h"
+#include "hald_dbus.h"
+#include "device_info.h"
+
+#include "util.h"
+
+gboolean
+hal_util_remove_trailing_slash (gchar *path)
+{
+ gchar *c = NULL;
+
+ if (path == NULL) {
+ return FALSE;
+ }
+
+ c = strrchr (path, '/');
+ if (c == NULL) {
+ HAL_WARNING (("Invalid path %s", path));
+ return 1;
+ }
+ if (*(c+1) == '\0')
+ *c = '\0';
+
+ return TRUE;
+}
+
+/** Given a path, /foo/bar/bat/foobar, return the last element, e.g.
+ * foobar.
+ *
+ * @param path Path
+ * @return Pointer into given string
+ */
+const gchar *
+hal_util_get_last_element (const gchar *s)
+{
+ int len;
+ const gchar *p;
+
+ len = strlen (s);
+ for (p = s + len - 1; p > s; --p) {
+ if ((*p) == '/')
+ return p + 1;
+ }
+
+ return s;
+}
+
+/** Given a path, this functions finds the path representing the
+ * parent directory by truncation.
+ *
+ * @param path Path
+ * @return Path for parent or NULL. Must be freed by caller
+ */
+gchar *
+hal_util_get_parent_path (const gchar *path)
+{
+ guint i;
+ guint len;
+ gchar *parent_path;
+
+ /* Find parent device by truncating our own path */
+ parent_path = g_strndup (path, HAL_PATH_MAX);
+ len = strlen (parent_path);
+ for (i = len - 1; parent_path[i] != '/'; --i) {
+ parent_path[i] = '\0';
+ }
+ parent_path[i] = '\0';
+
+ return parent_path;
+}
+
+gchar *
+hal_util_get_normalized_path (const gchar *path1, const gchar *path2)
+{
+ int len1;
+ int len2;
+ const gchar *p1;
+ const gchar *p2;
+ gchar buf[HAL_PATH_MAX];
+
+ len1 = strlen (path1);
+ len2 = strlen (path2);
+
+ p1 = path1 + len1;
+
+ p2 = path2;
+ while (p2 < path2 + len2 && strncmp (p2, "../", 3) == 0) {
+ p2 += 3;
+
+ while (p1 >= path1 && *(--p1)!='/')
+ ;
+ }
+
+ if ((p1-path1) < 0) {
+ HAL_ERROR (("Could not normalize '%s' and '%s', return 'NULL'", path1, path2));
+ return NULL;
+ }
+
+ strncpy (buf, path1, (p1-path1));
+ buf[p1-path1] = '\0';
+
+ return g_strdup_printf ("%s/%s", buf, p2);
+}
+
+gboolean
+hal_util_get_int_from_file (const gchar *directory, const gchar *file, gint *result, gint base)
+{
+ FILE *f;
+ char buf[64];
+ gchar path[HAL_PATH_MAX];
+ gboolean ret;
+
+ f = NULL;
+ ret = FALSE;
+
+ g_snprintf (path, sizeof (path), "%s/%s", directory, file);
+
+ f = fopen (path, "rb");
+ if (f == NULL) {
+ HAL_ERROR (("Cannot open '%s'", path));
+ goto out;
+ }
+
+ if (fgets (buf, sizeof (buf), f) == NULL) {
+ HAL_ERROR (("Cannot read from '%s'", path));
+ goto out;
+ }
+
+ /* TODO: handle error condition */
+ *result = strtol (buf, NULL, base);
+ ret = TRUE;
+
+out:
+ if (f != NULL)
+ fclose (f);
+
+ return ret;
+}
+
+gboolean
+hal_util_set_int_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
+{
+ gint value;
+ gboolean ret;
+
+ ret = FALSE;
+
+ if (hal_util_get_int_from_file (directory, file, &value, base))
+ ret = hal_device_property_set_int (d, key, value);
+
+ return ret;
+}
+
+
+gboolean
+hal_util_get_uint64_from_file (const gchar *directory, const gchar *file, guint64 *result, gint base)
+{
+ FILE *f;
+ char buf[64];
+ gchar path[HAL_PATH_MAX];
+ gboolean ret;
+
+ f = NULL;
+ ret = FALSE;
+
+ g_snprintf (path, sizeof (path), "%s/%s", directory, file);
+
+ f = fopen (path, "rb");
+ if (f == NULL) {
+ HAL_ERROR (("Cannot open '%s'", path));
+ goto out;
+ }
+
+ if (fgets (buf, sizeof (buf), f) == NULL) {
+ HAL_ERROR (("Cannot read from '%s'", path));
+ goto out;
+ }
+
+ /* TODO: handle error condition */
+ *result = strtoll (buf, NULL, base);
+
+ ret = TRUE;
+
+out:
+ if (f != NULL)
+ fclose (f);
+
+ return ret;
+}
+
+gboolean
+hal_util_set_uint64_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
+{
+ guint64 value;
+ gboolean ret;
+
+ ret = FALSE;
+
+ if (hal_util_get_uint64_from_file (directory, file, &value, base))
+ ret = hal_device_property_set_uint64 (d, key, value);
+
+ return ret;
+}
+
+gboolean
+hal_util_get_bcd2_from_file (const gchar *directory, const gchar *file, gint *result)
+{
+ FILE *f;
+ char buf[64];
+ gchar path[HAL_PATH_MAX];
+ gboolean ret;
+ gint digit;
+ gint left, right;
+ gboolean passed_white_space;
+ gint num_prec;
+ gsize len;
+ gchar c;
+ guint i;
+
+ f = NULL;
+ ret = FALSE;
+
+ g_snprintf (path, sizeof (path), "%s/%s", directory, file);
+
+ f = fopen (path, "rb");
+ if (f == NULL) {
+ HAL_ERROR (("Cannot open '%s'", path));
+ goto out;
+ }
+
+ if (fgets (buf, sizeof (buf), f) == NULL) {
+ HAL_ERROR (("Cannot read from '%s'", path));
+ goto out;
+ }
+
+ left = 0;
+ len = strlen (buf);
+ passed_white_space = FALSE;
+ for (i = 0; i < len && buf[i] != '.'; i++) {
+ if (g_ascii_isspace (buf[i])) {
+ if (passed_white_space)
+ break;
+ else
+ continue;
+ }
+ passed_white_space = TRUE;
+ left *= 16;
+ c = buf[i];
+ digit = (int) (c - '0');
+ left += digit;
+ }
+ i++;
+ right = 0;
+ num_prec = 0;
+ for (; i < len; i++) {
+ if (g_ascii_isspace (buf[i]))
+ break;
+ if (num_prec == 2) /* Only care about two digits
+ * of precision */
+ break;
+ right *= 16;
+ c = buf[i];
+ digit = (int) (c - '0');
+ right += digit;
+ num_prec++;
+ }
+
+ for (; num_prec < 2; num_prec++)
+ right *= 16;
+
+ *result = left * 256 + (right & 255);
+ ret = TRUE;
+
+out:
+ if (f != NULL)
+ fclose (f);
+
+ return ret;
+}
+
+gboolean
+hal_util_set_bcd2_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
+{
+ gint value;
+ gboolean ret;
+
+ ret = FALSE;
+
+ if (hal_util_get_bcd2_from_file (directory, file, &value))
+ ret = hal_device_property_set_int (d, key, value);
+
+ return ret;
+}
+
+gchar *
+hal_util_get_string_from_file (const gchar *directory, const gchar *file)
+{
+ FILE *f;
+ static gchar buf[256];
+ gchar path[HAL_PATH_MAX];
+ gchar *result;
+ gsize len;
+ gint i;
+
+ f = NULL;
+ result = NULL;
+
+ g_snprintf (path, sizeof (path), "%s/%s", directory, file);
+
+ f = fopen (path, "rb");
+ if (f == NULL) {
+ HAL_ERROR (("Cannot open '%s'", path));
+ goto out;
+ }
+
+ buf[0] = '\0';
+ if (fgets (buf, sizeof (buf), f) == NULL) {
+ HAL_ERROR (("Cannot read from '%s'", path));
+ goto out;
+ }
+
+ len = strlen (buf);
+ if (len>0)
+ buf[len-1] = '\0';
+
+ /* Clear remaining whitespace */
+ for (i = len - 2; i >= 0; --i) {
+ if (!g_ascii_isspace (buf[i]))
+ break;
+ buf[i] = '\0';
+ }
+
+ result = buf;
+
+out:
+ if (f != NULL)
+ fclose (f);
+
+ return result;
+}
+
+gboolean
+hal_util_set_string_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
+{
+ gchar *buf;
+ gboolean ret;
+
+ ret = FALSE;
+
+ if ((buf = hal_util_get_string_from_file (directory, file)) != NULL)
+ ret = hal_device_property_set_string (d, key, buf);
+
+ return ret;
+}
+
+void
+hal_util_compute_udi (HalDeviceStore *store, gchar *dst, gsize dstsize, const gchar *format, ...)
+{
+ guint i;
+ va_list args;
+ gchar buf[256];
+
+ va_start (args, format);
+ g_vsnprintf (buf, sizeof (buf), format, args);
+ va_end (args);
+
+ g_strcanon (buf,
+ "/_"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "1234567890", '_');
+
+ g_strlcpy (dst, buf, dstsize);
+ if (hal_device_store_find (store, dst) == NULL)
+ goto out;
+
+ for (i = 0; ; i++) {
+ g_snprintf (dst, dstsize, "%s_%d", buf, i);
+ if (hal_device_store_find (store, dst) == NULL)
+ goto out;
+ }
+
+out:
+ ;
+}
+
+
+gboolean
+hal_util_path_ascend (gchar *path)
+{
+ gchar *p;
+
+ if (path == NULL)
+ return FALSE;
+
+ p = strrchr (path, '/');
+ if (p == NULL)
+ return FALSE;
+
+ *p = '\0';
+ return TRUE;
+}
+
+static gboolean _grep_can_reuse = FALSE;
+
+void
+hal_util_grep_discard_existing_data (void)
+{
+ _grep_can_reuse = FALSE;
+}
+
+/** Given a directory and filename, open the file and search for the
+ * first line that starts with the given linestart string. Returns
+ * the rest of the line as a string if found.
+ *
+ * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
+ * @param file File, e.g. "info"
+ * @param linestart Start of line, e.g. "serial number"
+ * @param reuse Whether we should reuse the file contents
+ * if the file is the same; can be cleared
+ * with hal_util_grep_discard_existing_data()
+ * @return NULL if not found, otherwise the remainder
+ * of the line, e.g. ": 21805" if
+ * the file /proc/acpi/battery/BAT0 contains
+ * this line "serial number: 21805"
+ * The string is only valid until the next
+ * invocation of this function.
+ */
+gchar *
+hal_util_grep_file (const gchar *directory, const gchar *file, const gchar *linestart, gboolean reuse)
+{
+ static gchar buf[2048];
+ static unsigned int bufsize;
+ static gchar filename[HAL_PATH_MAX];
+ static gchar oldfilename[HAL_PATH_MAX];
+ gchar *result;
+ gsize linestart_len;
+ gchar *p;
+
+ result = NULL;
+
+ /* TODO: use reuse and _grep_can_reuse parameters to avoid loading
+ * the file again and again
+ */
+
+ if (file != NULL && strlen (file) > 0)
+ snprintf (filename, sizeof (filename), "%s/%s", directory, file);
+ else
+ strncpy (filename, directory, sizeof (filename));
+
+ if (_grep_can_reuse && reuse && strcmp (oldfilename, filename) == 0) {
+ /* just reuse old file; e.g. bufsize, buf */
+ /*HAL_INFO (("hal_util_grep_file: reusing buf for %s", filename));*/
+ } else {
+ FILE *f;
+
+ f = fopen (filename, "r");
+ if (f == NULL)
+ goto out;
+ bufsize = fread (buf, sizeof (char), sizeof (buf) - 1, f);
+ buf[bufsize] = '\0';
+ fclose (f);
+
+ /*HAL_INFO (("hal_util_grep_file: read %s of %d bytes", filename, bufsize));*/
+ }
+
+ /* book keeping */
+ _grep_can_reuse = TRUE;
+ strncpy (oldfilename, filename, sizeof(oldfilename));
+
+ linestart_len = strlen (linestart);
+
+ /* analyze buf */
+ p = buf;
+ do {
+ unsigned int linelen;
+ static char line[256];
+
+ for (linelen = 0; p[linelen] != '\n' && p[linelen] != '\0'; linelen++)
+ ;
+
+ if (linelen < sizeof (line)) {
+
+ strncpy (line, p, linelen);
+ line[linelen] = '\0';
+
+ if (strncmp (line, linestart, linestart_len) == 0) {
+ result = line + linestart_len;
+ goto out;
+ }
+ }
+
+ p += linelen + 1;
+
+ } while (p < buf + bufsize);
+
+out:
+ return result;
+}
+
+gchar *
+hal_util_grep_string_elem_from_file (const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, gboolean reuse)
+{
+ gchar *line;
+ gchar *res;
+ static gchar buf[256];
+ gchar **tokens;
+ guint i, j;
+
+ res = NULL;
+ tokens = NULL;
+
+ if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
+ goto out;
+
+ tokens = g_strsplit_set (line, " \t:", 0);
+ for (i = 0, j = 0; tokens[i] != NULL; i++) {
+ if (strlen (tokens[i]) == 0)
+ continue;
+ if (j == elem) {
+ strncpy (buf, tokens[i], sizeof (buf));
+ res = buf;
+ goto out;
+ }
+ j++;
+ }
+
+out:
+ if (tokens != NULL)
+ g_strfreev (tokens);
+
+ return res;
+}
+
+gint
+hal_util_grep_int_elem_from_file (const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, guint base, gboolean reuse)
+{
+ gchar *endptr;
+ gchar *strvalue;
+ int value;
+
+ value = G_MAXINT;
+
+ strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse);
+ if (strvalue == NULL)
+ goto out;
+
+ value = strtol (strvalue, &endptr, base);
+ if (endptr == strvalue) {
+ value = G_MAXINT;
+ goto out;
+ }
+
+out:
+ return value;
+}
+
+/** Get a string value from a formatted text file and assign it to
+ * a property on a device object.
+ *
+ * Example: Given that the file /proc/acpi/battery/BAT0/info contains
+ * the line
+ *
+ * "design voltage: 10800 mV"
+ *
+ * then hal_util_set_string_elem_from_file (d, "battery.foo",
+ * "/proc/acpi/battery/BAT0", "info", "design voltage", 1) will assign
+ * the string "mV" to the property "battery.foo" on d.
+ *
+ * @param d Device object
+ * @param key Property name
+ * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
+ * @param file File, e.g. "info"
+ * @param linestart Start of line, e.g. "design voltage"
+ * @param elem Element number after linestart to extract
+ * excluding whitespace and ':' characters.
+ * @return TRUE, if, and only if, the value could be
+ * extracted and the property was set
+ */
+gboolean
+hal_util_set_string_elem_from_file (HalDevice *d, const gchar *key,
+ const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, gboolean reuse)
+{
+ gboolean res;
+ gchar *value;
+
+ res = FALSE;
+
+ if ((value = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse)) == NULL)
+ goto out;
+
+ res = hal_device_property_set_string (d, key, value);
+out:
+ return res;
+}
+
+/** Get an integer value from a formatted text file and assign it to
+ * a property on a device object.
+ *
+ * Example: Given that the file /proc/acpi/battery/BAT0/info contains
+ * the line
+ *
+ * "design voltage: 10800 mV"
+ *
+ * then hal_util_set_int_elem_from_file (d, "battery.foo",
+ * "/proc/acpi/battery/BAT0", "info", "design voltage", 0) will assign
+ * the integer 10800 to the property "battery.foo" on d.
+ *
+ * @param d Device object
+ * @param key Property name
+ * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
+ * @param file File, e.g. "info"
+ * @param linestart Start of line, e.g. "design voltage"
+ * @param elem Element number after linestart to extract
+ * excluding whitespace and ':' characters.
+ * @return TRUE, if, and only if, the value could be
+ * extracted and the property was set
+ */
+gboolean
+hal_util_set_int_elem_from_file (HalDevice *d, const gchar *key,
+ const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, guint base, gboolean reuse)
+{
+ gchar *endptr;
+ gboolean res;
+ gchar *strvalue;
+ int value;
+
+ res = FALSE;
+
+ strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse);
+ if (strvalue == NULL)
+ goto out;
+
+ value = strtol (strvalue, &endptr, base);
+ if (endptr == strvalue)
+ goto out;
+
+ res = hal_device_property_set_int (d, key, value);
+
+out:
+ return res;
+
+}
+
+/** Get a value from a formatted text file, test it against a given
+ * value, and set a boolean property on a device object with the
+ * test result.
+ *
+ * Example: Given that the file /proc/acpi/battery/BAT0/info contains
+ * the line
+ *
+ * "present: yes"
+ *
+ * then hal_util_set_bool_elem_from_file (d, "battery.baz",
+ * "/proc/acpi/battery/BAT0", "info", "present", 0, "yes") will assign
+ * the boolean TRUE to the property "battery.baz" on d.
+ *
+ * If, instead, the line was
+ *
+ * "present: no"
+ *
+ * the value assigned will be FALSE.
+ *
+ * @param d Device object
+ * @param key Property name
+ * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
+ * @param file File, e.g. "info"
+ * @param linestart Start of line, e.g. "design voltage"
+ * @param elem Element number after linestart to extract
+ * excluding whitespace and ':' characters.
+ * @param expected Value to test against
+ * @return TRUE, if, and only if, the value could be
+ * extracted and the property was set
+ */
+gboolean
+hal_util_set_bool_elem_from_file (HalDevice *d, const gchar *key,
+ const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, const gchar *expected, gboolean reuse)
+{
+ gchar *line;
+ gboolean res;
+ gchar **tokens;
+ guint i, j;
+
+ res = FALSE;
+ tokens = NULL;
+
+ if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
+ goto out;
+
+ tokens = g_strsplit_set (line, " \t:", 0);
+
+ for (i = 0, j = 0; tokens[i] != NULL; i++) {
+ if (strlen (tokens[i]) == 0)
+ continue;
+ if (j == elem) {
+ hal_device_property_set_bool (d, key, strcmp (tokens[i], expected) == 0);
+ res = TRUE;
+ goto out;
+ }
+ j++;
+ }
+
+
+out:
+ if (tokens != NULL)
+ g_strfreev (tokens);
+
+ return res;
+}
+
+gchar **
+hal_util_dup_strv_from_g_slist (GSList *strlist)
+{
+ guint j;
+ guint len;
+ gchar **strv;
+ GSList *i;
+
+ len = g_slist_length (strlist);
+ strv = g_new (char *, len + 1);
+
+ for (i = strlist, j = 0; i != NULL; i = g_slist_next (i), j++) {
+ strv[j] = g_strdup ((const gchar *) i->data);
+ }
+ strv[j] = NULL;
+
+ return strv;
+}
+
+/* -------------------------------------------------------------------------------------------------------------- */
+
+typedef struct {
+ HalDevice *d;
+ gchar **programs;
+ gchar **extra_env;
+ guint next_program;
+
+ HalCalloutsDone callback;
+ gpointer userdata1;
+ gpointer userdata2;
+
+} Callout;
+
+static void callout_do_next (Callout *c);
+
+static void
+callout_terminated (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ Callout *c;
+
+ c = (Callout *) data1;
+ callout_do_next (c);
+}
+
+static void
+callout_do_next (Callout *c)
+{
+
+ /* Check if we're done */
+ if (c->programs[c->next_program] == NULL) {
+ HalDevice *d;
+ gpointer userdata1;
+ gpointer userdata2;
+ HalCalloutsDone callback;
+
+ d = c->d;
+ userdata1 = c->userdata1;
+ userdata2 = c->userdata2;
+ callback = c->callback;
+
+ g_strfreev (c->programs);
+ g_strfreev (c->extra_env);
+ g_free (c);
+
+ callback (d, userdata1, userdata2);
+
+ } else {
+ hald_runner_run(c->d, c->programs[c->next_program], c->extra_env,
+ HAL_HELPER_TIMEOUT, callout_terminated,
+ (gpointer)c, NULL);
+ c->next_program++;
+ }
+}
+
+static void
+hal_callout_device (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2,
+ GSList *programs, gchar **extra_env)
+{
+ Callout *c;
+
+ c = g_new0 (Callout, 1);
+ c->d = d;
+ c->callback = callback;
+ c->userdata1 = userdata1;
+ c->userdata2 = userdata2;
+ c->programs = hal_util_dup_strv_from_g_slist (programs);
+ c->extra_env = g_strdupv (extra_env);
+ c->next_program = 0;
+
+ callout_do_next (c);
+}
+
+void
+hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
+{
+ GSList *programs;
+ gchar *extra_env[2] = {"HALD_ACTION=add", NULL};
+
+ if ((programs = hal_device_property_get_strlist (d, "info.callouts.add")) == NULL) {
+ callback (d, userdata1, userdata2);
+ goto out;
+ }
+
+ HAL_INFO (("Add callouts for udi=%s", d->udi));
+
+ hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
+out:
+ ;
+}
+
+void
+hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
+{
+ GSList *programs;
+ gchar *extra_env[2] = {"HALD_ACTION=remove", NULL};
+
+ if ((programs = hal_device_property_get_strlist (d, "info.callouts.remove")) == NULL) {
+ callback (d, userdata1, userdata2);
+ goto out;
+ }
+
+ HAL_INFO (("Remove callouts for udi=%s", d->udi));
+
+ hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
+out:
+ ;
+}
+
+void
+hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
+{
+ GSList *programs;
+ gchar *extra_env[2] = {"HALD_ACTION=preprobe", NULL};
+
+ if ((programs = hal_device_property_get_strlist (d, "info.callouts.preprobe")) == NULL) {
+ callback (d, userdata1, userdata2);
+ goto out;
+ }
+
+ HAL_INFO (("Preprobe callouts for udi=%s", d->udi));
+
+ hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
+out:
+ ;
+}
+
+gchar *
+hal_util_strdup_valid_utf8 (const char *str)
+{
+ char *endchar;
+ char *newstr;
+ unsigned int count = 0;
+
+ if (str == NULL)
+ return NULL;
+
+ newstr = g_strdup (str);
+
+ while (!g_utf8_validate (newstr, -1, (const char **) &endchar)) {
+ *endchar = '?';
+ count++;
+ }
+
+ if (strlen(newstr) == count)
+ return NULL;
+ else
+ return newstr;
+}
+
+void
+hal_util_hexdump (const void *mem, unsigned int size)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int n;
+ const char *buf = (const char *) mem;
+
+ n = 0;
+ printf ("Dumping %d=0x%x bytes\n", size, size);
+ while (n < size) {
+
+ printf ("0x%04x: ", n);
+
+ j = n;
+ for (i = 0; i < 16; i++) {
+ if (j >= size)
+ break;
+ printf ("%02x ", buf[j]);
+ j++;
+ }
+
+ for ( ; i < 16; i++) {
+ printf (" ");
+ }
+
+ printf (" ");
+
+ j = n;
+ for (i = 0; i < 16; i++) {
+ if (j >= size)
+ break;
+ printf ("%c", isprint(buf[j]) ? buf[j] : '.');
+ j++;
+ }
+
+ printf ("\n");
+
+ n += 16;
+ }
+}
+
+gboolean
+hal_util_is_mounted_by_hald (const char *mount_point)
+{
+ int i;
+ FILE *hal_mtab;
+ int hal_mtab_len;
+ int num_read;
+ char *hal_mtab_buf;
+ char **lines;
+ gboolean found;
+
+ hal_mtab = NULL;
+ hal_mtab_buf = NULL;
+ found = FALSE;
+
+ /*HAL_DEBUG (("examining /media/.hal-mtab for %s", mount_point));*/
+
+ hal_mtab = fopen ("/media/.hal-mtab", "r");
+ if (hal_mtab == NULL) {
+ HAL_ERROR (("Cannot open /media/.hal-mtab"));
+ goto out;
+ }
+ if (fseek (hal_mtab, 0L, SEEK_END) != 0) {
+ HAL_ERROR (("Cannot seek to end of /media/.hal-mtab"));
+ goto out;
+ }
+ hal_mtab_len = ftell (hal_mtab);
+ if (hal_mtab_len < 0) {
+ HAL_ERROR (("Cannot determine size of /media/.hal-mtab"));
+ goto out;
+ }
+ rewind (hal_mtab);
+
+ hal_mtab_buf = g_new0 (char, hal_mtab_len + 1);
+ num_read = fread (hal_mtab_buf, 1, hal_mtab_len, hal_mtab);
+ if (num_read != hal_mtab_len) {
+ HAL_ERROR (("Cannot read from /media/.hal-mtab"));
+ goto out;
+ }
+ fclose (hal_mtab);
+ hal_mtab = NULL;
+
+ /*HAL_DEBUG (("hal_mtab = '%s'\n", hal_mtab_buf));*/
+
+ lines = g_strsplit (hal_mtab_buf, "\n", 0);
+ g_free (hal_mtab_buf);
+ hal_mtab_buf = NULL;
+
+ /* find the entry we're going to unmount */
+ for (i = 0; lines[i] != NULL && !found; i++) {
+ char **line_elements;
+
+ /*HAL_DEBUG ((" line = '%s'", lines[i]));*/
+
+ if ((lines[i])[0] == '#')
+ continue;
+
+ line_elements = g_strsplit (lines[i], "\t", 6);
+ if (g_strv_length (line_elements) == 6) {
+/*
+ HAL_DEBUG ((" devfile = '%s'", line_elements[0]));
+ HAL_DEBUG ((" uid = '%s'", line_elements[1]));
+ HAL_DEBUG ((" session id = '%s'", line_elements[2]));
+ HAL_DEBUG ((" fs = '%s'", line_elements[3]));
+ HAL_DEBUG ((" options = '%s'", line_elements[4]));
+ HAL_DEBUG ((" mount_point = '%s'", line_elements[5]));
+ HAL_DEBUG ((" (comparing against '%s')", mount_point));
+*/
+
+ if (strcmp (line_elements[5], mount_point) == 0) {
+ found = TRUE;
+ /*HAL_INFO (("device at '%s' is indeed mounted by HAL's Mount()", mount_point));*/
+ }
+
+ }
+
+ g_strfreev (line_elements);
+ }
+
+ g_strfreev (lines);
+
+out:
+ if (hal_mtab != NULL)
+ fclose (hal_mtab);
+ if (hal_mtab_buf != NULL)
+ g_free (hal_mtab_buf);
+
+ return found;
+}
+
+void
+hal_util_branch_claim (HalDeviceStore *store, HalDevice *root, dbus_bool_t claimed,
+ const char *service, int uid)
+{
+ GSList *children;
+ GSList *i;
+ HalDevice *d;
+
+ if (claimed) {
+ hal_device_property_set_bool (root, "info.claimed", claimed);
+ hal_device_property_set_string (root, "info.claimed.service", service);
+ hal_device_property_set_int (root, "info.claimed.uid", uid);
+ } else {
+ hal_device_property_remove (root, "info.claimed");
+ hal_device_property_remove (root, "info.claimed.service");
+ hal_device_property_remove (root, "info.claimed.uid");
+ }
+
+
+ children = hal_device_store_match_multiple_key_value_string (store,
+ "info.parent", root->udi);
+
+ for (i = children; i != NULL; i = g_slist_next (i)) {
+ d = HAL_DEVICE (i->data);
+ hal_util_branch_claim (store, d, claimed, service, uid);
+ }
+
+ g_slist_free (children);
+}
diff --git a/usr/src/cmd/hal/hald/util.h b/usr/src/cmd/hal/hald/util.h
new file mode 100644
index 0000000000..a009a44911
--- /dev/null
+++ b/usr/src/cmd/hal/hald/util.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * util.h - Various utilities
+ *
+ * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include "device.h"
+#include "device_store.h"
+
+#ifndef __FUNCTION__
+#define __FUNCTION__ __func__
+#endif
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
+#define HAL_NAME_MAX 256
+#define HAL_PATH_MAX 512
+#define HAL_HELPER_TIMEOUT 10000
+
+gboolean hal_util_remove_trailing_slash (gchar *path);
+
+const gchar *hal_util_get_last_element (const gchar *s);
+
+gchar *hal_util_get_parent_path (const gchar *path);
+
+gchar *hal_util_get_normalized_path (const gchar *path1, const gchar *path2);
+
+gboolean hal_util_get_int_from_file (const gchar *directory, const gchar *file, gint *result, gint base);
+
+gboolean hal_util_set_int_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base);
+
+gboolean hal_util_get_uint64_from_file (const gchar *directory, const gchar *file, guint64 *result, gint base);
+
+gboolean hal_util_set_uint64_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base);
+
+gchar *hal_util_get_string_from_file (const gchar *directory, const gchar *file);
+
+gboolean hal_util_set_string_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file);
+
+gboolean hal_util_get_bcd2_from_file (const gchar *directory, const gchar *file, gint *result);
+
+gboolean hal_util_set_bcd2_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file);
+
+void hal_util_compute_udi (HalDeviceStore *store, gchar *dst, gsize dstsize, const gchar *format, ...);
+
+gboolean hal_util_path_ascend (gchar *path);
+
+void hal_util_grep_discard_existing_data (void);
+
+gchar *hal_util_grep_file (const gchar *directory, const gchar *file, const gchar *linestart, gboolean reuse_file);
+
+gint hal_util_grep_int_elem_from_file (const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, guint base, gboolean reuse_file);
+
+gchar *hal_util_grep_string_elem_from_file (const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, gboolean reuse_file);
+
+gboolean hal_util_set_string_elem_from_file (HalDevice *d, const gchar *key,
+ const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, gboolean reuse_file);
+
+gboolean hal_util_set_int_elem_from_file (HalDevice *d, const gchar *key,
+ const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, guint base, gboolean reuse_file);
+
+gboolean hal_util_set_bool_elem_from_file (HalDevice *d, const gchar *key,
+ const gchar *directory, const gchar *file,
+ const gchar *linestart, guint elem, const gchar *expected,
+ gboolean reuse_file);
+
+gchar **hal_util_dup_strv_from_g_slist (GSList *strlist);
+
+typedef void (*HalCalloutsDone) (HalDevice *d, gpointer userdata1, gpointer userdata2);
+
+void hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2);
+void hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2);
+void hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2);
+
+gchar *hal_util_strdup_valid_utf8 (const char *str);
+
+void hal_util_hexdump (const void *buf, unsigned int size);
+
+gboolean hal_util_is_mounted_by_hald (const char *mount_point);
+
+void
+hal_util_branch_claim (HalDeviceStore *store, HalDevice *root, dbus_bool_t claimed, const char *service, int uid);
+
+#endif /* UTIL_H */
diff --git a/usr/src/cmd/hal/hald/util_helper.c b/usr/src/cmd/hal/hald/util_helper.c
new file mode 100644
index 0000000000..ee97026aa0
--- /dev/null
+++ b/usr/src/cmd/hal/hald/util_helper.c
@@ -0,0 +1,188 @@
+/***************************************************************************
+ *
+ * util_helper.c - HAL utilities for helper (as e.g. prober/addons) et al.
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <grp.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include "logger.h"
+
+#include "util_helper.h"
+
+#ifdef __linux__
+extern char **environ;
+#endif
+
+static char **argv_buffer = NULL;
+static size_t argv_size = 0;
+
+#ifdef sun
+#include <priv.h>
+void
+drop_privileges (int keep_auxgroups)
+{
+ priv_set_t *pPrivSet = NULL;
+ priv_set_t *lPrivSet = NULL;
+
+ /*
+ * Start with the 'basic' privilege set and then remove any
+ * of the 'basic' privileges that will not be needed.
+ */
+ if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ return;
+ }
+
+ /* Clear privileges we will not need from the 'basic' set */
+ (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
+ (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
+ (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
+
+ /* for sysevent need to be root and have this privilege */
+ (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG);
+
+ /* Set the permitted privilege set. */
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
+ return;
+ }
+
+ /* Clear the limit set. */
+ if ((lPrivSet = priv_allocset()) == NULL) {
+ return;
+ }
+
+ priv_emptyset(lPrivSet);
+
+ if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
+ return;
+ }
+
+ priv_freeset(lPrivSet);
+}
+#else /* !sun */
+
+/** Drop root privileges: Set the running user id to HAL_USER and
+ * group to HAL_GROUP, and optionally retain auxiliary groups of HAL_USER.
+ */
+void
+drop_privileges (int keep_auxgroups)
+{
+ struct passwd *pw = NULL;
+ struct group *gr = NULL;
+
+ /* determine user id */
+ pw = getpwnam (HAL_USER);
+ if (!pw) {
+ HAL_DEBUG (("drop_privileges: user " HAL_USER " does not exist"));
+ exit (-1);
+ }
+
+ /* determine primary group id */
+ gr = getgrnam (HAL_GROUP);
+ if (!gr) {
+ HAL_DEBUG (("drop_privileges: group " HAL_GROUP " does not exist"));
+ exit (-1);
+ }
+
+ if (keep_auxgroups) {
+ if (initgroups (HAL_USER, gr->gr_gid)) {
+ HAL_DEBUG(("drop_privileges: could not initialize groups"));
+ exit (-1);
+ }
+ }
+
+ if (setgid (gr->gr_gid)) {
+ HAL_DEBUG (("drop_privileges: could not set group id"));
+ exit (-1);
+ }
+
+ if (setuid (pw->pw_uid)) {
+ HAL_DEBUG (("drop_privileges: could not set user id"));
+ exit (-1);
+ }
+}
+#endif /* !sun */
+
+void
+hal_set_proc_title_init (int argc, char *argv[])
+{
+#ifdef __linux__
+ unsigned int i;
+ char **new_environ, *endptr;
+
+ /* This code is really really ugly. We make some memory layout
+ * assumptions and reuse the environment array as memory to store
+ * our process title in */
+
+ for (i = 0; environ[i] != NULL; i++)
+ ;
+
+ endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]);
+
+ argv_buffer = argv;
+ argv_size = endptr - argv_buffer[0];
+
+ /* Make a copy of environ */
+
+ new_environ = malloc (sizeof(char*) * (i + 1));
+ for (i = 0; environ[i] != NULL; i++)
+ new_environ[i] = strdup (environ[i]);
+ new_environ[i] = NULL;
+
+ environ = new_environ;
+#endif
+}
+
+/* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */
+void
+hal_set_proc_title (const char *format, ...)
+{
+#ifdef __linux__
+ size_t len;
+ va_list ap;
+
+ if (argv_buffer == NULL)
+ goto out;
+
+ va_start (ap, format);
+ vsnprintf (argv_buffer[0], argv_size, format, ap);
+ va_end (ap);
+
+ len = strlen (argv_buffer[0]);
+
+ memset (argv_buffer[0] + len, 0, argv_size - len);
+ argv_buffer[1] = NULL;
+out:
+ ;
+#endif
+}
+
diff --git a/usr/src/cmd/hal/hald/util_helper.h b/usr/src/cmd/hal/hald/util_helper.h
new file mode 100644
index 0000000000..b9309f4a56
--- /dev/null
+++ b/usr/src/cmd/hal/hald/util_helper.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+ *
+ * util_helper.h - HAL utilities for helper (as e.g. prober/addons) et al.
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifndef UTIL_HELPER_H
+#define UTIL_HELPER_H
+
+void drop_privileges (int keep_auxgroups);
+void hal_set_proc_title_init (int argc, char *argv[]);
+void hal_set_proc_title (const char *format, ...);
+
+#endif /* UTIL_HELPER_H */
diff --git a/usr/src/cmd/hal/hald/util_pm.c b/usr/src/cmd/hal/hald/util_pm.c
new file mode 100644
index 0000000000..0bc62e8184
--- /dev/null
+++ b/usr/src/cmd/hal/hald/util_pm.c
@@ -0,0 +1,227 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * utili_pm.c - Various Powermanagement related utilities
+ *
+ * Copyright (C) 2005 Richard Hughes <richard@hughsie.com>
+ * Copyright (C) 2005 Danny Kukawka <danny.kukawka@web.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include <glib.h>
+
+#include "logger.h"
+
+#include "util_pm.h"
+
+typedef struct {
+ int last_level;
+ int last_chargeRate;
+ time_t last_time;
+} batteryInfo;
+
+GHashTable *saved_battery_info = NULL;
+
+/** Convert the hardware reported value into a few sane choices
+ *
+ * This is needed as ACPI does not specify the description text for a
+ * battery, and so we have to calculate it from the hardware output
+ *
+ * @param type The battery type recieved from the hardware
+ * @return The battery technology which is one of:
+ * unknown, lithium-ion or lead-acid
+ */
+const char *
+util_get_battery_technology (const char *type)
+{
+ if (type == NULL) {
+ return "unknown";
+ }
+ /* every case combination of Li-Ion is commonly used.. */
+ if (strcasecmp (type, "li-ion") == 0 ||
+ strcasecmp (type, "lion") == 0) {
+ return "lithium-ion";
+ }
+ if (strcasecmp (type, "pb") == 0 ||
+ strcasecmp (type, "pbac") == 0) {
+ return "lead-acid";
+ }
+ if (strcasecmp (type, "lip") == 0) {
+ return "lithium-polymer";
+ }
+ if (strcasecmp (type, "nimh") == 0) {
+ return "nickel-metal-hydride";
+ }
+ return "unknown";
+}
+
+/** Given all the required parameters, this function will return the percentage
+ * charge remaining. There are lots of checks here as ACPI is often broken.
+ *
+ * @param id Optional ID given to this battery. Unused at present.
+ * @param chargeLevel The current charge level of the battery (typically mWh)
+ * @param chargeLastFull The last "full" charge of the battery (typically mWh)
+ * @return Percentage, -1 if invalid
+ */
+int
+util_compute_percentage_charge (const char *id,
+ int chargeLevel,
+ int chargeLastFull)
+{
+ int percentage;
+ /* make sure we have chargelevel */
+ if (chargeLevel <= 0) {
+ HAL_WARNING (("chargeLevel %i, returning -1!", chargeLevel));
+ return -1;
+ }
+ /* make sure not division by zero */
+ if (chargeLastFull > 0)
+ percentage = ((double) chargeLevel / (double) chargeLastFull) * 100;
+ else {
+ HAL_WARNING (("chargeLastFull %i, percentage returning -1!", chargeLastFull));
+ return -1;
+ }
+ /* Some bios's will report this higher than 100, limit it here */
+ if (percentage > 100) {
+ HAL_WARNING (("Percentage %i, returning 100!", percentage));
+ return 100;
+ }
+ /* Something really isn't right if we get a negative... */
+ if (percentage < 0) {
+ HAL_WARNING (("Percentage %i, returning -1!", percentage));
+ return -1;
+ }
+ return percentage;
+}
+
+/** Given all the required parameters, this function will return the number
+ * of seconds until the battery is charged (if charging) or the number
+ * of seconds until empty (if discharging)
+ *
+ * @param id Optional ID given to this battery. Unused at present.
+ * @param chargeRate The "rate" (typically mW)
+ * @param chargeLevel The current charge level of the battery (typically mWh)
+ * @param chargeLastFull The last "full" charge of the battery (typically mWh)
+ * @param isDischarging If battery is discharging
+ * @param isCharging If battery is charging
+ * @param guessChargeRate If ignore chargeRate and guess them.
+ * @return Number of seconds, or -1 if invalid
+ */
+int
+util_compute_time_remaining (const char *id,
+ int chargeRate,
+ int chargeLevel,
+ int chargeLastFull,
+ gboolean isDischarging,
+ gboolean isCharging,
+ gboolean guessChargeRate)
+{
+ int remaining_time = 0;
+
+ /* should not get negative values */
+ if (chargeRate < 0 || chargeLevel < 0 || chargeLastFull < 0) {
+ HAL_WARNING (("chargeRate, chargeLevel or chargeLastFull < 0, returning -1"));
+ return -1;
+ }
+ /* batteries cannot charge and discharge at the same time */
+ if (isDischarging && isCharging) {
+ HAL_WARNING (("isDischarging & isCharging TRUE, returning -1"));
+ return -1;
+ }
+ /*
+ * Some laptops don't supply any rate info, but that's no reason for HAL not
+ * to. We use the current and previous chargeLevel to estimate the rate.
+ * The info is stored in a GHashTable because there could be more than one battery.
+ */
+ if (chargeRate == 0 || guessChargeRate) {
+ batteryInfo *battery_info;
+ time_t cur_time = time(NULL);
+
+ /* Initialize the save_battery_info GHashTable */
+ if (!saved_battery_info)
+ saved_battery_info = g_hash_table_new(g_str_hash, g_str_equal);
+
+ if ((battery_info = g_hash_table_lookup(saved_battery_info, id))) {
+ /* check this to prevent division by zero */
+ if ((cur_time == battery_info->last_time) || (chargeLevel == battery_info->last_level)) {
+ /* if we can't calculate because nothing changed, use last
+ * chargeRate to prevent removing battery.remaining_time.
+ */
+ chargeRate = battery_info->last_chargeRate;
+ } else {
+ chargeRate = ((chargeLevel - battery_info->last_level) * 60 * 60) / (cur_time - battery_info->last_time);
+ /*
+ * During discharging chargeRate would be negative, which would
+ * mess up the the calculation below, so we make sure it's always
+ * positive.
+ */
+ chargeRate = (chargeRate > 0) ? chargeRate : -chargeRate;
+
+ battery_info->last_level = chargeLevel;
+ battery_info->last_time = cur_time;
+ battery_info->last_chargeRate = chargeRate;
+ }
+ } else {
+ battery_info = g_new0(batteryInfo, 1);
+ g_hash_table_insert(saved_battery_info, (char*) id, battery_info);
+
+ battery_info->last_level = chargeLevel;
+ battery_info->last_time = cur_time;
+ battery_info->last_chargeRate = 0;
+ return -1;
+ }
+ }
+
+ if (chargeRate == 0)
+ return -1;
+
+ if (isDischarging) {
+ remaining_time = ((double) chargeLevel / (double) chargeRate) * 60 * 60;
+ } else if (isCharging) {
+ /*
+ * Some ACPI BIOS's don't update chargeLastFull,
+ * so return 0 as we don't know how much more there is left
+ */
+ if (chargeLevel > chargeLastFull ) {
+ HAL_WARNING (("chargeLevel > chargeLastFull, returning -1"));
+ return -1;
+ }
+ remaining_time = ((double) (chargeLastFull - chargeLevel) / (double) chargeRate) * 60 * 60;
+ }
+
+ /* This shouldn't happen, but check for completeness */
+ if (remaining_time < 0) {
+ HAL_WARNING (("remaining_time %i, returning -1", remaining_time));
+ remaining_time = -1;
+ }
+ /* Battery life cannot be above 60 hours */
+ else if (remaining_time > 60*60*60) {
+ HAL_WARNING (("remaining_time *very* high, returning -1"));
+ remaining_time = -1;
+ }
+
+ return remaining_time;
+}
+
diff --git a/usr/src/cmd/hal/hald/util_pm.h b/usr/src/cmd/hal/hald/util_pm.h
new file mode 100644
index 0000000000..977531e97a
--- /dev/null
+++ b/usr/src/cmd/hal/hald/util_pm.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * util_pm.h - Various Powermanagement related utilities
+ *
+ * Copyright (C) 2005 Richard Hughes <richard@hughsie.com>
+ * Copyright (C) 2005 Danny Kukawka <danny.kukawka@web.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef UTIL_PM_H
+#define UTIL_PM_H
+
+const char *util_get_battery_technology (const char *type);
+
+int util_compute_time_remaining (const char *id, int chargeRate, int chargeLevel, int chargeLastFull,
+ gboolean isDischarging, gboolean isCharging, gboolean guessChargeRate);
+
+int util_compute_percentage_charge (const char *id, int chargeLevel, int chargeLastFull);
+
+#endif /* UTIL__PM_H */
diff --git a/usr/src/cmd/hal/inc.flg b/usr/src/cmd/hal/inc.flg
new file mode 100644
index 0000000000..74eb76a698
--- /dev/null
+++ b/usr/src/cmd/hal/inc.flg
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+find_files "s.*" usr/src/lib/hal
+find_files "s.*" usr/src/lib/policykit
+find_files "s.*" usr/src/cmd/policykit
+
+echo_file usr/src/lib/Makefile.lib
+echo_file usr/src/lib/Makefile.targ
+
diff --git a/usr/src/cmd/hal/probing/Makefile b/usr/src/cmd/hal/probing/Makefile
new file mode 100644
index 0000000000..32f487783c
--- /dev/null
+++ b/usr/src/cmd/hal/probing/Makefile
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUBDIRS = storage volume
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+
+.KEEP_STATE:
+
+all install clean clobber: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/cmd/hal/probing/storage/Makefile b/usr/src/cmd/hal/probing/storage/Makefile
new file mode 100644
index 0000000000..76450e1743
--- /dev/null
+++ b/usr/src/cmd/hal/probing/storage/Makefile
@@ -0,0 +1,71 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = hald-probe-storage
+OBJS = probe-storage.o cdutils.o fsutils.o logger.o
+SRCS = addon-storage.c
+
+include ../../../Makefile.cmd
+include ../../Makefile.hal
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -ldbus-1 -lhal -ladm -lefi
+
+CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal -I../../utils -I../../hald
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+logger.o: ../../hald/logger.c
+ $(COMPILE.c) -o $@ ../../hald/logger.c
+ $(POST_PROCESS_O)
+
+fsutils.o: ../../utils/fsutils.c
+ $(COMPILE.c) -o $@ ../../utils/fsutils.c
+ $(POST_PROCESS_O)
+
+cdutils.o: ../../utils/cdutils.c
+ $(COMPILE.c) -o $@ ../../utils/cdutils.c
+ $(POST_PROCESS_O)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD)
+
+clean:
+ $(RM) $(OBJS)
+
+FRC:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/hal/probing/storage/probe-storage.c b/usr/src/cmd/hal/probing/storage/probe-storage.c
new file mode 100644
index 0000000000..7a75f399be
--- /dev/null
+++ b/usr/src/cmd/hal/probing/storage/probe-storage.c
@@ -0,0 +1,488 @@
+/***************************************************************************
+ *
+ * probe-storage.c : Probe for storage devices
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mnttab.h>
+#include <sys/fdio.h>
+#include <sys/scsi/scsi.h>
+#include <sys/vtoc.h>
+#include <sys/efi_partition.h>
+#include <priv.h>
+
+#include <libhal.h>
+#include <cdutils.h>
+#include <fsutils.h>
+#include <logger.h>
+
+/** Check if a filesystem on a special device file is mounted
+ *
+ * @param device_file Special device file, e.g. /dev/cdrom
+ * @return TRUE iff there is a filesystem system mounted
+ * on the special device file
+ */
+static dbus_bool_t
+is_mounted (const char *device_file)
+{
+ FILE *f;
+ dbus_bool_t rc = FALSE;
+ struct mnttab mp;
+ struct mnttab mpref;
+
+ if ((f = fopen ("/etc/mnttab", "r")) == NULL)
+ return rc;
+
+ bzero(&mp, sizeof (mp));
+ bzero(&mpref, sizeof (mpref));
+ mpref.mnt_special = (char *)device_file;
+ if (getmntany(f, &mp, &mpref) == 0) {
+ rc = TRUE;
+ }
+
+ fclose (f);
+ return rc;
+}
+
+static int
+get_cdrom_properties_walker (void *arg, int profile, boolean_t is_current)
+{
+ LibHalChangeSet *cs = (LibHalChangeSet *)arg;
+
+ switch (profile) {
+ case 0x09:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", TRUE);
+ break;
+ case 0x0a:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", TRUE);
+ break;
+ case 0x10:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", TRUE);
+ break;
+ case 0x11:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", TRUE);
+ break;
+ case 0x12:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", TRUE);
+ break;
+ case 0x13:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
+ break;
+ case 0x14:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
+ break;
+ case 0x1a:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", TRUE);
+ break;
+ case 0x1b:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", TRUE);
+ break;
+ case 0x2b:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", TRUE);
+ break;
+ case 0x40:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", TRUE);
+ break;
+ case 0x41:
+ case 0x42:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", TRUE);
+ break;
+ case 0x43:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", TRUE);
+ break;
+ case 0x50:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", TRUE);
+ break;
+ case 0x51:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", TRUE);
+ break;
+ case 0x52:
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", TRUE);
+ break;
+ }
+
+ return CDUTIL_WALK_CONTINUE;
+}
+
+#define WSPLEN 64
+
+static void
+get_cdrom_properties (int fd, LibHalChangeSet *cs)
+{
+ DBusError error;
+ int capabilities;
+ int read_speed, write_speed;
+ intlist_t *write_speeds, *write_speeds_mem, *sp;
+ int n_wspeeds;
+ char **wspeeds;
+ char *wspeeds_mem;
+ int i;
+
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", FALSE);
+
+ walk_profiles(fd, get_cdrom_properties_walker, cs);
+
+ /* XXX */
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", TRUE);
+
+ get_read_write_speeds(fd, &read_speed, &write_speed, &write_speeds, &n_wspeeds, &write_speeds_mem);
+
+ libhal_changeset_set_property_int (cs, "storage.cdrom.read_speed", read_speed);
+ libhal_changeset_set_property_int (cs, "storage.cdrom.write_speed", write_speed);
+
+ if (n_wspeeds <= 0) {
+ wspeeds_mem = NULL;
+ libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)&wspeeds_mem);
+ return;
+ }
+ if ((wspeeds = (char **)calloc(n_wspeeds + 1, sizeof (char *))) == NULL) {
+ free (write_speeds_mem);
+ return;
+ }
+ if ((wspeeds_mem = (char *)calloc(n_wspeeds, WSPLEN)) == NULL) {
+ free (wspeeds);
+ free (write_speeds_mem);
+ return;
+ }
+ for (i = 0; i < n_wspeeds; i++) {
+ wspeeds[i] = &wspeeds_mem[i * WSPLEN];
+ }
+
+ for (sp = write_speeds, i = 0; sp != NULL; sp = sp->next, i++) {
+ snprintf (wspeeds[i], WSPLEN, "%d", sp->val);
+ }
+ libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", (const char **)wspeeds);
+
+ free (wspeeds);
+ free (wspeeds_mem);
+ free (write_speeds_mem);
+}
+
+/*
+ * Return a copy of a string without trailing spaces. If 'len' is non-zero,
+ * it specifies max length, otherwise the string must be null-terminated.
+ */
+char *
+rtrim_copy(char *src, int len)
+{
+ char *dst, *p;
+
+ if (len == 0) {
+ len = strlen(src);
+ }
+ if ((dst = calloc(1, len + 1)) != NULL) {
+ strncpy(dst, src, len);
+ p = dst + len - 1;
+ while ((p >= dst) && (isspace(*p))) {
+ *p-- = '\0';
+ }
+ }
+ return (dst);
+}
+
+static void
+get_disk_properties (int fd, LibHalChangeSet *cs)
+{
+ struct scsi_inquiry inq;
+ struct uscsi_cmd ucmd;
+ union scsi_cdb cdb;
+ int status;
+ char *s;
+
+ /* INQUIRY */
+ (void) memset((void *) &inq, 0, sizeof (inq));
+ (void) memset((void *) &ucmd, 0, sizeof (ucmd));
+ (void) memset((void *) &cdb, 0, sizeof (union scsi_cdb));
+ cdb.scc_cmd = SCMD_INQUIRY;
+ FORMG0COUNT(&cdb, sizeof (inq));
+ ucmd.uscsi_cdb = (caddr_t) & cdb;
+ ucmd.uscsi_cdblen = CDB_GROUP0;
+ ucmd.uscsi_bufaddr = (caddr_t) & inq;
+ ucmd.uscsi_buflen = sizeof (inq);
+ ucmd.uscsi_timeout = 30;
+ ucmd.uscsi_flags = USCSI_READ;
+ status = ioctl(fd, USCSICMD, &ucmd);
+ if (status || ucmd.uscsi_status) {
+ return;
+ }
+
+ if ((s = rtrim_copy(inq.inq_vid, sizeof (inq.inq_vid))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.vendor", s);
+ free(s);
+ }
+ if ((s = rtrim_copy(inq.inq_pid, sizeof (inq.inq_pid))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.model", s);
+ free(s);
+ }
+ if ((s = rtrim_copy(inq.inq_revision, sizeof (inq.inq_revision))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.firmware_revision", s);
+ free(s);
+ }
+ if ((s = rtrim_copy(inq.inq_serial, sizeof (inq.inq_serial))) != NULL) {
+ libhal_changeset_set_property_string (cs, "storage.serial", s);
+ free(s);
+ }
+}
+
+/*
+ * returns TRUE if diskette is inserted.
+ * also returns write protection status.
+ */
+static dbus_bool_t
+check_floppy(int fd, dbus_bool_t *wprot)
+{
+ int chg;
+
+ if ((ioctl(fd, FDGETCHANGE, &chg) == 0) && !(chg & FDGC_CURRENT)) {
+ *wprot = ((chg & FDGC_CURWPROT) != NULL);
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+
+void
+drop_privileges ()
+{
+ priv_set_t *pPrivSet = NULL;
+ priv_set_t *lPrivSet = NULL;
+
+ /*
+ * Start with the 'basic' privilege set and then remove any
+ * of the 'basic' privileges that will not be needed.
+ */
+ if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ return;
+ }
+
+ /* Clear privileges we will not need from the 'basic' set */
+ (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
+ (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
+ (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
+ (void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
+ (void) priv_delset(pPrivSet, PRIV_PROC_FORK);
+
+ /* for uscsi */
+ (void) priv_addset(pPrivSet, PRIV_SYS_DEVICES);
+
+ /* to open logindevperm'd devices */
+ (void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
+
+ /* Set the permitted privilege set. */
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
+ return;
+ }
+
+ /* Clear the limit set. */
+ if ((lPrivSet = priv_allocset()) == NULL) {
+ return;
+ }
+
+ priv_emptyset(lPrivSet);
+
+ if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
+ return;
+ }
+
+ priv_freeset(lPrivSet);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret = 1;
+ int fd = -1;
+ int rfd = -1;
+ char *udi;
+ char *device_file;
+ char *raw_device_file;
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ char *bus;
+ char *drive_type;
+ dbus_bool_t is_cdrom;
+ dbus_bool_t is_floppy;
+ struct dk_minfo minfo;
+ dbus_bool_t only_check_for_media;
+ int got_media = FALSE;
+ dbus_bool_t is_write_protected = FALSE;
+ dbus_bool_t is_mbr = FALSE;
+ dbus_bool_t is_smi = FALSE;
+ dbus_bool_t is_gpt = FALSE;
+ dbus_bool_t is_partitioned = FALSE;
+ dbus_bool_t vtoc_slices = FALSE;
+ int dos_cnt = 0;
+ const char *scheme = "";
+ struct vtoc vtoc;
+ dk_gpt_t *gpt;
+ LibHalChangeSet *cs = NULL;
+
+ if ((udi = getenv ("UDI")) == NULL)
+ goto out;
+ if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
+ goto out;
+ if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
+ goto out;
+ if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
+ goto out;
+ if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
+ goto out;
+
+ drop_privileges ();
+
+ setup_logger ();
+
+ if (argc == 2 && strcmp (argv[1], "--only-check-for-media") == 0)
+ only_check_for_media = TRUE;
+ else
+ only_check_for_media = FALSE;
+
+ is_cdrom = (strcmp (drive_type, "cdrom") == 0);
+ is_floppy = (strcmp (drive_type, "floppy") == 0);
+
+ dbus_error_init (&error);
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+ goto out;
+
+ if ((cs = libhal_device_new_changeset (udi)) == NULL) {
+ HAL_DEBUG (("Cannot allocate changeset"));
+ goto out;
+ }
+
+ HAL_DEBUG (("Doing probe-storage for %s (bus %s) (drive_type %s) (udi=%s) (--only-check-for-media==%d)",
+ device_file, bus, drive_type, udi, only_check_for_media));
+
+ if ((rfd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0) {
+ HAL_DEBUG (("Cannot open %s: %s", raw_device_file, strerror (errno)));
+ goto out;
+ }
+
+ if (!only_check_for_media) {
+ if (strcmp (drive_type, "cdrom") == 0) {
+ get_cdrom_properties (rfd, cs);
+ } else if (strcmp (drive_type, "disk") == 0) {
+ get_disk_properties (rfd, cs);
+ }
+ }
+
+ ret = 0;
+
+ if (is_cdrom) {
+ HAL_DEBUG (("Checking for optical disc on %s", raw_device_file));
+ got_media = get_media_info(rfd, &minfo);
+ if (!got_media) {
+ goto out_cs;
+ }
+ /* XXX */
+ is_write_protected = TRUE;
+ } else if (is_floppy) {
+ HAL_DEBUG (("Checking for floppy on %s", raw_device_file));
+ if (check_floppy(rfd, &is_write_protected)) {
+ got_media = TRUE;
+ }
+ /* don't look for partitions on floppy */
+ goto out_cs;
+ } else {
+ got_media = TRUE;
+ }
+
+ HAL_DEBUG (("Checking for partitions on %s", device_file));
+
+ if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
+ HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno)));
+ goto out_cs;
+ }
+
+ dos_cnt = get_num_dos_drives(fd);
+ is_mbr = (dos_cnt > 0);
+ if (is_mbr) {
+ scheme = "mbr";
+ }
+ if (read_vtoc(rfd, &vtoc) >= 0) {
+ if (!vtoc_one_slice_entire_disk(&vtoc)) {
+ is_smi = TRUE;
+ if (!is_mbr) {
+ /* smi within mbr partition is okay */
+ scheme = "smi";
+ }
+ vtoc_slices = TRUE;
+ }
+ } else if (!is_cdrom && (efi_alloc_and_read(rfd, &gpt) >= 0)) {
+ /*
+ * Note: for some reason efi_read takes very long on cdroms.
+ * Needs more investigation, skip gpt on cdrom for now.
+ */
+ is_gpt = TRUE;
+ scheme = "gpt";
+ efi_free(gpt);
+ }
+
+out_cs:
+ is_partitioned = is_mbr || is_smi || is_gpt;
+ libhal_changeset_set_property_bool (cs, "storage.no_partitions_hint", !is_partitioned);
+ libhal_changeset_set_property_bool (cs, "block.no_partitions", !is_partitioned);
+ libhal_changeset_set_property_string (cs, "storage.partitioning_scheme", scheme);
+ libhal_changeset_set_property_bool (cs, "storage.solaris.vtoc_slices", vtoc_slices);
+ libhal_changeset_set_property_int (cs, "storage.solaris.num_dos_partitions", dos_cnt);
+ /* XXX should only set for removable drives */
+ libhal_changeset_set_property_bool (cs, "storage.removable.media_available", got_media);
+ libhal_changeset_set_property_bool (cs, "storage.removable.solaris.read_only", is_write_protected);
+
+ libhal_device_commit_changeset (ctx, cs, &error);
+
+out:
+ if (cs != NULL) {
+ libhal_device_free_changeset (cs);
+ }
+ if (fd >= 0) {
+ close (fd);
+ }
+ if (rfd >= 0) {
+ close (rfd);
+ }
+ if (ctx != NULL) {
+ if (dbus_error_is_set(&error)) {
+ dbus_error_free (&error);
+ }
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return ret;
+}
diff --git a/usr/src/cmd/hal/probing/volume/Makefile b/usr/src/cmd/hal/probing/volume/Makefile
new file mode 100644
index 0000000000..a9cd36186b
--- /dev/null
+++ b/usr/src/cmd/hal/probing/volume/Makefile
@@ -0,0 +1,71 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = hald-probe-volume
+OBJS = probe-volume.o cdutils.o fsutils.o logger.o
+SRCS = probe-volume.c
+
+include ../../../Makefile.cmd
+include ../../Makefile.hal
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -ldbus-1 -lhal -lfstyp -lnvpair -ladm -lefi
+
+CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal -I../../utils -I../../hald
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+logger.o: ../../hald/logger.c
+ $(COMPILE.c) -o $@ ../../hald/logger.c
+ $(POST_PROCESS_O)
+
+fsutils.o: ../../utils/fsutils.c
+ $(COMPILE.c) -o $@ ../../utils/fsutils.c
+ $(POST_PROCESS_O)
+
+cdutils.o: ../../utils/cdutils.c
+ $(COMPILE.c) -o $@ ../../utils/cdutils.c
+ $(POST_PROCESS_O)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD)
+
+clean:
+ $(RM) $(OBJS)
+
+FRC:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/hal/probing/volume/probe-volume.c b/usr/src/cmd/hal/probing/volume/probe-volume.c
new file mode 100644
index 0000000000..005948b67e
--- /dev/null
+++ b/usr/src/cmd/hal/probing/volume/probe-volume.c
@@ -0,0 +1,569 @@
+/***************************************************************************
+ *
+ * probe-volume.c : probe volumes
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/dkio.h>
+#include <sys/cdio.h>
+#include <sys/fdio.h>
+#include <libnvpair.h>
+#include <libfstyp.h>
+#include <sys/vtoc.h>
+#include <sys/efi_partition.h>
+#include <priv.h>
+
+#include <libhal.h>
+#include <cdutils.h>
+#include <fsutils.h>
+#include <logger.h>
+
+static void
+my_dbus_error_free(DBusError *error)
+{
+ if (dbus_error_is_set(error)) {
+ dbus_error_free(error);
+ }
+}
+
+/*
+ * Return a copy of a string without trailing spaces. If 'len' is non-zero,
+ * it specifies max length, otherwise the string must be null-terminated.
+ */
+static char *
+rtrim_copy(char *src, int len)
+{
+ char *dst, *p;
+
+ if (len == 0) {
+ len = strlen(src);
+ }
+ if ((dst = calloc(1, len + 1)) != NULL) {
+ strncpy(dst, src, len);
+ p = dst + len - 1;
+ while ((p >= dst) && (isspace(*p))) {
+ *p-- = '\0';
+ }
+ }
+ return (dst);
+}
+
+static void
+set_fstyp_properties (LibHalContext *ctx, const char *udi, const char *fstype, nvlist_t *fsattr)
+{
+ char buf[256];
+ DBusError error;
+ char *uuid = NULL;
+ char *label_orig = NULL;
+ char *label = NULL;
+ LibHalChangeSet *cs;
+
+ dbus_error_init (&error);
+
+ if ((cs = libhal_device_new_changeset (udi)) == NULL) {
+ return;
+ }
+
+ libhal_changeset_set_property_string (cs, "volume.fsusage", "filesystem");
+ libhal_changeset_set_property_string (cs, "volume.fstype", fstype);
+
+ /* label */
+ (void) nvlist_lookup_string(fsattr, "gen_volume_label", &label_orig);
+ if (label_orig != NULL) {
+ label = rtrim_copy(label_orig, 0);
+ }
+ if ((label != NULL) && (label[0] != '\0')) {
+ libhal_changeset_set_property_string (cs, "volume.label", label);
+ libhal_changeset_set_property_string (cs, "info.product", label);
+ } else {
+ libhal_changeset_set_property_string (cs, "volume.label", "");
+ snprintf (buf, sizeof (buf), "Volume (%s)", fstype);
+ libhal_changeset_set_property_string (cs, "info.product", buf);
+ }
+ free(label);
+
+ /* uuid */
+ if (nvlist_lookup_string(fsattr, "gen_uuid", &uuid) == 0) {
+ libhal_changeset_set_property_string (cs, "volume.uuid", uuid);
+ } else {
+ libhal_changeset_set_property_string (cs, "volume.uuid", "");
+ }
+
+ libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_free_changeset (cs);
+
+ my_dbus_error_free (&error);
+}
+
+dbus_bool_t
+probe_disc (int fd, LibHalContext *ctx, const char *udi, dbus_bool_t *should_probe_for_fs)
+{
+ DBusError error;
+ disc_info_t di;
+ int profile;
+ dbus_bool_t has_audio, has_data, is_blank, is_appendable, is_rewritable;
+ char *disc_type = "cd_rom";
+ uint64_t capacity = 0;
+ int i;
+ LibHalChangeSet *cs;
+
+ dbus_error_init (&error);
+
+ if (get_disc_info (fd, &di)) {
+ is_blank = (di.disc_status == 0);
+ is_appendable = (di.disc_status == 1);
+ is_rewritable = (di.erasable != 0);
+ } else {
+ is_blank = is_appendable = is_rewritable = FALSE;
+ }
+
+ if (get_current_profile (fd, &profile)) {
+ switch (profile) {
+ case 0x08: /* CD-ROM */
+ disc_type = "cd_rom";
+ break;
+ case 0x09: /* CD-R */
+ disc_type = "cd_r";
+ break;
+ case 0x0A: /* CD-RW */
+ disc_type = "cd_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x10: /* DVD-ROM */
+ disc_type = "dvd_rom";
+ break;
+ case 0x11: /* DVD-R Sequential */
+ disc_type = "dvd_r";
+ break;
+ case 0x12: /* DVD-RAM */
+ disc_type = "dvd_ram";
+ is_rewritable = TRUE;
+ break;
+ case 0x13: /* DVD-RW Restricted Overwrite */
+ disc_type = "dvd_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x14: /* DVD-RW Sequential */
+ disc_type = "dvd_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x1A: /* DVD+RW */
+ disc_type = "dvd_plus_rw";
+ is_rewritable = TRUE;
+ break;
+ case 0x1B: /* DVD+R */
+ disc_type = "dvd_plus_r";
+ break;
+ case 0x2B: /* DVD+R Double Layer */
+ disc_type = "dvd_plus_r_dl";
+ break;
+ case 0x40: /* BD-ROM */
+ disc_type = "bd_rom";
+ break;
+ case 0x41: /* BD-R Sequential */
+ disc_type = "bd_r";
+ break;
+ case 0x42: /* BD-R Random */
+ disc_type = "bd_r";
+ break;
+ case 0x43: /* BD-RE */
+ disc_type = "bd_re";
+ is_rewritable = TRUE;
+ break;
+ case 0x50: /* HD DVD-ROM */
+ disc_type = "hddvd_rom";
+ break;
+ case 0x51: /* HD DVD-R */
+ disc_type = "hddvd_r";
+ break;
+ case 0x52: /* HD DVD-Rewritable */
+ disc_type = "hddvd_rw";
+ is_rewritable = TRUE;
+ break;
+ }
+
+ (void) get_disc_capacity_for_profile(fd, profile, &capacity);
+ }
+
+ has_audio = has_data = FALSE;
+ if (!is_blank) {
+ uchar_t smalltoc[12];
+ size_t toc_size;
+ uchar_t *toc, *p;
+
+ /*
+ * XXX for some reason CDROMREADTOCENTRY fails on video DVDs,
+ * but extracting the toc directly works okay.
+ */
+ if (!read_toc(fd, 0, 1, 4, smalltoc)) {
+ HAL_DEBUG(("read_toc failed"));
+ has_data = B_TRUE; /* probe for fs anyway */
+ } else {
+ toc_size = smalltoc[0] * 256 + smalltoc[1] + 2;
+ toc = (uchar_t *)calloc(1, toc_size);
+ if (toc == NULL || !read_toc(fd, 0, 1, toc_size, toc)) {
+ HAL_DEBUG (("read_toc again failed"));
+ } else {
+ for (p = &toc[4]; p < (toc + toc_size); p += 8) {
+ /* skip leadout */
+ if (p[2] == 0xAA) {
+ continue;
+ }
+ if (p[1] & 4) {
+ has_data = B_TRUE;
+ } else {
+ has_audio = B_TRUE;
+ }
+ }
+ }
+ free(toc);
+ }
+ }
+
+ if ((cs = libhal_device_new_changeset (udi)) == NULL) {
+ return (FALSE);
+ }
+ libhal_changeset_set_property_string (cs, "volume.disc.type", disc_type);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", is_blank);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", has_audio);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_data", has_data);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", is_appendable);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", is_rewritable);
+ libhal_changeset_set_property_uint64 (cs, "volume.disc.capacity", capacity);
+
+ libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_free_changeset (cs);
+
+out:
+
+ *should_probe_for_fs = has_data;
+
+ my_dbus_error_free (&error);
+
+ return (TRUE);
+}
+
+void
+drop_privileges ()
+{
+ priv_set_t *pPrivSet = NULL;
+ priv_set_t *lPrivSet = NULL;
+
+ /*
+ * Start with the 'basic' privilege set and then remove any
+ * of the 'basic' privileges that will not be needed.
+ */
+ if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ return;
+ }
+
+ /* Clear privileges we will not need from the 'basic' set */
+ (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
+ (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
+ (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
+ (void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
+ (void) priv_delset(pPrivSet, PRIV_PROC_FORK);
+
+ /* for uscsi */
+ (void) priv_addset(pPrivSet, PRIV_SYS_DEVICES);
+
+
+ /* to open logindevperm'd devices */
+ (void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
+
+ /* Set the permitted privilege set. */
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
+ return;
+ }
+
+ /* Clear the limit set. */
+ if ((lPrivSet = priv_allocset()) == NULL) {
+ return;
+ }
+
+ priv_emptyset(lPrivSet);
+
+ if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
+ return;
+ }
+
+ priv_freeset(lPrivSet);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int fd, rfd;
+ int ret;
+ char *udi;
+ char *device_file, *raw_device_file;
+ char *devpath, *rdevpath;
+ boolean_t is_dos;
+ int dos_num;
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ DBusConnection *conn;
+ char *parent_udi;
+ char *storage_device;
+ char *is_disc_str;
+ int fdc;
+ dbus_bool_t is_disc = FALSE;
+ dbus_bool_t is_floppy = FALSE;
+ unsigned int block_size;
+ dbus_uint64_t vol_size;
+ dbus_bool_t should_probe_for_fs;
+ char *partition_scheme = NULL;
+ dbus_uint64_t partition_start = 0;
+ dbus_uint64_t partition_number = 0;
+ struct vtoc vtoc;
+ dk_gpt_t *gpt;
+ struct dk_minfo mi;
+ int i, dos_cnt;
+ fstyp_handle_t fstyp_handle;
+ int systid, relsect, numsect;
+ off_t probe_offset = 0;
+ int num_volumes;
+ char **volumes;
+ dbus_uint64_t v_start;
+ const char *fstype;
+ nvlist_t *fsattr;
+
+ fd = rfd = -1;
+
+ ret = 1;
+
+ if ((udi = getenv ("UDI")) == NULL) {
+ goto out;
+ }
+ if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL) {
+ goto out;
+ }
+ if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL) {
+ goto out;
+ }
+ if (!dos_to_dev(device_file, &rdevpath, &dos_num)) {
+ rdevpath = raw_device_file;
+ }
+ if (!(is_dos = dos_to_dev(device_file, &devpath, &dos_num))) {
+ devpath = device_file;
+ }
+ if ((parent_udi = getenv ("HAL_PROP_INFO_PARENT")) == NULL) {
+ goto out;
+ }
+ if ((storage_device = getenv ("HAL_PROP_BLOCK_STORAGE_DEVICE")) == NULL) {
+ goto out;
+ }
+
+ is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC");
+ if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) {
+ is_disc = TRUE;
+ } else {
+ is_disc = FALSE;
+ }
+
+ drop_privileges ();
+
+ setup_logger ();
+
+ dbus_error_init (&error);
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+ goto out;
+
+ HAL_DEBUG (("Doing probe-volume for %s\n", device_file));
+
+ fd = open (devpath, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ goto out;
+ }
+ rfd = open (rdevpath, O_RDONLY | O_NONBLOCK);
+ if (rfd < 0) {
+ goto out;
+ }
+
+ /* if it's a floppy with no media, bail out */
+ if (ioctl(rfd, FDGETCHANGE, &fdc) == 0) {
+ is_floppy = TRUE;
+ if (fdc & FDGC_CURRENT) {
+ goto out;
+ }
+ }
+
+ /* block size and total size */
+ if (ioctl(rfd, DKIOCGMEDIAINFO, &mi) != -1) {
+ block_size = mi.dki_lbsize;
+ vol_size = mi.dki_capacity * block_size;
+ } else {
+ block_size = 512;
+ vol_size = 0;
+ }
+ libhal_device_set_property_int (ctx, udi, "volume.block_size", block_size, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_uint64 (ctx, udi, "volume.size", vol_size, &error);
+ my_dbus_error_free (&error);
+
+ should_probe_for_fs = TRUE;
+
+ if (is_disc) {
+ if (!probe_disc (rfd, ctx, udi, &should_probe_for_fs)) {
+ HAL_DEBUG (("probe_disc failed, skipping fstyp"));
+ goto out;
+ }
+ /* XXX vol_probe_offset for multisession discs? */
+ }
+
+ if (!should_probe_for_fs) {
+ goto skip_fs;
+ }
+
+ /* don't support partitioned floppy */
+ if (is_floppy) {
+ goto skip_part;
+ }
+
+ /*
+ * first get partitioning info
+ */
+ if (is_dos) {
+ /* for a dos drive find partition offset */
+ if (!find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) {
+ goto out;
+ }
+ partition_scheme = "mbr";
+ partition_start = (dbus_uint64_t)relsect * 512;
+ partition_number = dos_num;
+ probe_offset = (off_t)relsect * 512;
+ } else {
+ if ((partition_number = read_vtoc(rfd, &vtoc)) >= 0) {
+ if (!vtoc_one_slice_entire_disk(&vtoc)) {
+ partition_scheme = "smi";
+ if (partition_number < vtoc.v_nparts) {
+ if (vtoc.v_part[partition_number].p_size == 0) {
+ HAL_DEBUG (("zero size partition"));
+ }
+ partition_start = vtoc.v_part[partition_number].p_start * block_size;
+ }
+ }
+ } else if ((partition_number = efi_alloc_and_read(rfd, &gpt)) >= 0) {
+ partition_scheme = "gpt";
+ if (partition_number < gpt->efi_nparts) {
+ if (gpt->efi_parts[partition_number].p_size == 0) {
+ HAL_DEBUG (("zero size partition"));
+ }
+ partition_start = gpt->efi_parts[partition_number].p_start * block_size;
+ }
+ efi_free(gpt);
+ }
+ probe_offset = 0;
+ }
+
+ if (partition_scheme != NULL) {
+ libhal_device_set_property_string (ctx, udi, "volume.partition.scheme", partition_scheme, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_int (ctx, udi, "volume.partition.number", partition_number, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_uint64 (ctx, udi, "volume.partition.start", partition_start, &error);
+ my_dbus_error_free (&error);
+ libhal_device_set_property_bool (ctx, udi, "volume.is_partition", TRUE, &error);
+ my_dbus_error_free (&error);
+ } else {
+ libhal_device_set_property_bool (ctx, udi, "volume.is_partition", FALSE, &error);
+ my_dbus_error_free (&error);
+ }
+
+ /*
+ * ignore duplicate partitions
+ */
+ if ((volumes = libhal_manager_find_device_string_match (
+ ctx, "block.storage_device", storage_device, &num_volumes, &error)) != NULL) {
+ my_dbus_error_free (&error);
+ for (i = 0; i < num_volumes; i++) {
+ if (strcmp (udi, volumes[i]) == 0) {
+ continue; /* skip self */
+ }
+ v_start = libhal_device_get_property_uint64 (ctx, volumes[i], "volume.partition.start", &error);
+ if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
+ continue;
+ }
+ if (v_start == partition_start) {
+ HAL_DEBUG (("duplicate partition"));
+ goto out;
+ }
+ }
+ libhal_free_string_array (volumes);
+ }
+
+skip_part:
+
+ /*
+ * now determine fs type
+ */
+ if (fstyp_init(fd, probe_offset, NULL, &fstyp_handle) != 0) {
+ HAL_DEBUG (("fstyp_init failed"));
+ goto out;
+ }
+ if ((fstyp_ident(fstyp_handle, NULL, &fstype) != 0) ||
+ (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) {
+ HAL_DEBUG (("fstyp ident or get_attr failed"));
+
+ /*
+ * XXX fstyp_udfs has a bug that it only works on raw,
+ * but we don't want to slow down the fast path above.
+ * Try raw for just udfs here until the bug is fixed.
+ */
+ HAL_DEBUG (("trying udfs workaround"));
+ fstyp_fini(fstyp_handle);
+ if (fstyp_init(rfd, probe_offset, NULL, &fstyp_handle) != 0) {
+ goto out;
+ }
+ if ((fstyp_ident(fstyp_handle, "udfs", &fstype) != 0) ||
+ (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) {
+ fstyp_fini(fstyp_handle);
+ goto out;
+ }
+ }
+ set_fstyp_properties (ctx, udi, fstype, fsattr);
+ fstyp_fini(fstyp_handle);
+
+skip_fs:
+
+ ret = 0;
+
+out:
+ if (fd >= 0)
+ close (fd);
+ if (rfd >= 0)
+ close (rfd);
+
+ if (ctx != NULL) {
+ my_dbus_error_free (&error);
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return ret;
+
+}
diff --git a/usr/src/cmd/hal/tools/Makefile b/usr/src/cmd/hal/tools/Makefile
new file mode 100644
index 0000000000..1bffd11e74
--- /dev/null
+++ b/usr/src/cmd/hal/tools/Makefile
@@ -0,0 +1,146 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+HAL_PROG = hal-device hal-find-by-capability hal-find-by-property \
+ hal-get-property hal-set-property lshal
+
+SCRIPT = hal-fdi-validate
+
+STORAGE_METHOD_PROG = hal-storage-closetray hal-storage-eject \
+ hal-storage-mount hal-storage-unmount \
+ hal-storage-zpool-export hal-storage-zpool-import
+
+STORAGE_PROG = $(STORAGE_METHOD_PROG) \
+ hal-storage-cleanup-mountpoint \
+ hal-storage-cleanup-all-mountpoints
+
+PROGSRCS = $(PROG:%=%.c) $(STORAGE_PROG:%=%.c)
+
+STORAGE_OBJS = $(STORAGE_PROG:%=%.o)
+STORAGE_SHAREDOBJS = hal-storage-shared.o
+STORAGE_SHAREDSRCS = $(STORAGE_SHAREDOBJS:%.o=%.c)
+
+SRCS = $(PROGSRCS) $(STORAGE_SHAREDSRCS)
+
+CLOBBERFILES += $(HAL_PROG) $(STORAGE_PROG) $(SCRIPT)
+CLEANFILES += $(STORAGE_SHAREDOBJS) $(STORAGE_OBJS)
+
+include ../../Makefile.cmd
+include ../Makefile.hal
+
+$(HAL_PROG) := LDLIBS += -lc -ldbus-1 -lhal
+
+lshal := LDLIBS += -ldbus-glib-1 -lglib-2.0
+
+$(STORAGE_PROG) := LDLIBS += -lc -ldbus-1 -lglib-2.0 -lhal -lhal-storage -lbsm
+
+$(STORAGE_METHOD_PROG) := LDLIBS += -lpolkit
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal
+CPPFLAGS += -I$(ROOT)/usr/include/libpolkit
+C99MODE = $(C99_ENABLE)
+
+ROOTUSRSBINPROG = $(HAL_PROG:%=$(ROOTUSRSBIN)/%) $(SCRIPT:%=$(ROOTUSRSBIN)/%)
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+ROOTCMD = $(STORAGE_PROG:%=$(ROOTCMDDIR)/%)
+
+.KEEP_STATE:
+
+all: $(HAL_PROG) $(STORAGE_PROG) $(SCRIPT)
+
+$(STORAGE_SHAREDOBJS): $(STORAGE_SHAREDSRCS)
+ $(COMPILE.c) $(STORAGE_SHAREDSRCS)
+
+hal-storage-closetray: hal-storage-closetray.o $(STORAGE_SHAREDOBJS)
+ $(LINK.c) hal-storage-closetray.o $(STORAGE_SHAREDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-eject: hal-storage-eject.o $(STORAGE_SHAREDOBJS)
+ $(LINK.c) hal-storage-eject.o $(STORAGE_SHAREDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-mount: hal-storage-mount.o $(STORAGE_SHAREDOBJS)
+ $(LINK.c) hal-storage-mount.o $(STORAGE_SHAREDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-unmount: hal-storage-unmount.o $(STORAGE_SHAREDOBJS)
+ $(LINK.c) hal-storage-unmount.o $(STORAGE_SHAREDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-cleanup-mountpoint: hal-storage-cleanup-mountpoint.c \
+ $(STORAGE_SHAREDOBJS)
+ $(LINK.c) hal-storage-cleanup-mountpoint.c \
+ $(STORAGE_SHAREDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-cleanup-all-mountpoints: hal-storage-cleanup-all-mountpoints.c \
+ $(STORAGE_SHAREDOBJS)
+ $(LINK.c) hal-storage-cleanup-all-mountpoints.c \
+ $(STORAGE_SHAREDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-zpool-export: hal-storage-zpool.c $(STORAGE_SHAREDOBJS)
+ $(LINK.c) -o $@ $(STORAGE_SHAREDOBJS) -DZPOOL_SUBCMD=\"export\" hal-storage-zpool.c $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-storage-zpool-import: hal-storage-zpool.c $(STORAGE_SHAREDOBJS)
+ $(LINK.c) -o $@ $(STORAGE_SHAREDOBJS) -DZPOOL_SUBCMD=\"import\" hal-storage-zpool.c $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-device: hal-device.c
+ $(LINK.c) -o $@ hal-device.c $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-find-by-capability: hal_find_by_capability.c
+ $(LINK.c) -o $@ hal_find_by_capability.c $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-find-by-property: hal_find_by_property.c
+ $(LINK.c) -o $@ hal_find_by_property.c $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-get-property: hal_get_property.c
+ $(LINK.c) -o $@ hal_get_property.c $(LDLIBS)
+ $(POST_PROCESS)
+
+hal-set-property: hal_set_property.c
+ $(LINK.c) -o $@ hal_set_property.c $(LDLIBS)
+ $(POST_PROCESS)
+
+lshal: lshal.c
+ $(LINK.c) -o $@ lshal.c $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTUSRSBINPROG) $(ROOTCMD)
+
+
+clean:
+ $(RM) $(CLEANFILES)
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/hal/tools/hal-device.c b/usr/src/cmd/hal/tools/hal-device.c
new file mode 100644
index 0000000000..3bbecd4d0f
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-device.c
@@ -0,0 +1,652 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal-device.c : add devices HAL
+ *
+ * Copyright (C) 2005 SuSE Linux Gmbh
+ *
+ * Authors:
+ * Steffen Winterfeldt <snwint@suse.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include <getopt.h>
+
+#ifndef DBUS_API_SUBJECT_TO_CHANGE
+#define DBUS_API_SUBJECT_TO_CHANGE 1
+#endif
+
+#include <dbus/dbus.h>
+#include <libhal.h>
+
+typedef struct {
+ char *udi;
+ char *real_udi;
+} new_dev_t;
+
+typedef struct lh_prop_s {
+ struct lh_prop_s *next;
+ LibHalPropertyType type;
+ char *key;
+ union {
+ char *str_value;
+ dbus_int32_t int_value;
+ dbus_uint64_t uint64_value;
+ double double_value;
+ dbus_bool_t bool_value;
+ char **strlist_value;
+ } v;
+} lh_prop_t;
+
+
+void help(void);
+int dump_devices(LibHalContext *hal_ctx, char *arg);
+int remove_udi(LibHalContext *hal_ctx, char *arg);
+int add_udi(LibHalContext *hal_ctx, char *arg);
+void process_property(LibHalContext *hal_ctx, char *buf, lh_prop_t **prop);
+int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop);
+lh_prop_t *free_properties(lh_prop_t *prop);
+static char *skip_space(char *s);
+static char *skip_non_eq_or_space(char *s);
+static char *skip_number(char *s);
+static char *skip_nonquote(char *s);
+
+
+new_dev_t new_dev;
+
+struct {
+ unsigned remove:1;
+ unsigned add:1;
+ unsigned list:1;
+ char *udi;
+} opt;
+
+struct option options[] = {
+ { "remove", 1, NULL, 'r' },
+ { "add", 1, NULL, 'a' },
+ { "help", 0, NULL, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+
+int main(int argc, char **argv)
+{
+ DBusError error;
+ DBusConnection *conn;
+ LibHalContext *hal_ctx;
+ int i, err;
+
+ opterr = 0;
+ opt.list = 1;
+
+ while ((i = getopt_long(argc, argv, "a:hr:", options, NULL)) != -1) {
+ switch (i) {
+ case 'a':
+ opt.add = 1;
+ opt.list = 0;
+ opt.udi = optarg;
+ break;
+ case 'r':
+ opt.remove = 1;
+ opt.list = 0;
+ opt.udi = optarg;
+ break;
+ case 'h':
+ help();
+ return 0;
+ default:
+ help();
+ return 1;
+ }
+ }
+
+ dbus_error_init(&error);
+
+ if (!(conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
+ fprintf(stderr, "error: dbus_bus_get: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 2;
+ }
+
+ /* fprintf(stderr, "connected to: %s\n", dbus_bus_get_unique_name(conn)); */
+ if (!(hal_ctx = libhal_ctx_new())) return 3;
+ if (!libhal_ctx_set_dbus_connection(hal_ctx, conn)) return 4;
+ if (!libhal_ctx_init(hal_ctx, &error)) {
+ if (dbus_error_is_set(&error)) {
+ fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ fprintf (stderr, "Could not initialise connection to hald.\n"
+ "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+ return 5;
+ }
+
+ err = 0;
+ if (opt.list)
+ err = dump_devices(hal_ctx, argv[optind]);
+ else if (opt.remove)
+ err = remove_udi(hal_ctx, opt.udi);
+ else if (opt.add)
+ err = add_udi(hal_ctx, opt.udi);
+ else
+ err = 6;
+
+ libhal_ctx_shutdown(hal_ctx, &error);
+ libhal_ctx_free(hal_ctx);
+ dbus_connection_close(conn);
+ dbus_connection_unref(conn);
+ dbus_error_free(&error);
+
+ return err;
+}
+
+
+void help()
+{
+ fprintf(stderr,
+ "usage: hal-device [--help] [--add udi] [--remove udi] [udi]\n"
+ "Create, remove, or show HAL device. If no udi is given, shows all devices.\n"
+ "If udi doesn't start with a '/', '/org/freedesktop/Hal/devices/' is prepended.\n"
+ " -a, --add udi\t\tAdd new device.\n"
+ " \t\t\tReads property list in 'lshal' syntax from stdin.\n"
+ " -r, --remove udi\tRemove device.\n"
+ " -h, --help\t\tShow this text.\n"
+ );
+}
+
+
+/*
+ * Dump all devices.
+ */
+int dump_devices(LibHalContext *hal_ctx, char *arg)
+{
+ int i;
+ int num_devices;
+ char **device_names;
+ DBusError error;
+ char *udi = NULL;
+
+ if (arg) {
+ if (*arg == '/') {
+ udi = arg;
+ } else {
+#ifdef HAVE_ASPRINTF
+ asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg);
+#else
+ udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg));
+ sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg);
+
+#endif
+ }
+ }
+
+ dbus_error_init(&error);
+
+ if (!udi) {
+ if (!(device_names = libhal_get_all_devices(hal_ctx, &num_devices, &error))) {
+ fprintf(stderr, "Empty HAL device list.\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 31;
+ }
+ } else {
+ device_names = calloc(2, sizeof *device_names);
+ device_names[0] = strdup(udi);
+ num_devices = 1;
+ }
+
+ for(i = 0; i < num_devices; i++) {
+ LibHalPropertySet *props;
+ LibHalPropertySetIterator it;
+ int type;
+
+ if (!(props = libhal_device_get_all_properties(hal_ctx, device_names[i], &error))) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ dbus_error_init(&error);
+ continue;
+ }
+
+ if (!udi)
+ printf("%d: ", i);
+ printf("udi = '%s'\n", device_names[i]);
+
+ for(libhal_psi_init(&it, props); libhal_psi_has_more(&it); libhal_psi_next(&it)) {
+ type = libhal_psi_get_type(&it);
+ switch (type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ printf(" %s = '%s' (string)\n",
+ libhal_psi_get_key(&it),
+ libhal_psi_get_string(&it)
+ );
+ break;
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ printf(" %s = %d (0x%x) (int)\n",
+ libhal_psi_get_key(&it),
+ libhal_psi_get_int(&it),
+ libhal_psi_get_int(&it)
+ );
+ break;
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ printf(" %s = %lld (0x%llx) (uint64)\n",
+ libhal_psi_get_key(&it),
+ (long long) libhal_psi_get_uint64(&it),
+ (long long) libhal_psi_get_uint64(&it)
+ );
+ break;
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ printf(" %s = %g (double)\n",
+ libhal_psi_get_key(&it),
+ libhal_psi_get_double(&it)
+ );
+ break;
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ printf(" %s = %s (bool)\n",
+ libhal_psi_get_key(&it),
+ libhal_psi_get_bool(&it) ? "true" : "false"
+ );
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ {
+ char **strlist;
+
+ printf (" %s = { ", libhal_psi_get_key(&it));
+ strlist = libhal_psi_get_strlist(&it);
+ while (*strlist) {
+ printf("'%s'%s", *strlist, strlist[1] ? ", " : "");
+ strlist++;
+ }
+ printf(" } (string list)\n");
+ }
+ break;
+ default:
+ printf("Unknown type %d = 0x%02x\n", type, type);
+ break;
+ }
+ }
+
+ libhal_free_property_set(props);
+ printf("\n");
+ }
+
+ libhal_free_string_array(device_names);
+ dbus_error_free(&error);
+
+ return 0;
+}
+
+
+int remove_udi(LibHalContext *hal_ctx, char *arg)
+{
+ DBusError error;
+ char *udi;
+
+ if (!arg) return 11;
+
+ if (*arg == '/') {
+ udi = arg;
+ } else {
+#ifdef HAVE_ASPRINTF
+ asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg);
+#else
+ udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg));
+ sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg);
+#endif
+
+ }
+
+ dbus_error_init(&error);
+
+ if (opt.remove) {
+ if (!libhal_remove_device(hal_ctx, udi, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 12;
+ }
+
+ fprintf(stderr, "removed: %s\n", udi);
+ return 13;
+ }
+
+ return 0;
+}
+
+
+int add_udi(LibHalContext *hal_ctx, char *arg)
+{
+ DBusError error;
+ dbus_bool_t dev_exists = FALSE;
+ char *udi = NULL, buf[1024];
+ lh_prop_t *prop;
+ int err;
+
+ if (!arg)
+ return 21;
+
+ if (*arg == '/') {
+ udi = arg;
+ } else {
+#ifdef HAVE_ASPRINTF
+ asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg);
+#else
+ udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg));
+ sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg);
+#endif
+ }
+
+ if (udi)
+ new_dev.udi = strdup(udi);
+
+ dbus_error_init(&error);
+
+ if (udi)
+ dev_exists = libhal_device_exists(hal_ctx, udi, &error);
+
+ if (dev_exists) {
+ new_dev.real_udi = strdup(new_dev.udi);
+ } else {
+ new_dev.real_udi = libhal_new_device(hal_ctx, &error);
+
+ if (!new_dev.real_udi) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ free(new_dev.real_udi);
+
+ return 22;
+ }
+
+ printf("tmp udi: %s\n", new_dev.real_udi);
+ }
+
+ prop = NULL;
+
+ while (fgets(buf, sizeof buf, stdin)) {
+ process_property(hal_ctx, buf, &prop);
+ }
+
+ err = add_properties(hal_ctx, &new_dev, prop);
+
+ prop = free_properties(prop);
+
+ if (!dev_exists) {
+ if (!libhal_device_commit_to_gdl(hal_ctx, new_dev.real_udi, new_dev.udi, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ free(new_dev.real_udi);
+
+ err = err ? err : 23;
+ }
+ }
+
+ printf("%s: %s\n", dev_exists ? "merged": "created", new_dev.udi);
+
+ return err;
+}
+
+
+char *skip_space(char *s)
+{
+ while (isspace(*s)) s++;
+
+ return s;
+}
+
+
+char *skip_non_eq_or_space(char *s)
+{
+ while (*s && *s != '=' && !isspace(*s))
+ s++;
+
+ return s;
+}
+
+
+char *skip_number(char *s)
+{
+ while (*s == '-' || *s == '+' || *s == '.' || isdigit(*s))
+ s++;
+
+ return s;
+}
+
+
+char *skip_nonquote(char *s)
+{
+ while (*s && *s != '\'')
+ s++;
+
+ return s;
+}
+
+
+void process_property(LibHalContext *hal_ctx, char *buf, lh_prop_t **prop)
+{
+ char *s, *s1;
+ char *key, *s_val = NULL;
+ lh_prop_t *p;
+ unsigned len;
+ int remove = 0;
+
+ s = skip_space(buf);
+
+ if (*s == '-') {
+ remove = 1;
+ s = skip_space(s + 1);
+ }
+
+ if ((s1 = skip_number(s), s1 != s) && *s1 == ':') s = skip_space(s1 + 1);
+
+ s = skip_non_eq_or_space(key = s);
+ *s++ = 0;
+ if (!*key)
+ return;
+
+ if (*key == '#')
+ return;
+
+ if (*s == '=')
+ s++;
+ s = skip_space(s);
+
+ if (!*s)
+ remove = 1;
+
+ p = calloc(1, sizeof *p);
+ p->type = LIBHAL_PROPERTY_TYPE_INVALID;
+ p->key = strdup(key);
+
+ if (remove) {
+ p->next = *prop;
+ *prop = p;
+ return;
+ }
+
+ if (*s == '\'') {
+ s_val = s + 1;
+ s = strrchr(s_val, '\'');
+ *(s ? s : s_val) = 0;
+ p->type = LIBHAL_PROPERTY_TYPE_STRING;
+ p->v.str_value = strdup(s_val);
+ } else if (*s == '{') {
+ s_val = s + 1;
+ s1 = strrchr(s_val, '}');
+ if (s1) *s1 = 0;
+ p->type = LIBHAL_PROPERTY_TYPE_STRLIST;
+ len = 0;
+ p->v.strlist_value = calloc(1, sizeof *p->v.strlist_value);
+ while (*s_val++ == '\'') {
+ s = skip_nonquote(s_val);
+ if (*s) *s++ = 0;
+ p->v.strlist_value = realloc(p->v.strlist_value, (len + 2) * sizeof *p->v.strlist_value);
+ p->v.strlist_value[len] = strdup(s_val);
+ p->v.strlist_value[++len] = NULL;
+ s_val = skip_nonquote(s);
+ }
+ } else if (!strncmp(s, "true", 4)) {
+ s += 4;
+ p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
+ p->v.bool_value = TRUE;
+ } else if (!strncmp(s, "false", 5)) {
+ s += 5;
+ p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
+ p->v.bool_value = FALSE;
+ } else if ((s1 = skip_number(s)) != s) {
+ if (strstr(s1, "(int)")) {
+ *s1++ = 0;
+ p->type = LIBHAL_PROPERTY_TYPE_INT32;
+ p->v.int_value = strtol(s, NULL, 10);
+ } else if (strstr(s1, "(uint64)")) {
+ *s1++ = 0;
+ p->type = LIBHAL_PROPERTY_TYPE_UINT64;
+ p->v.uint64_value = strtoull(s, NULL, 10);
+ } else if (strstr(s1, "(double)")) {
+ p->type = LIBHAL_PROPERTY_TYPE_DOUBLE;
+ p->v.double_value = strtod(s, NULL);
+ }
+
+ s = s1;
+ }
+
+ if (p->type == LIBHAL_PROPERTY_TYPE_INVALID) {
+ free(p->key);
+ free(p);
+ } else {
+ p->next = *prop;
+ *prop = p;
+ }
+}
+
+
+int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop)
+{
+ DBusError error;
+ lh_prop_t *p;
+ char *udi2 = NULL, *udi3 = NULL, **s;
+ LibHalPropertyType old_type;
+
+ dbus_error_init(&error);
+
+ for(p = prop; p; p = p->next) {
+ if (!strcmp(p->key, "udi") && p->type == LIBHAL_PROPERTY_TYPE_STRING) {
+ udi2 = p->v.str_value;
+ continue;
+ }
+
+ old_type = libhal_device_get_property_type(hal_ctx, nd->real_udi, p->key, &error);
+ dbus_error_init(&error);
+
+ if (old_type != LIBHAL_PROPERTY_TYPE_INVALID &&
+ ( p->type != old_type || p->type == LIBHAL_PROPERTY_TYPE_STRLIST)) {
+ if (!libhal_device_remove_property(hal_ctx, nd->real_udi, p->key, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 41;
+ }
+ }
+
+ switch (p->type) {
+ case LIBHAL_PROPERTY_TYPE_INVALID:
+ break;
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ if (!libhal_device_set_property_bool(hal_ctx, nd->real_udi, p->key, p->v.bool_value, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 42;
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ if (!libhal_device_set_property_int(hal_ctx, nd->real_udi, p->key, p->v.int_value, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 42;
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ if (!libhal_device_set_property_uint64(hal_ctx, nd->real_udi, p->key, p->v.uint64_value, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 42;
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ if (!libhal_device_set_property_double(hal_ctx, nd->real_udi, p->key, p->v.double_value, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 42;
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ if (!strcmp(p->key, "info.udi")) udi3 = p->v.str_value;
+ if (!libhal_device_set_property_string(hal_ctx, nd->real_udi, p->key, p->v.str_value, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 42;
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ for(s = p->v.strlist_value; *s; s++) {
+ if (!libhal_device_property_strlist_append(hal_ctx, nd->real_udi, p->key, *s, &error)) {
+ fprintf(stderr, "%s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 42;
+ }
+ }
+ break;
+ }
+ }
+
+ if (udi2) udi3 = NULL;
+ if (udi3) udi2 = udi3;
+
+ if (udi2 && !nd->udi)
+ nd->udi = strdup(udi2);
+
+ return 0;
+}
+
+
+lh_prop_t *free_properties(lh_prop_t *prop)
+{
+ lh_prop_t *next;
+ char **s;
+
+ for(; prop; prop = next) {
+ next = prop->next;
+
+ free(prop->key);
+ if (prop->type == LIBHAL_PROPERTY_TYPE_STRING) free(prop->v.str_value);
+ if (prop->type == LIBHAL_PROPERTY_TYPE_STRLIST && prop->v.strlist_value) {
+ for(s = prop->v.strlist_value; *s; ) free(*s++);
+ free(prop->v.strlist_value);
+ }
+ free(prop);
+ }
+
+ return NULL;
+}
diff --git a/usr/src/cmd/hal/tools/hal-fdi-validate.sh b/usr/src/cmd/hal/tools/hal-fdi-validate.sh
new file mode 100644
index 0000000000..280c30bf34
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-fdi-validate.sh
@@ -0,0 +1,32 @@
+#
+# hal-fdi-validate.sh : Validate one or more fdi(4) files
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Licensed under the Academic Free License version 2.1
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+usage() {
+ echo "Usage: hal-fdi-validate [-f dtd] file [file ...]"
+ exit 1
+}
+
+if [ "$1" = "-f" ]; then
+ if [ "foo$2" != "foo" ] ; then
+ DTD="$2"
+ shift 2
+ else
+ usage
+ fi
+else
+ DTD="/usr/share/lib/xml/dtd/fdi.dtd.1"
+fi
+
+if [ $# -eq 0 ]; then
+ usage
+fi
+
+xmllint --noout --dtdvalid $DTD $*
diff --git a/usr/src/cmd/hal/tools/hal-storage-cleanup-all-mountpoints.c b/usr/src/cmd/hal/tools/hal-storage-cleanup-all-mountpoints.c
new file mode 100644
index 0000000000..aa8d657481
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-cleanup-all-mountpoints.c
@@ -0,0 +1,180 @@
+/***************************************************************************
+ * CVSID: $Id: hal-storage-mount.c,v 1.7 2006/06/21 00:44:03 david Exp $
+ *
+ * hal-storage-cleanup-all-mountpoints.c : Cleanup all mount points in
+ * /media/.hal-mtab that is currently unused
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "hal-storage-shared.h"
+
+/*#define DEBUG*/
+#define DEBUG
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+static void
+do_cleanup (void)
+{
+ int i, j;
+ FILE *hal_mtab_orig;
+ int hal_mtab_orig_len;
+ int num_read;
+ char *hal_mtab_buf;
+ char **lines;
+ FILE *hal_mtab_new;
+
+ hal_mtab_orig = fopen ("/media/.hal-mtab", "r");
+ if (hal_mtab_orig == NULL) {
+ unknown_error ("Cannot open /media/.hal-mtab");
+ }
+ if (fseek (hal_mtab_orig, 0L, SEEK_END) != 0) {
+ unknown_error ("Cannot seek to end of /media/.hal-mtab");
+ }
+ hal_mtab_orig_len = ftell (hal_mtab_orig);
+ if (hal_mtab_orig_len < 0) {
+ unknown_error ("Cannot determine size of /media/.hal-mtab");
+ }
+ rewind (hal_mtab_orig);
+ hal_mtab_buf = g_new0 (char, hal_mtab_orig_len + 1);
+ num_read = fread (hal_mtab_buf, 1, hal_mtab_orig_len, hal_mtab_orig);
+ if (num_read != hal_mtab_orig_len) {
+ unknown_error ("Cannot read from /media/.hal-mtab");
+ }
+ fclose (hal_mtab_orig);
+
+#ifdef DEBUG
+ printf ("hal_mtab = '%s'\n", hal_mtab_buf);
+#endif
+
+ lines = g_strsplit (hal_mtab_buf, "\n", 0);
+ g_free (hal_mtab_buf);
+
+ /* find the entry we're going to unmount */
+ for (i = 0; lines[i] != NULL; i++) {
+ char **line_elements;
+
+#ifdef DEBUG
+ printf (" line = '%s'\n", lines[i]);
+#endif
+
+ if ((lines[i])[0] == '#')
+ continue;
+
+ line_elements = g_strsplit (lines[i], "\t", 6);
+ if (g_strv_length (line_elements) == 6) {
+ char *mount_point;
+
+#ifdef DEBUG
+ printf (" devfile = '%s'\n", line_elements[0]);
+ printf (" uid = '%s'\n", line_elements[1]);
+ printf (" session id = '%s'\n", line_elements[2]);
+ printf (" fs = '%s'\n", line_elements[3]);
+ printf (" options = '%s'\n", line_elements[4]);
+ printf (" mount_point = '%s'\n", line_elements[5]);
+#endif
+
+ /* just try to rmdir the entry; if it's non-empty or something is mounted on it,
+ * this will fail
+ */
+ mount_point = line_elements[5];
+
+ /* remove directory */
+ if (g_rmdir (mount_point) == 0) {
+ char *line_to_free;
+
+ printf ("Removed mount_point '%s'", mount_point);
+
+ line_to_free = lines[i];
+ for (j = i; lines[j] != NULL; j++) {
+ lines[j] = lines[j+1];
+ }
+ lines[j] = NULL;
+ g_free (line_to_free);
+
+ /* we've moved the lines one back, so make sure we don't advance to next line */
+ i--;
+ }
+ }
+
+ g_strfreev (line_elements);
+ }
+
+ /* create new .hal-mtab~ file without the entries we've removed */
+ hal_mtab_new = fopen ("/media/.hal-mtab~", "w");
+ if (hal_mtab_new == NULL) {
+ unknown_error ("Cannot create /media/.hal-mtab~");
+ }
+ for (i = 0; lines[i] != NULL; i++) {
+ if (strlen (lines[i]) > 0) {
+ char anewl[2] = "\n\0";
+ if (fwrite (lines[i], 1, strlen (lines[i]), hal_mtab_new) != strlen (lines[i])) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+ if (fwrite (anewl, 1, 1, hal_mtab_new) != 1) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+ }
+ }
+ fclose (hal_mtab_new);
+
+ g_strfreev (lines);
+
+ /* set new .hal-mtab file */
+ if (rename ("/media/.hal-mtab~", "/media/.hal-mtab") != 0) {
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot rename /media/.hal-mtab~ to /media/.hal-mtab");
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (!lock_hal_mtab ()) {
+ unknown_error ("Cannot obtain lock on /media/.hal-mtab");
+ }
+
+ if (getenv ("HAL_PROP_INFO_UDI") == NULL)
+ usage ();
+
+#ifdef DEBUG
+ printf ("in hal-storage-cleanup-all-mountpoints\n");
+#endif
+ do_cleanup ();
+
+
+ unlock_hal_mtab ();
+ return 0;
+}
diff --git a/usr/src/cmd/hal/tools/hal-storage-cleanup-mountpoint.c b/usr/src/cmd/hal/tools/hal-storage-cleanup-mountpoint.c
new file mode 100644
index 0000000000..f4973a82db
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-cleanup-mountpoint.c
@@ -0,0 +1,192 @@
+/***************************************************************************
+ * CVSID: $Id: hal-storage-mount.c,v 1.7 2006/06/21 00:44:03 david Exp $
+ *
+ * hal-storage-cleanup-mountpoint.c : Cleanup mount point when hald detects
+ * that an unmount not done through Unmount()
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "hal-storage-shared.h"
+
+/*#define DEBUG*/
+#define DEBUG
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+static void
+do_cleanup (const char *mount_point)
+{
+ int i, j;
+ FILE *hal_mtab_orig;
+ int hal_mtab_orig_len;
+ int num_read;
+ char *hal_mtab_buf;
+ char **lines;
+ FILE *hal_mtab_new;
+ gboolean found;
+
+ hal_mtab_orig = fopen ("/media/.hal-mtab", "r");
+ if (hal_mtab_orig == NULL) {
+ unknown_error ("Cannot open /media/.hal-mtab");
+ }
+ if (fseek (hal_mtab_orig, 0L, SEEK_END) != 0) {
+ unknown_error ("Cannot seek to end of /media/.hal-mtab");
+ }
+ hal_mtab_orig_len = ftell (hal_mtab_orig);
+ if (hal_mtab_orig_len < 0) {
+ unknown_error ("Cannot determine size of /media/.hal-mtab");
+ }
+ rewind (hal_mtab_orig);
+ hal_mtab_buf = g_new0 (char, hal_mtab_orig_len + 1);
+ num_read = fread (hal_mtab_buf, 1, hal_mtab_orig_len, hal_mtab_orig);
+ if (num_read != hal_mtab_orig_len) {
+ unknown_error ("Cannot read from /media/.hal-mtab");
+ }
+ fclose (hal_mtab_orig);
+
+#ifdef DEBUG
+ printf ("hal_mtab = '%s'\n", hal_mtab_buf);
+#endif
+
+ lines = g_strsplit (hal_mtab_buf, "\n", 0);
+ g_free (hal_mtab_buf);
+
+ /* find the entry we're going to unmount */
+ found = FALSE;
+ for (i = 0; lines[i] != NULL && !found; i++) {
+ char **line_elements;
+
+#ifdef DEBUG
+ printf (" line = '%s'\n", lines[i]);
+#endif
+
+ if ((lines[i])[0] == '#')
+ continue;
+
+ line_elements = g_strsplit (lines[i], "\t", 6);
+ if (g_strv_length (line_elements) == 6) {
+
+#ifdef DEBUG
+ printf (" devfile = '%s'\n", line_elements[0]);
+ printf (" uid = '%s'\n", line_elements[1]);
+ printf (" session id = '%s'\n", line_elements[2]);
+ printf (" fs = '%s'\n", line_elements[3]);
+ printf (" options = '%s'\n", line_elements[4]);
+ printf (" mount_point = '%s'\n", line_elements[5]);
+#endif
+
+ if (strcmp (line_elements[5], mount_point) == 0) {
+ char *line_to_free;
+
+ found = TRUE;
+
+ line_to_free = lines[i];
+ for (j = i; lines[j] != NULL; j++) {
+ lines[j] = lines[j+1];
+ }
+ lines[j] = NULL;
+ g_free (line_to_free);
+ }
+ }
+
+ g_strfreev (line_elements);
+ }
+
+ if (!found) {
+ unknown_error ("mount point is not /media/.hal-mtab");
+ }
+
+#ifdef DEBUG
+ printf ("Found entry for mount point '%s' in /media/.hal-mtab", mount_point);
+#endif
+
+ /* create new .hal-mtab~ file without the entry we're going to unmount */
+ hal_mtab_new = fopen ("/media/.hal-mtab~", "w");
+ if (hal_mtab_new == NULL) {
+ unknown_error ("Cannot create /media/.hal-mtab~");
+ }
+ for (i = 0; lines[i] != NULL; i++) {
+ if (i > 0) {
+ char anewl[2] = "\n\0";
+ if (fwrite (anewl, 1, 1, hal_mtab_new) != 1) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+ }
+
+ if (fwrite (lines[i], 1, strlen (lines[i]), hal_mtab_new) != strlen (lines[i])) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+
+ }
+ fclose (hal_mtab_new);
+
+ g_strfreev (lines);
+
+ /* remove directory */
+ if (g_rmdir (mount_point) != 0) {
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot remove directory");
+ }
+
+ /* set new .hal-mtab file */
+ if (rename ("/media/.hal-mtab~", "/media/.hal-mtab") != 0) {
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot rename /media/.hal-mtab~ to /media/.hal-mtab");
+ }
+
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *mount_point;
+
+ if (!lock_hal_mtab ()) {
+ unknown_error ("Cannot obtain lock on /media/.hal-mtab");
+ }
+
+ mount_point = getenv ("HALD_CLEANUP");
+ if (mount_point == NULL)
+ usage ();
+
+#ifdef DEBUG
+ printf ("in hal-storage-cleanup-mountpoint for mount point '%s'\n", mount_point);
+#endif
+ do_cleanup (mount_point);
+
+
+ unlock_hal_mtab ();
+ return 0;
+}
diff --git a/usr/src/cmd/hal/tools/hal-storage-closetray.c b/usr/src/cmd/hal/tools/hal-storage-closetray.c
new file mode 100644
index 0000000000..9dbfd05e4f
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-closetray.c
@@ -0,0 +1,178 @@
+/***************************************************************************
+ *
+ * hal-storage-closetray.c : CloseTray method handler
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2006 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+
+#include "hal-storage-shared.h"
+
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+
+void static
+unknown_closetray_error (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Storage.UnknownFailure\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+
+static void
+invalid_closetray_option (const char *option, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Storage.InvalidCloseTrayOption\n");
+ fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ exit (1);
+}
+
+#ifdef __FreeBSD__
+#error Need FreeBSD specific changes here
+#endif
+
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device;
+ LibHalDrive *drive;
+ DBusError error;
+ LibHalContext *hal_ctx = NULL;
+ DBusConnection *system_bus = NULL;
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx = NULL;
+#endif
+ char *invoked_by_uid;
+ char *invoked_by_syscon_name;
+ int i;
+ char closetray_options[1024];
+ char **given_options;
+ const char *end;
+
+ device = getenv ("HAL_PROP_BLOCK_DEVICE");
+ if (device == NULL)
+ usage ();
+
+ udi = getenv ("HAL_PROP_INFO_UDI");
+ if (udi == NULL)
+ usage ();
+
+ invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
+
+ invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ printf ("Cannot connect to hald\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+
+ dbus_error_init (&error);
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (system_bus == NULL) {
+ printf ("Cannot connect to the system bus\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+#ifdef HAVE_POLKIT
+ pol_ctx = libpolkit_new_context (system_bus);
+ if (pol_ctx == NULL) {
+ printf ("Cannot get libpolkit context\n");
+ unknown_closetray_error ("Cannot get libpolkit context");
+ }
+#endif
+
+ /* read from stdin */
+ if (strlen (fgets (closetray_options, sizeof (closetray_options), stdin)) > 0)
+ closetray_options [strlen (closetray_options) - 1] = '\0';
+ /* validate that input from stdin is UTF-8 */
+ if (!g_utf8_validate (closetray_options, -1, &end))
+ unknown_closetray_error ("Error validating closetray_options as UTF-8");
+#ifdef DEBUG
+ printf ("closetray_options = '%s'\n", closetray_options);
+#endif
+
+ /* delete any trailing whitespace options from splitting the string */
+ given_options = g_strsplit (closetray_options, "\t", 0);
+ for (i = g_strv_length (given_options) - 1; i >= 0; --i) {
+ if (strlen (given_options[i]) > 0)
+ break;
+ given_options[i] = NULL;
+ }
+
+ /* check options */
+ for (i = 0; given_options[i] != NULL; i++) {
+ char *given = given_options[i];
+
+ /* none supported right now */
+
+ invalid_closetray_option (given, invoked_by_uid);
+ }
+ g_strfreev (given_options);
+
+ /* should be storage */
+ if ((drive = libhal_drive_from_udi (hal_ctx, udi)) == NULL) {
+ unknown_closetray_error ("Cannot get drive");
+ }
+
+ /* use handle_eject() with the closetray option */
+ handle_eject (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ libhal_drive_get_udi (drive),
+ drive,
+ libhal_drive_get_device_file (drive),
+ invoked_by_uid,
+ invoked_by_syscon_name,
+ TRUE /* closetray option */,
+ system_bus);
+
+ return 0;
+}
+
+
diff --git a/usr/src/cmd/hal/tools/hal-storage-eject.c b/usr/src/cmd/hal/tools/hal-storage-eject.c
new file mode 100644
index 0000000000..afc1252b96
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-eject.c
@@ -0,0 +1,236 @@
+/***************************************************************************
+ *
+ * hal-storage-eject.c : Eject method handler
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+
+#include "hal-storage-shared.h"
+
+/* possible values: "Volume", "Storage" */
+static char *devtype = "Volume";
+
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+
+void static
+unknown_eject_error (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.%s.UnknownFailure\n", devtype);
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+
+static void
+invalid_eject_option (const char *option, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.InvalidEjectOption\n");
+ fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ exit (1);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device;
+ const char *drive_udi;
+ LibHalDrive *drive;
+ LibHalVolume *volume;
+ DBusError error;
+ LibHalContext *hal_ctx = NULL;
+ DBusConnection *system_bus = NULL;
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx = NULL;
+#endif
+ char *invoked_by_uid;
+ char *invoked_by_syscon_name;
+ char **volume_udis;
+ int num_volumes;
+ int i;
+ char eject_options[1024];
+ char **given_options;
+ const char *end;
+
+ device = getenv ("HAL_PROP_BLOCK_DEVICE");
+ if (device == NULL)
+ usage ();
+
+ udi = getenv ("HAL_PROP_INFO_UDI");
+ if (udi == NULL)
+ usage ();
+
+ invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
+
+ invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ printf ("Cannot connect to hald\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+
+ dbus_error_init (&error);
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (system_bus == NULL) {
+ printf ("Cannot connect to the system bus\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+#ifdef HAVE_POLKIT
+ pol_ctx = libpolkit_new_context (system_bus);
+ if (pol_ctx == NULL) {
+ printf ("Cannot get libpolkit context\n");
+ unknown_eject_error ("Cannot get libpolkit context");
+ }
+#endif
+
+ /* read from stdin */
+ if (strlen (fgets (eject_options, sizeof (eject_options), stdin)) > 0)
+ eject_options [strlen (eject_options) - 1] = '\0';
+ /* validate that input from stdin is UTF-8 */
+ if (!g_utf8_validate (eject_options, -1, &end))
+ unknown_eject_error ("Error validating eject_options as UTF-8");
+#ifdef DEBUG
+ printf ("eject_options = '%s'\n", eject_options);
+#endif
+
+ /* delete any trailing whitespace options from splitting the string */
+ given_options = g_strsplit (eject_options, "\t", 0);
+ for (i = g_strv_length (given_options) - 1; i >= 0; --i) {
+ if (strlen (given_options[i]) > 0)
+ break;
+ given_options[i] = NULL;
+ }
+
+ /* check eject options */
+ for (i = 0; given_options[i] != NULL; i++) {
+ char *given = given_options[i];
+
+ /* none supported right now */
+
+ invalid_eject_option (given, invoked_by_uid);
+ }
+ g_strfreev (given_options);
+
+ /* should be either volume or storage */
+ if ((volume = libhal_volume_from_udi (hal_ctx, udi)) != NULL) {
+ drive_udi = libhal_volume_get_storage_device_udi (volume);
+ } else {
+ drive_udi = g_strdup (udi);
+ devtype = "Storage";
+ }
+ if (drive_udi == NULL) {
+ unknown_eject_error ("Cannot get drive udi");
+ }
+ if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
+ unknown_eject_error ("Cannot get drive from udi");
+ }
+
+ /* first, unmount all volumes */
+ volume_udis = libhal_drive_find_all_volumes (hal_ctx, drive, &num_volumes);
+ if (volume_udis == NULL)
+ unknown_eject_error ("Cannot get all enclosed volumes");
+ for (i = 0; i < num_volumes; i++) {
+ char *volume_udi;
+ LibHalVolume *volume_to_unmount;
+
+ volume_udi = volume_udis[i];
+
+#ifdef DEBUG
+ printf ("processing drive's volume %s (%d of %d)\n", volume_udi, i + 1, num_volumes);
+#endif
+ volume_to_unmount = libhal_volume_from_udi (hal_ctx, volume_udi);
+ if (volume_to_unmount == NULL) {
+ unknown_eject_error ("Cannot get volume object");
+ }
+
+ if (libhal_volume_is_mounted (volume_to_unmount)) {
+#ifdef DEBUG
+ printf (" unmounting\n");
+#endif
+ /* only lock around unmount call because hald's /proc/mounts handler
+ * will also want to lock the /media/.hal-mtab-lock file for peeking
+ */
+ if (!lock_hal_mtab ()) {
+ unknown_eject_error ("Cannot obtain lock on /media/.hal-mtab");
+ }
+ handle_unmount (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ volume_udi, volume_to_unmount, drive,
+ libhal_volume_get_device_file (volume_to_unmount),
+ invoked_by_uid, invoked_by_syscon_name,
+ FALSE, FALSE, system_bus); /* use neither lazy nor force */
+ unlock_hal_mtab ();
+ } else {
+#ifdef DEBUG
+ printf (" not mounted\n");
+#endif
+ }
+
+ libhal_volume_free (volume_to_unmount);
+
+ }
+ libhal_free_string_array (volume_udis);
+
+ /* now attempt the eject */
+ handle_eject (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ libhal_drive_get_udi (drive),
+ drive,
+ libhal_drive_get_device_file (drive),
+ invoked_by_uid,
+ invoked_by_syscon_name,
+ FALSE, system_bus);
+
+ return 0;
+}
+
+
diff --git a/usr/src/cmd/hal/tools/hal-storage-mount.c b/usr/src/cmd/hal/tools/hal-storage-mount.c
new file mode 100644
index 0000000000..be3c6b7b7f
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-mount.c
@@ -0,0 +1,1156 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal-storage-mount.c : Mount wrapper
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#ifdef __FreeBSD__
+#include <fstab.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <pwd.h>
+#elif sun
+#include <sys/mnttab.h>
+#include <sys/vfstab.h>
+#include <sys/wait.h>
+#else
+#include <mntent.h>
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+
+#include "hal-storage-shared.h"
+
+#ifdef __FreeBSD__
+#define MOUNT "/sbin/mount"
+#define MOUNT_OPTIONS "noexec,nosuid"
+#define MOUNT_TYPE_OPT "-t"
+#elif sun
+#define MOUNT "/sbin/mount"
+#define MOUNT_OPTIONS "noexec,nosuid"
+#define MOUNT_TYPE_OPT "-F"
+#else
+#define MOUNT "/bin/mount"
+#define MOUNT_OPTIONS "noexec,nosuid,nodev"
+#define MOUNT_TYPE_OPT "-t"
+#endif
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+static void
+permission_denied_volume_ignore (const char *device)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.PermissionDenied\n");
+ fprintf (stderr, "Device has %s volume.ignore set to TRUE. Refusing to mount.\n", device);
+ exit (1);
+}
+
+static void
+permission_denied_etc_fstab (const char *device)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.PermissionDenied\n");
+ fprintf (stderr, "Device %s is listed in /etc/fstab. Refusing to mount.\n", device);
+ exit (1);
+}
+
+static void
+already_mounted (const char *device)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.AlreadyMounted\n");
+ fprintf (stderr, "Device %s is already mounted.\n", device);
+ exit (1);
+}
+
+static void
+invalid_mount_option (const char *option, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.InvalidMountOption\n");
+ fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ exit (1);
+}
+
+static void
+unknown_filesystem (const char *filesystem)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFilesystemType\n");
+ fprintf (stderr, "Unknown file system '%s'\n", filesystem);
+ exit (1);
+}
+
+static void
+invalid_mount_point (const char *mount_point)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.InvalidMountpoint\n");
+ fprintf (stderr, "The mount point '%s' is invalid\n", mount_point);
+ exit (1);
+}
+
+static void
+mount_point_not_available (const char *mount_point)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.MountPointNotAvailable\n");
+ fprintf (stderr, "The mount point '%s' is already occupied\n", mount_point);
+ exit (1);
+}
+
+
+static void
+cannot_remount (const char *device)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.CannotRemount\n");
+ fprintf (stderr, "%s not mounted already\n", device);
+ exit (1);
+}
+
+#ifdef HAVE_POLKIT
+static void
+permission_denied_privilege (const char *privilege, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n");
+ fprintf (stderr, "%s refused uid %s\n", privilege, uid);
+ exit (1);
+}
+#endif
+
+
+/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
+static void
+canonicalize_filename (gchar *filename)
+{
+ gchar *p, *q;
+ gboolean last_was_slash = FALSE;
+
+ p = filename;
+ q = filename;
+
+ while (*p)
+ {
+ if (*p == G_DIR_SEPARATOR)
+ {
+ if (!last_was_slash)
+ *q++ = G_DIR_SEPARATOR;
+
+ last_was_slash = TRUE;
+ }
+ else
+ {
+ if (last_was_slash && *p == '.')
+ {
+ if (*(p + 1) == G_DIR_SEPARATOR ||
+ *(p + 1) == '\0')
+ {
+ if (*(p + 1) == '\0')
+ break;
+
+ p += 1;
+ }
+ else if (*(p + 1) == '.' &&
+ (*(p + 2) == G_DIR_SEPARATOR ||
+ *(p + 2) == '\0'))
+ {
+ if (q > filename + 1)
+ {
+ q--;
+ while (q > filename + 1 &&
+ *(q - 1) != G_DIR_SEPARATOR)
+ q--;
+ }
+
+ if (*(p + 2) == '\0')
+ break;
+
+ p += 2;
+ }
+ else
+ {
+ *q++ = *p;
+ last_was_slash = FALSE;
+ }
+ }
+ else
+ {
+ *q++ = *p;
+ last_was_slash = FALSE;
+ }
+ }
+
+ p++;
+ }
+
+ if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
+ q--;
+
+ *q = '\0';
+}
+
+static char *
+resolve_symlink (const char *file)
+{
+ GError *error;
+ char *dir;
+ char *link;
+ char *f;
+ char *f1;
+
+ f = g_strdup (file);
+
+ while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) {
+ link = g_file_read_link (f, &error);
+ if (link == NULL) {
+ g_warning ("Cannot resolve symlink %s: %s", f, error->message);
+ g_error_free (error);
+ g_free (f);
+ f = NULL;
+ goto out;
+ }
+
+ dir = g_path_get_dirname (f);
+ f1 = g_strdup_printf ("%s/%s", dir, link);
+ g_free (dir);
+ g_free (link);
+ g_free (f);
+ f = f1;
+ }
+
+out:
+ if (f != NULL)
+ canonicalize_filename (f);
+ return f;
+}
+
+static LibHalVolume *
+volume_findby (LibHalContext *hal_ctx, const char *property, const char *value)
+{
+ int i;
+ char **hal_udis;
+ int num_hal_udis;
+ LibHalVolume *result = NULL;
+ char *found_udi = NULL;
+ DBusError error;
+
+ dbus_error_init (&error);
+ if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, property,
+ value, &num_hal_udis, &error)) == NULL) {
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ goto out;
+ }
+ for (i = 0; i < num_hal_udis; i++) {
+ char *udi;
+ udi = hal_udis[i];
+ if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) {
+ found_udi = strdup (udi);
+ break;
+ }
+ }
+
+ libhal_free_string_array (hal_udis);
+
+ if (found_udi != NULL)
+ result = libhal_volume_from_udi (hal_ctx, found_udi);
+
+ free (found_udi);
+out:
+ return result;
+}
+
+static void
+bailout_if_in_fstab (LibHalContext *hal_ctx, const char *device, const char *label, const char *uuid)
+{
+ gpointer handle;
+ char *entry;
+ char *_mount_point;
+
+ printf (" label '%s' uuid '%s'\n", label ? label : "" , uuid ? uuid : "");
+
+ /* check if /etc/fstab mentions this device... (with symlinks etc) */
+ if (! fstab_open (&handle)) {
+ printf ("cannot open /etc/fstab\n");
+ unknown_error ("Cannot open /etc/fstab");
+ }
+ while ((entry = fstab_next (handle, &_mount_point)) != NULL) {
+ char *resolved;
+
+#ifdef DEBUG
+ printf ("Looking at /etc/fstab entry '%s'\n", entry);
+#endif
+ if (label != NULL && g_str_has_prefix (entry, "LABEL=")) {
+ if (strcmp (entry + 6, label) == 0) {
+ gboolean skip_fstab_entry;
+
+ skip_fstab_entry = FALSE;
+
+ /* (heck, we also do the stuff below in gnome-mount) */
+
+ /* OK, so what's if someone attaches an external disk with the label '/' and
+ * /etc/fstab has
+ *
+ * LABEL=/ / ext3 defaults 1 1
+ *
+ * in /etc/fstab as most Red Hat systems do? Bugger, this is a very common use
+ * case; suppose that you take the disk from your Fedora server and attaches it
+ * to your laptop. Bingo, you now have two disks with the label '/'. One must
+ * seriously wonder if using things like LABEL=/ for / is a good idea; just
+ * what happens if you boot in this configuration? (answer: the initrd gets
+ * it wrong most of the time.. sigh)
+ *
+ * To work around this, check if the listed entry in /etc/fstab is already mounted,
+ * if it is, then check if it's the same device_file as the given one...
+ */
+
+ /* see if a volume is mounted at this mount point */
+ if (_mount_point != NULL) {
+ LibHalVolume *mounted_vol;
+
+ mounted_vol = volume_findby (hal_ctx, "volume.mount_point", _mount_point);
+ if (mounted_vol != NULL) {
+ const char *mounted_vol_device_file;
+
+ mounted_vol_device_file = libhal_volume_get_device_file (mounted_vol);
+ /* no need to resolve symlinks, hal uses the canonical device file */
+ if (mounted_vol_device_file != NULL &&
+ strcmp (mounted_vol_device_file, device) !=0) {
+#ifdef DEBUG
+ printf ("Wanting to mount %s that has label %s, but /etc/fstab says LABEL=%s is to be mounted at mount point '%s'. However %s (that also has label %s), is already mounted at said mount point. So, skipping said /etc/fstab entry.\n",
+ device, label, label, _mount_point, mounted_vol_device_file, _mount_point);
+#endif
+ skip_fstab_entry = TRUE;
+ }
+ libhal_volume_free (mounted_vol);
+ }
+ }
+
+ if (!skip_fstab_entry) {
+ printf ("%s found in /etc/fstab. Not mounting.\n", entry);
+ permission_denied_etc_fstab (device);
+ }
+ }
+ } else if (uuid != NULL && g_str_has_prefix (entry, "UUID=")) {
+ if (strcmp (entry + 5, uuid) == 0) {
+ printf ("%s found in /etc/fstab. Not mounting.\n", entry);
+ permission_denied_etc_fstab (device);
+ }
+ } else {
+
+ resolved = resolve_symlink (entry);
+#ifdef DEBUG
+ printf ("/etc/fstab: device %s -> %s \n", entry, resolved);
+#endif
+ if (strcmp (device, resolved) == 0) {
+ printf ("%s (-> %s) found in /etc/fstab. Not mounting.\n", entry, resolved);
+ permission_denied_etc_fstab (device);
+ }
+
+ g_free (resolved);
+ }
+ }
+ fstab_close (handle);
+}
+
+static gboolean
+device_is_mounted (const char *device, char **mount_point)
+{
+ gpointer handle;
+ char *entry;
+ gboolean ret;
+
+ ret = FALSE;
+
+ /* check if /proc/mounts mentions this device... (with symlinks etc) */
+ if (! mtab_open (&handle)) {
+ printf ("cannot open mount list\n");
+ unknown_error ("Cannot open /etc/mtab or equivalent");
+ }
+ while (((entry = mtab_next (handle, mount_point)) != NULL) && (ret == FALSE)) {
+ char *resolved;
+
+ resolved = resolve_symlink (entry);
+#ifdef DEBUG
+ printf ("/proc/mounts: device %s -> %s \n", entry, resolved);
+#endif
+ if (strcmp (device, resolved) == 0) {
+ printf ("%s (-> %s) found in mount list. Not mounting.\n", entry, resolved);
+ ret = TRUE;
+ }
+
+ g_free (resolved);
+ }
+ mtab_close (handle);
+ return ret;
+}
+
+/* maps volume_id fs types to the appropriate -t mount option */
+static const char *
+map_fstype (const char *fstype)
+{
+#ifdef __FreeBSD__
+ if (! strcmp (fstype, "iso9660"))
+ return "cd9660";
+ else if (! strcmp (fstype, "ext2"))
+ return "ext2fs";
+ else if (! strcmp (fstype, "vfat"))
+ return "msdosfs";
+#elif sun
+ if (! strcmp (fstype, "iso9660"))
+ return "hsfs";
+ else if (! strcmp (fstype, "vfat"))
+ return "pcfs";
+#endif
+
+ return fstype;
+}
+
+static void
+handle_mount (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalVolume *volume, LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ DBusConnection *system_bus)
+{
+ int i, j;
+ DBusError error;
+ char mount_point[256];
+ char mount_fstype[256];
+ char mount_options[1024];
+ char **allowed_options;
+ char **given_options;
+ gboolean wants_to_change_uid;
+ char *mount_dir;
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[10];
+ int na;
+ GString *mount_option_str;
+ gboolean pol_is_fixed;
+ gboolean pol_change_uid;
+ char *privilege;
+ gboolean is_remount;
+#ifdef HAVE_POLKIT
+ gboolean allowed_by_privilege;
+ gboolean is_temporary_privilege;
+#endif
+ gboolean explicit_mount_point_given;
+ const char *end;
+#ifdef __FreeBSD__
+ struct passwd *pw;
+ uid_t calling_uid;
+ gid_t calling_gid;
+#endif
+ const char *label;
+ const char *uuid;
+ const char *model;
+ const char *drive_type;
+#ifdef sun
+ adt_export_data_t *adt_data;
+ size_t adt_data_size;
+ gboolean append_ro = FALSE;
+ gboolean is_abs_path = FALSE;
+ uid_t calling_uid;
+
+ calling_uid = atol (invoked_by_uid);
+#endif
+
+#ifdef DEBUG
+ printf ("device = %s\n", device);
+ printf ("invoked by uid = %s\n", invoked_by_uid);
+ printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
+#endif
+
+ if (volume != NULL) {
+ dbus_error_init (&error);
+ if (libhal_device_get_property_bool (hal_ctx, udi, "volume.ignore", &error) ||
+ dbus_error_is_set (&error)) {
+ if (dbus_error_is_set (&error)) {
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ /*
+ * When device allocation is enabled (bsmconv or TX), we
+ * set volume.ignore on all volumes, but still want
+ * Mount() to succeed when called from the euid=0
+ * device allocation program.
+ */
+ if (atol (invoked_by_uid) != 0) {
+ permission_denied_volume_ignore (device);
+ }
+ }
+
+ label = libhal_volume_get_label (volume);
+ uuid = libhal_volume_get_uuid (volume);
+ } else {
+ label = NULL;
+ uuid = NULL;
+ }
+
+ bailout_if_in_fstab (hal_ctx, device, label, uuid);
+
+ /* TODO: sanity check that what hal exports is correct (cf. Martin Pitt's email) */
+
+ /* read from stdin */
+ if (strlen (fgets (mount_point, sizeof (mount_point), stdin)) > 0)
+ mount_point [strlen (mount_point) - 1] = '\0';
+ if (strlen (fgets (mount_fstype, sizeof (mount_fstype), stdin)) > 0)
+ mount_fstype [strlen (mount_fstype) - 1] = '\0';
+ if (strlen (fgets (mount_options, sizeof (mount_options), stdin)) > 0)
+ mount_options [strlen (mount_options) - 1] = '\0';
+ /* validate that input from stdin is UTF-8 */
+ if (!g_utf8_validate (mount_point, -1, &end))
+ unknown_error ("Error validating mount_point as UTF-8");
+ if (!g_utf8_validate (mount_fstype, -1, &end))
+ unknown_error ("Error validating mount_fstype as UTF-8");
+ if (!g_utf8_validate (mount_options, -1, &end))
+ unknown_error ("Error validating mount_options as UTF-8");
+
+#ifdef sun
+ if (calling_uid != 0) {
+#endif
+ for (i = 0; mount_point[i] != '\0'; i++) {
+ if (mount_point[i] == '\n' ||
+ mount_point[i] == G_DIR_SEPARATOR) {
+ unknown_error ("mount_point cannot contain the following characters: newline, G_DIR_SEPARATOR (usually /)");
+ }
+ }
+#ifdef sun
+ }
+ is_abs_path = (mount_point[0] == G_DIR_SEPARATOR);
+#endif
+
+#ifdef DEBUG
+ printf ("mount_point = '%s'\n", mount_point);
+ printf ("mount_fstype = '%s'\n", mount_fstype);
+ printf ("mount_options = '%s'\n", mount_options);
+#endif
+
+ /* delete any trailing whitespace options from splitting the string */
+ given_options = g_strsplit (mount_options, "\t", 0);
+ for (i = g_strv_length (given_options) - 1; i >= 0; --i) {
+ if (strlen (given_options[i]) > 0)
+ break;
+ given_options[i] = NULL;
+ }
+
+#ifdef sun
+ /* for read-only media append 'ro' option if not already */
+ append_ro = libhal_device_get_property_bool (hal_ctx, libhal_drive_get_udi(drive),
+ "storage.removable.solaris.read_only", NULL);
+
+ if (append_ro) {
+ for (i = 0; i < (int) g_strv_length (given_options); i++) {
+ if (strcmp (given_options[i], "ro") == 0) {
+ append_ro = FALSE;
+ }
+ }
+ }
+#endif /* sun */
+
+ /* is option 'remount' included? */
+ is_remount = FALSE;
+ for (i = 0; i < (int) g_strv_length (given_options); i++) {
+ if (strcmp (given_options[i], "remount") == 0) {
+ is_remount = TRUE;
+ }
+ }
+
+ mount_dir = NULL;
+ if (is_remount) {
+ if (volume != NULL) {
+ if (!libhal_volume_is_mounted (volume)) {
+ cannot_remount (device);
+ }
+ mount_dir = g_strdup (libhal_volume_get_mount_point (volume));
+ } else {
+ if (!device_is_mounted (device, &mount_dir)) {
+ cannot_remount (device);
+ }
+ }
+
+ if (mount_dir == NULL) {
+ unknown_error ("Cannot get mount_dir for remount even though volume is mounted!");
+ }
+
+ } else {
+ if (volume != NULL) {
+ if (libhal_volume_is_mounted (volume)) {
+ already_mounted (device);
+ }
+ } else {
+ if (device_is_mounted (device, NULL)) {
+ already_mounted (device);
+ }
+ }
+ }
+
+ if (!is_remount) {
+ /* figure out mount point if no mount point is given... */
+ explicit_mount_point_given = FALSE;
+ if (strlen (mount_point) == 0) {
+ char *p;
+ const char *label;
+
+ if (volume != NULL)
+ label = libhal_volume_get_label (volume);
+ else
+ label = NULL;
+
+ model = libhal_drive_get_model (drive);
+ drive_type = libhal_drive_get_type_textual (drive);
+
+ if (label != NULL) {
+ /* best - use label */
+ g_strlcpy (mount_point, label, sizeof (mount_point));
+
+ } else if ((model != NULL) && (strlen (model) > 0)) {
+ g_strlcpy (mount_point, model, sizeof (mount_point));
+ } else if ((drive_type != NULL) && (strlen (drive_type) > 0)) {
+ g_strlcpy (mount_point, drive_type, sizeof (mount_point));
+ } else {
+ /* fallback - use "disk" */
+ g_snprintf (mount_point, sizeof (mount_point), "disk");
+ }
+
+ /* sanitize computed mount point name, e.g. replace invalid chars with '-' */
+ p = mount_point;
+ while (TRUE) {
+ p = g_utf8_strchr (mount_point, -1, G_DIR_SEPARATOR);
+ if (p == NULL)
+ break;
+ *p = '-';
+ };
+
+ } else {
+ explicit_mount_point_given = TRUE;
+ }
+
+ /* check mount point name - only forbid separators */
+#ifdef sun
+ if (calling_uid != 0) {
+#endif
+ if (g_utf8_strchr (mount_point, -1, G_DIR_SEPARATOR) != NULL) {
+ printf ("'%s' is an invalid mount point\n", mount_point);
+ invalid_mount_point (mount_point);
+ }
+#ifdef sun
+ }
+#endif
+
+ /* check if mount point is available - append number to mount point */
+ i = 0;
+ mount_dir = NULL;
+ while (TRUE) {
+ g_free (mount_dir);
+#ifdef sun
+ if (is_abs_path)
+ mount_dir = g_strdup (mount_point);
+ else
+#endif
+ if (i == 0)
+ mount_dir = g_strdup_printf ("/media/%s", mount_point);
+ else
+ mount_dir = g_strdup_printf ("/media/%s-%d", mount_point, i);
+
+#ifdef DEBUG
+ printf ("trying dir %s\n", mount_dir);
+#endif
+
+ /* XXX should test for being a mount point */
+ if (!g_file_test (mount_dir, G_FILE_TEST_EXISTS)) {
+ break;
+ }
+#ifdef sun
+ if (calling_uid == 0) {
+ break;
+ }
+#endif
+ if (explicit_mount_point_given) {
+ mount_point_not_available (mount_dir);
+ }
+
+ i++;
+ }
+ }
+
+ dbus_error_init (&error);
+ allowed_options = libhal_device_get_property_strlist (hal_ctx, udi, "volume.mount.valid_options", &error);
+ if (dbus_error_is_set (&error)) {
+ unknown_error ("Cannot get volume.mount.valid_options");
+ dbus_error_free (&error);
+ }
+
+#ifdef DEBUG
+ for (i = 0; given_options[i] != NULL; i++)
+ printf ("given_options[%d] = '%s'\n", i, given_options[i]);
+ for (i = 0; allowed_options[i] != NULL; i++)
+ printf ("allowed_options[%d] = '%s'\n", i, allowed_options[i]);
+#endif
+
+ wants_to_change_uid = FALSE;
+
+ /* check mount options */
+ for (i = 0; given_options[i] != NULL; i++) {
+ char *given = given_options[i];
+
+ for (j = 0; allowed_options[j] != NULL; j++) {
+ char *allow = allowed_options[j];
+ int allow_len = strlen (allow);
+
+ if (strcmp (given, allow) == 0) {
+ goto option_ok;
+ }
+
+ if ((allow[allow_len - 1] == '=') &&
+ (strncmp (given, allow, allow_len) == 0) &&
+ (int) strlen (given) > allow_len) {
+
+ /* option matched allowed ending in '=', e.g.
+ * given == "umask=foobar" and allowed == "umask="
+ */
+ if (strcmp (allow, "uid=") == 0) {
+ uid_t uid;
+ char *endp;
+ /* check for uid=, it requires special handling */
+ uid = (uid_t) strtol (given + allow_len, &endp, 10);
+ if (*endp != '\0') {
+ printf ("'%s' is not a number?\n", given);
+ unknown_error ("option uid is malformed");
+ }
+#ifdef DEBUG
+ printf ("%s with uid %d\n", allow, uid);
+#endif
+ wants_to_change_uid = TRUE;
+
+ goto option_ok;
+ } else {
+
+ goto option_ok;
+ }
+ }
+ }
+
+ /* apparently option was not ok */
+ invalid_mount_option (given, invoked_by_uid);
+
+ option_ok:
+ ;
+ }
+
+ /* Check privilege */
+ pol_is_fixed = TRUE;
+ if (libhal_drive_is_hotpluggable (drive) || libhal_drive_uses_removable_media (drive))
+ pol_is_fixed = FALSE;
+
+ pol_change_uid = FALSE;
+ /* don't consider uid= on non-pollable drives for the purpose of policy
+ * (since these drives normally use vfat)
+ */
+ if (volume != NULL) {
+ /* don't consider uid= on vfat, iso9660, udf change-uid for the purpose of policy
+ * (since these doesn't contain uid/gid bits)
+ */
+ if (strcmp (libhal_volume_get_fstype (volume), "vfat") != 0 &&
+ strcmp (libhal_volume_get_fstype (volume), "iso9660") != 0 &&
+ strcmp (libhal_volume_get_fstype (volume), "udf") != 0) {
+ pol_change_uid = wants_to_change_uid;
+ }
+ }
+
+ if (pol_is_fixed) {
+ if (pol_change_uid) {
+ privilege = "hal-storage-fixed-mount-all-options";
+ } else {
+ privilege = "hal-storage-fixed-mount";
+ }
+ } else {
+ if (pol_change_uid) {
+ privilege = "hal-storage-removable-mount-all-options";
+ } else {
+ privilege = "hal-storage-removable-mount";
+ }
+ }
+
+#ifdef DEBUG
+ printf ("using privilege %s for uid %s, system_bus_connection %s\n", privilege, invoked_by_uid,
+ invoked_by_syscon_name);
+#endif
+
+#ifdef HAVE_POLKIT
+ if (libpolkit_is_uid_allowed_for_privilege (pol_ctx,
+ invoked_by_syscon_name,
+ invoked_by_uid,
+ privilege,
+ udi,
+ &allowed_by_privilege,
+ &is_temporary_privilege,
+ NULL) != LIBPOLKIT_RESULT_OK) {
+ printf ("cannot lookup privilege\n");
+ unknown_error ("Cannot lookup privilege from PolicyKit");
+ }
+
+ if (!allowed_by_privilege) {
+ printf ("caller don't possess privilege\n");
+ permission_denied_privilege (privilege, invoked_by_uid);
+ }
+#endif
+
+#ifdef DEBUG
+ printf ("passed privilege\n");
+#endif
+
+ if (!is_remount) {
+ /* create directory */
+#ifdef sun
+ if (!g_file_test (mount_dir, G_FILE_TEST_EXISTS))
+#endif
+ if (g_mkdir (mount_dir, 0700) != 0) {
+ printf ("Cannot create '%s'\n", mount_dir);
+ unknown_error ("Cannot create mount directory");
+ }
+
+#ifdef __FreeBSD__
+ calling_uid = (uid_t) strtol (invoked_by_uid, (char **) NULL, 10);
+ pw = getpwuid (calling_uid);
+ if (pw != NULL) {
+ calling_gid = pw->pw_gid;
+ } else {
+ calling_gid = 0;
+ }
+ if (chown (mount_dir, calling_uid, calling_gid) != 0) {
+ printf ("Cannot chown '%s' to uid: %d, gid: %d\n", mount_dir,
+ calling_uid, calling_gid);
+ g_rmdir (mount_dir);
+ unknown_error ();
+ }
+#endif
+ }
+
+ char *mount_option_commasep = NULL;
+ char *mount_do_fstype = "auto";
+
+ /* construct arguments to mount */
+ na = 0;
+ args[na++] = MOUNT;
+ if (strlen (mount_fstype) > 0) {
+ mount_do_fstype = (char *) map_fstype (mount_fstype);
+ } else if (volume == NULL) {
+ /* non-pollable drive; force auto */
+ mount_do_fstype = "auto";
+ } else if (libhal_volume_get_fstype (volume) != NULL && strlen (libhal_volume_get_fstype (volume)) > 0) {
+ mount_do_fstype = (char *) map_fstype (libhal_volume_get_fstype (volume));
+ }
+ args[na++] = MOUNT_TYPE_OPT;
+ args[na++] = mount_do_fstype;
+
+ args[na++] = "-o";
+ mount_option_str = g_string_new (MOUNT_OPTIONS);
+ for (i = 0; given_options[i] != NULL; i++) {
+ g_string_append (mount_option_str, ",");
+ g_string_append (mount_option_str, given_options[i]);
+ }
+#ifdef sun
+ if (append_ro) {
+ g_string_append (mount_option_str, ",ro");
+ }
+#endif
+ mount_option_commasep = g_string_free (mount_option_str, FALSE); /* leak! */
+ args[na++] = mount_option_commasep;
+ args[na++] = (char *) device;
+ args[na++] = mount_dir;
+ args[na++] = NULL;
+
+ /* TODO FIXME XXX HACK: OK, so we should rewrite the options in /media/.hal-mtab ..
+ * but it doesn't really matter much at this point */
+ if (!is_remount) {
+ FILE *hal_mtab;
+ char *mount_dir_escaped;
+ FILE *hal_mtab_orig;
+ int hal_mtab_orig_len;
+ int num_read;
+ char *hal_mtab_buf;
+ char *hal_mtab_buf_old;
+
+ /* Maintain a list in /media/.hal-mtab with entries of the following format
+ *
+ * <device_file>\t<uid>\t<session-id>\t<fstype>\t<options_sep_by_comma>\t<mount point>\n
+ *
+ * where session-id currently is unused and thus set to 0.
+ *
+ * Example:
+ *
+ * /dev/sda2 500 0 hfsplus noexec,nosuid,nodev /media/Macintosh HD
+ * /dev/sda4 500 0 ntfs noexec,nosuid,nodev,umask=222 /media/Windows
+ * /dev/sdb1 500 0 vfat noexec,nosuid,nodev,shortname=winnt,uid=500 /media/davidz
+ */
+
+
+ if (g_file_test ("/media/.hal-mtab", G_FILE_TEST_EXISTS)) {
+ hal_mtab_orig = fopen ("/media/.hal-mtab", "r");
+ if (hal_mtab_orig == NULL) {
+ unknown_error ("Cannot open /media/.hal-mtab");
+ }
+ if (fseek (hal_mtab_orig, 0L, SEEK_END) != 0) {
+ unknown_error ("Cannot seek to end of /media/.hal-mtab");
+ }
+ hal_mtab_orig_len = ftell (hal_mtab_orig);
+ if (hal_mtab_orig_len < 0) {
+ unknown_error ("Cannot determine size of /media/.hal-mtab");
+ }
+ rewind (hal_mtab_orig);
+ hal_mtab_buf = g_new0 (char, hal_mtab_orig_len + 1);
+ num_read = fread (hal_mtab_buf, 1, hal_mtab_orig_len, hal_mtab_orig);
+ if (num_read != hal_mtab_orig_len) {
+ unknown_error ("Cannot read from /media/.hal-mtab");
+ }
+ fclose (hal_mtab_orig);
+ } else {
+ hal_mtab_buf = g_strdup ("");
+ }
+
+ mount_dir_escaped = g_strescape (mount_dir, NULL);
+#ifdef DEBUG
+ printf ("%d: XYA creating /media/.hal-mtab~\n", getpid ());
+#endif
+ hal_mtab = fopen ("/media/.hal-mtab~", "w");
+ if (hal_mtab == NULL) {
+ unknown_error ("Cannot create /media/.hal-mtab~");
+ }
+ hal_mtab_buf_old = hal_mtab_buf;
+ hal_mtab_buf = g_strdup_printf ("%s%s\t%s\t0\t%s\t%s\t%s\n",
+ hal_mtab_buf_old,
+ device, invoked_by_uid, mount_do_fstype,
+ mount_option_commasep, mount_dir_escaped);
+ g_free (hal_mtab_buf_old);
+ if (hal_mtab_buf_old == NULL) {
+ unknown_error ("Out of memory appending to /media/.hal-mtab~");
+ }
+ if (fwrite (hal_mtab_buf, 1, strlen (hal_mtab_buf), hal_mtab) != strlen (hal_mtab_buf)) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+ fclose (hal_mtab);
+ g_free (hal_mtab_buf);
+ g_free (mount_dir_escaped);
+#ifdef DEBUG
+ printf ("%d: XYA closing /media/.hal-mtab~\n", getpid ());
+#endif
+ } /* !is_remount */
+
+ /* now try to mount */
+ if (!g_spawn_sync ("/",
+ args,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ printf ("Cannot execute %s\n", MOUNT);
+ g_rmdir (mount_dir);
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot spawn " MOUNT);
+ }
+
+
+ if (exit_status != 0) {
+ char errstr[] = "mount: unknown filesystem type";
+
+ printf ("%s error %d, stdout='%s', stderr='%s'\n", MOUNT, exit_status, sout, serr);
+
+ if (!is_remount) {
+ g_rmdir (mount_dir);
+ unlink ("/media/.hal-mtab~");
+ }
+
+ if (strncmp (errstr, serr, sizeof (errstr) - 1) == 0) {
+ unknown_filesystem (strlen (mount_fstype) > 0 ?
+ mount_fstype :
+ (volume != NULL ? libhal_volume_get_fstype (volume) : "") );
+ } else {
+ int n;
+ for (n = 0; serr[n] != '\0'; n++) {
+ if (serr[n] == '\n') {
+ serr[n] = ' ';
+ }
+ }
+ unknown_error (serr);
+ }
+ }
+
+ if (!is_remount) {
+ if (rename ("/media/.hal-mtab~", "/media/.hal-mtab") != 0) {
+ printf ("rename(2) failed, errno=%d -> '%s'\n", errno, strerror (errno));
+ unlink ("/media/.hal-mtab~");
+#ifdef DEBUG
+ printf ("%d: XYA failed renaming /media/.hal-mtab~ to /media/.hal-mtab\n", getpid ());
+#endif
+ unknown_error ("Cannot rename /media/.hal-mtab~ to /media/.hal-mtab");
+ }
+#ifdef DEBUG
+ printf ("%d: XYA done renaming /media/.hal-mtab~ to /media/.hal-mtab\n", getpid ());
+#endif
+ }
+
+ openlog ("hald", 0, LOG_DAEMON);
+ if (is_remount) {
+ syslog (LOG_INFO, "remounted %s at '%s' on behalf of uid %s", device, mount_dir, invoked_by_uid);
+ } else {
+ syslog (LOG_INFO, "mounted %s on behalf of uid %s", device, invoked_by_uid);
+ }
+ closelog ();
+
+#ifdef sun
+ if ((adt_data = get_audit_export_data (system_bus,
+ invoked_by_syscon_name, &adt_data_size)) != NULL) {
+ audit_volume (adt_data, ADT_attach,
+ WEXITSTATUS(exit_status), auth_from_privilege(privilege),
+ mount_dir, device, mount_option_commasep);
+ free (adt_data);
+ }
+#endif
+
+ g_free (sout);
+ g_free (serr);
+ g_free (mount_dir);
+ libhal_free_string_array (allowed_options);
+ g_strfreev (given_options);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device;
+ LibHalVolume *volume;
+ DBusError error;
+ LibHalContext *hal_ctx = NULL;
+ DBusConnection *system_bus = NULL;
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx = NULL;
+#endif
+ char *invoked_by_uid;
+ char *invoked_by_syscon_name;
+
+ if (!lock_hal_mtab ()) {
+ unknown_error ("Cannot obtain lock on /media/.hal-mtab");
+ }
+
+ device = getenv ("HAL_PROP_BLOCK_DEVICE");
+ if (device == NULL)
+ usage ();
+
+ udi = getenv ("HAL_PROP_INFO_UDI");
+ if (udi == NULL)
+ usage ();
+
+ invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
+
+ invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ printf ("Cannot connect to hald\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+
+ dbus_error_init (&error);
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (system_bus == NULL) {
+ printf ("Cannot connect to the system bus\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+#ifdef HAVE_POLKIT
+ pol_ctx = libpolkit_new_context (system_bus);
+ if (pol_ctx == NULL) {
+ printf ("Cannot get libpolkit context\n");
+ unknown_error ("Cannot get libpolkit context");
+ }
+#endif
+
+ volume = libhal_volume_from_udi (hal_ctx, udi);
+ if (volume == NULL) {
+ LibHalDrive *drive;
+
+ drive = libhal_drive_from_udi (hal_ctx, udi);
+ if (drive == NULL) {
+ usage ();
+ } else {
+ handle_mount (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ udi, NULL, drive, device, invoked_by_uid,
+ invoked_by_syscon_name, system_bus);
+ }
+
+ } else {
+ const char *drive_udi;
+ LibHalDrive *drive;
+
+ drive_udi = libhal_volume_get_storage_device_udi (volume);
+
+ if (drive_udi == NULL)
+ unknown_error ("Cannot get drive_udi from volume");
+ drive = libhal_drive_from_udi (hal_ctx, drive_udi);
+ if (drive == NULL)
+ unknown_error ("Cannot get drive from hal");
+
+ handle_mount (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ udi, volume, drive, device, invoked_by_uid,
+ invoked_by_syscon_name, system_bus);
+
+ }
+
+ unlock_hal_mtab ();
+
+ return 0;
+}
diff --git a/usr/src/cmd/hal/tools/hal-storage-shared.c b/usr/src/cmd/hal/tools/hal-storage-shared.c
new file mode 100644
index 0000000000..05a1c43a36
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-shared.c
@@ -0,0 +1,838 @@
+/***************************************************************************
+ * CVSID: $Id: hal-storage-mount.c,v 1.7 2006/06/21 00:44:03 david Exp $
+ *
+ * hal-storage-mount.c : Mount wrapper
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#ifdef __FreeBSD__
+#include <fstab.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <pwd.h>
+#elif sun
+#include <fcntl.h>
+#include <sys/mnttab.h>
+#include <sys/vfstab.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+#else
+#include <mntent.h>
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <errno.h>
+#include <syslog.h>
+
+#include "hal-storage-shared.h"
+
+#ifdef __FreeBSD__
+struct mtab_handle
+{
+ struct statfs *mounts;
+ int n_mounts;
+ int iter;
+};
+#endif
+
+
+gboolean
+mtab_open (gpointer *handle)
+{
+#ifdef __FreeBSD__
+ struct mtab_handle *mtab;
+
+ mtab = g_new0 (struct mtab_handle, 1);
+ mtab->n_mounts = getmntinfo (&mtab->mounts, MNT_NOWAIT);
+ if (mtab->n_mounts == 0) {
+ g_free (mtab);
+ return FALSE;
+ }
+
+ *handle = mtab;
+ return TRUE;
+#elif sun
+ *handle = fopen (MNTTAB, "r");
+ return *handle != NULL;
+#else
+ *handle = fopen ("/proc/mounts", "r");
+ return *handle != NULL;
+#endif
+}
+
+char *
+mtab_next (gpointer handle, char **mount_point)
+{
+#ifdef __FreeBSD__
+ struct mtab_handle *mtab = handle;
+
+ if (mtab->iter < mtab->n_mounts)
+ return mtab->mounts[mtab->iter++].f_mntfromname;
+ else
+ return NULL;
+#error TODO: set *mount_point to g_strdup()-ed value if mount_point!=NULL
+#elif sun
+ static struct mnttab mnt;
+
+ if (getmntent (handle, &mnt) == 0) {
+ if (mount_point != NULL) {
+ *mount_point = g_strdup (mnt.mnt_mountp);
+ }
+ return mnt.mnt_special;
+ } else {
+ return NULL;
+ }
+#else
+ struct mntent *mnt;
+
+ mnt = getmntent (handle);
+
+ if (mnt != NULL) {
+ if (mount_point != NULL) {
+ *mount_point = g_strdup (mnt->mnt_dir);
+ }
+ return mnt->mnt_fsname;
+ } else {
+ return NULL;
+ }
+#endif
+}
+
+void
+mtab_close (gpointer handle)
+{
+#ifdef __FreeBSD__
+ g_free (handle);
+#else
+ fclose (handle);
+#endif
+}
+
+
+
+gboolean
+fstab_open (gpointer *handle)
+{
+#ifdef __FreeBSD__
+ return setfsent () == 1;
+#elif sun
+ *handle = fopen (VFSTAB, "r");
+ return *handle != NULL;
+#else
+ *handle = fopen ("/etc/fstab", "r");
+ return *handle != NULL;
+#endif
+}
+
+char *
+fstab_next (gpointer handle, char **mount_point)
+{
+#ifdef __FreeBSD__
+ struct fstab *fstab;
+
+ fstab = getfsent ();
+
+ /* TODO: fill out mount_point */
+ if (mount_point != NULL && fstab != NULL) {
+ *mount_point = fstab->fs_file;
+ }
+
+ return fstab ? fstab->fs_spec : NULL;
+#elif sun
+ static struct vfstab v;
+
+ return getvfsent (handle, &v) == 0 ? v.vfs_special : NULL;
+#else
+ struct mntent *mnt;
+
+ mnt = getmntent (handle);
+
+ if (mount_point != NULL && mnt != NULL) {
+ *mount_point = mnt->mnt_dir;
+ }
+
+ return mnt ? mnt->mnt_fsname : NULL;
+#endif
+}
+
+void
+fstab_close (gpointer handle)
+{
+#ifdef __FreeBSD__
+ endfsent ();
+#else
+ fclose (handle);
+#endif
+}
+
+#ifdef __FreeBSD__
+#define UMOUNT "/sbin/umount"
+#elif sun
+#define UMOUNT "/sbin/umount"
+#else
+#define UMOUNT "/bin/umount"
+#endif
+
+void
+unknown_error (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+
+static void
+device_busy (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.Busy\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+
+static void
+not_mounted (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.NotMounted\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+
+static void
+not_mounted_by_hal (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.NotMountedByHal\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+static void
+permission_denied_privilege (const char *privilege, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n");
+ fprintf (stderr, "%s refused uid %s\n", privilege, uid);
+ exit (1);
+}
+
+static void
+permission_denied_volume_ignore (const char *device)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.PermissionDenied\n");
+ fprintf (stderr, "Device has %s volume.ignore set to TRUE. Refusing to mount.\n", device);
+ exit (1);
+}
+
+void
+handle_unmount (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalVolume *volume, LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ gboolean option_lazy, gboolean option_force,
+ DBusConnection *system_bus)
+{
+ int i, j;
+ DBusError error;
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[10];
+ int na;
+ FILE *hal_mtab_orig;
+ int hal_mtab_orig_len;
+ int num_read;
+ char *hal_mtab_buf;
+ char **lines;
+ char *mount_point_to_unmount;
+ gboolean mounted_by_other_uid;
+ FILE *hal_mtab_new;
+#ifdef sun
+ adt_export_data_t *adt_data;
+ size_t adt_data_size;
+#endif
+
+#ifdef DEBUG
+ printf ("device = %s\n", device);
+ printf ("invoked by uid = %s\n", invoked_by_uid);
+ printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
+#endif
+
+ if (volume != NULL) {
+ dbus_error_init (&error);
+ if (libhal_device_get_property_bool (hal_ctx, udi, "volume.ignore", &error) ||
+ dbus_error_is_set (&error)) {
+ if (dbus_error_is_set (&error)) {
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ /*
+ * When device allocation is enabled (bsmconv or TX), we
+ * set volume.ignore on all volumes, but still want
+ * Mount() to succeed when called from the euid=0
+ * device allocation program.
+ */
+ if (atol (invoked_by_uid) != 0) {
+ permission_denied_volume_ignore (device);
+ }
+ }
+
+ if (!libhal_volume_is_mounted (volume)) {
+ not_mounted ("According to HAL, the volume is not mounted");
+ }
+ }
+
+
+ /* check hal's mtab file to verify the device to unmount is actually mounted by hal */
+ hal_mtab_orig = fopen ("/media/.hal-mtab", "r");
+ if (hal_mtab_orig == NULL) {
+ unknown_error ("Cannot open /media/.hal-mtab");
+ }
+ if (fseek (hal_mtab_orig, 0L, SEEK_END) != 0) {
+ unknown_error ("Cannot seek to end of /media/.hal-mtab");
+ }
+ hal_mtab_orig_len = ftell (hal_mtab_orig);
+ if (hal_mtab_orig_len < 0) {
+ unknown_error ("Cannot determine size of /media/.hal-mtab");
+ }
+ rewind (hal_mtab_orig);
+ hal_mtab_buf = g_new0 (char, hal_mtab_orig_len + 1);
+ num_read = fread (hal_mtab_buf, 1, hal_mtab_orig_len, hal_mtab_orig);
+ if (num_read != hal_mtab_orig_len) {
+ unknown_error ("Cannot read from /media/.hal-mtab");
+ }
+ fclose (hal_mtab_orig);
+
+#ifdef DEBUG
+ printf ("hal_mtab = '%s'\n", hal_mtab_buf);
+#endif
+
+ lines = g_strsplit (hal_mtab_buf, "\n", 0);
+ g_free (hal_mtab_buf);
+
+ mount_point_to_unmount = NULL;
+ mounted_by_other_uid = TRUE;
+
+ /* find the entry we're going to unmount */
+ for (i = 0; lines[i] != NULL; i++) {
+ char **line_elements;
+ char *special, *dosp;
+ struct stat st;
+
+#ifdef DEBUG
+ printf (" line = '%s'\n", lines[i]);
+#endif
+
+ if ((lines[i])[0] == '#')
+ continue;
+
+ line_elements = g_strsplit (lines[i], "\t", 6);
+ if (g_strv_length (line_elements) == 6) {
+
+#ifdef DEBUG
+ printf (" devfile = '%s'\n", line_elements[0]);
+ printf (" uid = '%s'\n", line_elements[1]);
+ printf (" session id = '%s'\n", line_elements[2]);
+ printf (" fs = '%s'\n", line_elements[3]);
+ printf (" options = '%s'\n", line_elements[4]);
+ printf (" mount_point = '%s'\n", line_elements[5]);
+#endif
+
+ if (strcmp (line_elements[0], device) == 0) {
+ char *line_to_free;
+
+ if (strcmp (line_elements[1], invoked_by_uid) == 0) {
+ mounted_by_other_uid = FALSE;
+ }
+#ifdef sun
+ if (stat("/dev/console", &st) == 0 &&
+ st.st_uid == atoi (invoked_by_uid)) {
+ /*
+ * Owner is allowed to take over. Before we have real
+ * ownership in HAL, assume it's the console owner.
+ */
+ mounted_by_other_uid = FALSE;
+ }
+#endif /* sun */
+ mount_point_to_unmount = g_strdup (line_elements[5]);
+
+ line_to_free = lines[i];
+
+ for (j = i; lines[j] != NULL; j++) {
+ lines[j] = lines[j+1];
+ }
+ lines[j] = NULL;
+
+ g_free (line_to_free);
+
+ g_strfreev (line_elements);
+ goto line_found;
+
+ }
+
+ }
+
+ g_strfreev (line_elements);
+ }
+line_found:
+
+ if (mount_point_to_unmount == NULL) {
+ not_mounted_by_hal ("Device to unmount is not in /media/.hal-mtab so it is not mounted by HAL");
+ }
+
+ /* bail out, unless if we got the "hal-storage-can-unmount-volumes-mounted-by-others" privilege only
+ * if mounted_by_other_uid==TRUE
+ *
+ * We allow uid 0 to actually ensure that Unmount(options=["lazy"], "/dev/blah") works from addon-storage.
+ */
+ if ((strcmp (invoked_by_uid, "0") != 0) && mounted_by_other_uid) {
+ /* TODO: actually check for privilege "hal-storage-can-unmount-volumes-mounted-by-others" */
+ permission_denied_privilege ("hal-storage-can-unmount-volumes-mounted-by-others", invoked_by_uid);
+ }
+
+ /* create new .hal-mtab~ file without the entry we're going to unmount */
+ hal_mtab_new = fopen ("/media/.hal-mtab~", "w");
+ if (hal_mtab_new == NULL) {
+ unknown_error ("Cannot create /media/.hal-mtab~");
+ }
+ for (i = 0; lines[i] != NULL; i++) {
+ if (i > 0) {
+ char anewl[2] = "\n\0";
+ if (fwrite (anewl, 1, 1, hal_mtab_new) != 1) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+ }
+
+ if (fwrite (lines[i], 1, strlen (lines[i]), hal_mtab_new) != strlen (lines[i])) {
+ unknown_error ("Cannot write to /media/.hal-mtab~");
+ }
+
+ }
+ fclose (hal_mtab_new);
+
+ g_strfreev (lines);
+
+ /* construct arguments to /bin/umount */
+ na = 0;
+ args[na++] = UMOUNT;
+ if (option_lazy)
+ args[na++] = "-l";
+ if (option_force)
+ args[na++] = "-f";
+ args[na++] = (char *) device;
+ args[na++] = NULL;
+
+#ifdef DEBUG
+ printf ("will umount %s (mounted at '%s'), mounted_by_other_uid=%d\n",
+ device, mount_point_to_unmount, mounted_by_other_uid);
+#endif
+
+ /* invoke /bin/umount */
+ if (!g_spawn_sync ("/",
+ args,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ printf ("Cannot execute %s\n", UMOUNT);
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot spawn " UMOUNT);
+ }
+
+ /* check if unmount was succesful */
+ if (exit_status != 0) {
+ printf ("%s error %d, stdout='%s', stderr='%s'\n", UMOUNT, exit_status, sout, serr);
+
+ if (strstr (serr, "device is busy") != NULL) {
+ unlink ("/media/.hal-mtab~");
+ device_busy (serr);
+ } else {
+ unlink ("/media/.hal-mtab~");
+ unknown_error (serr);
+ }
+ }
+
+#ifdef sun
+ if ((adt_data = get_audit_export_data (system_bus,
+ invoked_by_syscon_name, &adt_data_size)) != NULL) {
+ audit_volume (adt_data, ADT_detach, WEXITSTATUS(exit_status),
+ "solaris.device.mount.removable",
+ mount_point_to_unmount, device, NULL);
+ free (adt_data);
+ }
+#endif
+
+ /* unmount was succesful, remove directory we created in Mount() */
+#ifdef sun
+ if (strncmp (mount_point_to_unmount, "/media/", 7) == 0)
+#endif
+ if (g_rmdir (mount_point_to_unmount) != 0) {
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot remove directory");
+ }
+
+ /* set new .hal-mtab file */
+ if (rename ("/media/.hal-mtab~", "/media/.hal-mtab") != 0) {
+ unlink ("/media/.hal-mtab~");
+ unknown_error ("Cannot rename /media/.hal-mtab~ to /media/.hal-mtab");
+ }
+
+#ifdef DEBUG
+ printf ("done unmounting\n");
+#endif
+ openlog ("hald", 0, LOG_DAEMON);
+ syslog (LOG_INFO, "unmounted %s from '%s' on behalf of uid %s", device, mount_point_to_unmount, invoked_by_uid);
+ closelog ();
+
+ g_free (sout);
+ g_free (serr);
+ g_free (mount_point_to_unmount);
+}
+
+#define EJECT "/usr/bin/eject"
+
+void
+handle_eject (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ gboolean closetray, DBusConnection *system_bus)
+{
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[10];
+ int na;
+#ifdef sun
+ adt_export_data_t *adt_data;
+ size_t adt_data_size;
+#endif
+ /* TODO: should we require privileges here? */
+
+#ifdef DEBUG
+ printf ("device = %s\n", device);
+ printf ("invoked by uid = %s\n", invoked_by_uid);
+ printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
+#endif
+
+ /* construct arguments to EJECT (e.g. /usr/bin/eject) */
+ na = 0;
+ args[na++] = EJECT;
+ if (closetray) {
+ args[na++] = "-t";
+ }
+ args[na++] = (char *) device;
+ args[na++] = NULL;
+
+#ifdef sun
+ putenv("EJECT_DIRECT=1");
+#endif
+
+#ifdef DEBUG
+ printf ("will eject %s\n", device);
+#endif
+
+ /* invoke eject command */
+ if (!g_spawn_sync ("/",
+ args,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ printf ("Cannot execute %s\n", EJECT);
+ unknown_error ("Cannot spawn " EJECT);
+ }
+
+#ifdef sun
+ /*
+ * Solaris eject returns 4 for manually ejectable media like floppy.
+ * Consider it success.
+ */
+ if (WEXITSTATUS(exit_status) == 4) {
+ exit_status = 0;
+ }
+
+ if ((adt_data = get_audit_export_data (system_bus,
+ invoked_by_syscon_name, &adt_data_size)) != NULL) {
+ audit_volume (adt_data, ADT_remove, WEXITSTATUS(exit_status),
+ "solaris.device.mount.removable", NULL, device, NULL);
+ free (adt_data);
+ }
+#endif /* sun */
+
+ /* check if eject was succesful */
+ if (exit_status != 0) {
+ printf ("%s error %d, stdout='%s', stderr='%s'\n", EJECT, exit_status, sout, serr);
+
+ unknown_error (serr);
+ }
+
+ /* eject was succesful... */
+
+#ifdef DEBUG
+ printf ("done ejecting\n");
+#endif
+
+ g_free (sout);
+ g_free (serr);
+}
+
+
+static int lock_mtab_fd = -1;
+
+gboolean
+lock_hal_mtab (void)
+{
+ if (lock_mtab_fd >= 0)
+ return TRUE;
+
+ printf ("%d: XYA attempting to get lock on /media/.hal-mtab-lock\n", getpid ());
+
+ lock_mtab_fd = open ("/media/.hal-mtab-lock", O_CREAT | O_RDWR);
+
+ if (lock_mtab_fd < 0)
+ return FALSE;
+
+tryagain:
+#if sun
+ if (lockf (lock_mtab_fd, F_LOCK, 0) != 0) {
+#else
+ if (flock (lock_mtab_fd, LOCK_EX) != 0) {
+#endif
+ if (errno == EINTR)
+ goto tryagain;
+ return FALSE;
+ }
+
+ printf ("%d: XYA got lock on /media/.hal-mtab-lock\n", getpid ());
+
+
+ return TRUE;
+}
+
+void
+unlock_hal_mtab (void)
+{
+#if sun
+ lockf (lock_mtab_fd, F_ULOCK, 0);
+#else
+ flock (lock_mtab_fd, LOCK_UN);
+#endif
+ close (lock_mtab_fd);
+ lock_mtab_fd = -1;
+ printf ("%d: XYA released lock on /media/.hal-mtab-lock\n", getpid ());
+}
+
+#if sun
+
+/* map PolicyKit privilege to RBAC authorization */
+char *
+auth_from_privilege(const char *privilege)
+{
+ char *authname;
+ int i;
+
+ if (strcmp (privilege, "hal-storage-removable-mount") == 0) {
+ authname = g_strdup ("solaris.device.mount.removable");
+ } else if (strcmp (privilege, "hal-storage-removable-mount-all-options") == 0) {
+ authname = g_strdup ("solaris.device.mount.alloptions.removable");
+ } else if (strcmp (privilege, "hal-storage-fixed-mount") == 0) {
+ authname = g_strdup ("solaris.device.mount.fixed");
+ } else if (strcmp (privilege, "hal-storage-fixed-mount-all-options") == 0) {
+ authname = g_strdup ("solaris.device.mount.alloptions.fixed");
+ } else {
+ /* replace '-' with '.' */
+ authname = g_strdup (privilege);
+ for (i = 0; i < strlen (authname); i++) {
+ if (authname[i] == '-') {
+ authname[i] = '.';
+ }
+ }
+ }
+ return (authname);
+}
+
+adt_export_data_t *
+get_audit_export_data(DBusConnection *bus, const char *invoked_by_syscon_name, size_t *data_size)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, subiter;
+ DBusError error;
+ int count, bufsize;
+ uchar_t *buf;
+ uchar_t value;
+
+ message = dbus_message_new_method_call ("org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetAuditSessionData");
+ if (message == NULL) {
+ printf ("cannot get message\n");
+ return NULL;
+ }
+
+ if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &invoked_by_syscon_name,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(message);
+ return NULL;
+ }
+
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (bus,
+ message, -1,
+ &error);
+ if (dbus_error_is_set (&error)) {
+ printf ("send failed %s\n", error.message);
+ dbus_error_free (&error);
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ dbus_message_iter_init (reply, &iter);
+
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_BYTE) {
+ printf ("expecting an array of byte entries\n");
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return NULL;
+ }
+ dbus_message_iter_recurse (&iter, &subiter);
+
+ count = 0;
+ bufsize = 256;
+ buf = (uchar_t *)malloc (bufsize);
+
+ while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_BYTE) {
+ if (count == bufsize) {
+ bufsize += 256;
+ buf = realloc (buf, bufsize);
+ if (buf == NULL) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return NULL;
+ }
+ }
+
+ dbus_message_iter_get_basic (&subiter, &value);
+ buf[count++] = value;
+ dbus_message_iter_next(&subiter);
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ *data_size = count;
+ if (count == 0) {
+ free (buf);
+ buf = NULL;
+ }
+
+ return (adt_export_data_t *)buf;
+}
+
+void
+audit_volume(const adt_export_data_t *imported_state, au_event_t event_id,
+ int result, const char *auth_used, const char *mount_point,
+ const char *device, const char *options)
+{
+ adt_session_data_t *ah;
+ adt_event_data_t *event;
+
+ if (adt_start_session(&ah, imported_state, 0) != 0) {
+ printf ("adt_start_session failed %d\n", errno);
+ return;
+ }
+ if ((event = adt_alloc_event(ah, event_id)) == NULL) {
+ printf ("adt_alloc_event(ADT_attach)\n", errno);
+ return;
+ }
+
+ switch (event_id) {
+ case ADT_attach:
+ event->adt_attach.auth_used = (char *)auth_used;
+ event->adt_attach.mount_point = (char *)mount_point;
+ event->adt_attach.device = (char *)device;
+ event->adt_attach.options = (char *)options;
+ break;
+ case ADT_detach:
+ event->adt_detach.auth_used = (char *)auth_used;
+ event->adt_detach.mount_point = (char *)mount_point;
+ event->adt_detach.device = (char *)device;
+ event->adt_detach.options = (char *)options;
+ break;
+ case ADT_remove:
+ event->adt_remove.auth_used = (char *)auth_used;
+ event->adt_remove.mount_point = (char *)mount_point;
+ event->adt_remove.device = (char *)device;
+ break;
+ default:
+ goto out;
+ }
+
+ if (result == 0) {
+ if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
+ printf ("adt_put_event(%d, success)\n", event_id);
+ }
+ } else {
+ if (adt_put_event(event, ADT_FAILURE, result) != 0) {
+ printf ("adt_put_event(%d, failure)\n", event_id);
+ }
+ }
+out:
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+}
+
+#endif /* sun */
diff --git a/usr/src/cmd/hal/tools/hal-storage-shared.h b/usr/src/cmd/hal/tools/hal-storage-shared.h
new file mode 100644
index 0000000000..8238011e2f
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-shared.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * CVSID: $Id: hal-storage-mount.c,v 1.7 2006/06/21 00:44:03 david Exp $
+ *
+ * hal-storage-mount.c : Mount wrapper
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef HAL_STORAGE_SHARED_H
+#define HAL_STORAGE_SHARED_H
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+#ifdef sun
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+#endif
+
+/*#define DEBUG*/
+#define DEBUG
+
+gboolean mtab_open (gpointer *handle);
+char *mtab_next (gpointer handle, char **mount_point);
+void mtab_close (gpointer handle);
+
+gboolean fstab_open (gpointer *handle);
+char *fstab_next (gpointer handle, char **mount_point);
+void fstab_close (gpointer handle);
+
+gboolean lock_hal_mtab (void);
+void unlock_hal_mtab (void);
+
+void unknown_error (const char *detail);
+
+void handle_unmount (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalVolume *volume, LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ gboolean option_lazy, gboolean option_force,
+ DBusConnection *system_bus);
+
+void handle_eject (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ gboolean closetray, DBusConnection *system_bus);
+
+#ifdef sun
+char *auth_from_privilege(const char *privilege);
+adt_export_data_t *get_audit_export_data(DBusConnection *bus, const char *invoked_by_syscon_name,
+ size_t *data_size);
+void audit_volume(const adt_export_data_t *imported_state, au_event_t event_id, int result,
+ const char *auth_used, const char *mount_point, const char *device, const char *options);
+#endif /* sun */
+
+#endif /* HAL_STORAGE_SHARED_H */
+
diff --git a/usr/src/cmd/hal/tools/hal-storage-unmount.c b/usr/src/cmd/hal/tools/hal-storage-unmount.c
new file mode 100644
index 0000000000..e9476742ac
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-unmount.c
@@ -0,0 +1,212 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal-storage-unmount.c : Unmount wrapper
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#ifdef __FreeBSD__
+#include <fstab.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <pwd.h>
+#elif sun
+#include <fcntl.h>
+#include <sys/mnttab.h>
+#include <sys/vfstab.h>
+#else
+#include <mntent.h>
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+
+#include "hal-storage-shared.h"
+
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+static void
+invalid_unmount_option (const char *option, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.InvalidUnmountOption\n");
+ fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ exit (1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device;
+ LibHalVolume *volume;
+ DBusError error;
+ LibHalContext *hal_ctx = NULL;
+ DBusConnection *system_bus = NULL;
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx = NULL;
+#endif
+ char *invoked_by_uid;
+ char *invoked_by_syscon_name;
+ int i;
+ char unmount_options[1024];
+ char **given_options;
+ gboolean use_lazy;
+ gboolean use_force;
+ const char *end;
+
+ if (!lock_hal_mtab ()) {
+ unknown_error ("Cannot obtain lock on /media/.hal-mtab");
+ }
+
+ device = getenv ("HAL_PROP_BLOCK_DEVICE");
+ if (device == NULL)
+ usage ();
+
+ udi = getenv ("HAL_PROP_INFO_UDI");
+ if (udi == NULL)
+ usage ();
+
+ invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
+
+ invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ printf ("Cannot connect to hald\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+
+ dbus_error_init (&error);
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (system_bus == NULL) {
+ printf ("Cannot connect to the system bus\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+#ifdef HAVE_POLKIT
+ pol_ctx = libpolkit_new_context (system_bus);
+ if (pol_ctx == NULL) {
+ printf ("Cannot get libpolkit context\n");
+ unknown_error ("Cannot get libpolkit context");
+ }
+#endif
+
+ /* read from stdin */
+ if (strlen (fgets (unmount_options, sizeof (unmount_options), stdin)) > 0)
+ unmount_options [strlen (unmount_options) - 1] = '\0';
+ /* validate that input from stdin is UTF-8 */
+ if (!g_utf8_validate (unmount_options, -1, &end))
+ unknown_error ("Error validating unmount_options as UTF-8");
+#ifdef DEBUG
+ printf ("unmount_options = '%s'\n", unmount_options);
+#endif
+
+ /* delete any trailing whitespace options from splitting the string */
+ given_options = g_strsplit (unmount_options, "\t", 0);
+ for (i = g_strv_length (given_options) - 1; i >= 0; --i) {
+ if (strlen (given_options[i]) > 0)
+ break;
+ given_options[i] = NULL;
+ }
+
+ use_lazy = FALSE;
+ use_force = FALSE;
+
+ /* check unmount options */
+ for (i = 0; given_options[i] != NULL; i++) {
+ char *given = given_options[i];
+
+ if (strcmp (given, "lazy") == 0) {
+ use_lazy = TRUE;
+ } else if (strcmp (given, "force") == 0) {
+ use_force = TRUE;
+ } else {
+ invalid_unmount_option (given, invoked_by_uid);
+ }
+ }
+ g_strfreev (given_options);
+
+
+ volume = libhal_volume_from_udi (hal_ctx, udi);
+ if (volume == NULL) {
+ LibHalDrive *drive;
+
+ drive = libhal_drive_from_udi (hal_ctx, udi);
+ if (drive == NULL) {
+ usage ();
+ } else {
+ handle_unmount (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ udi, NULL, drive, device, invoked_by_uid,
+ invoked_by_syscon_name, use_lazy, use_force,
+ system_bus);
+ }
+
+ } else {
+ const char *drive_udi;
+ LibHalDrive *drive;
+
+ drive_udi = libhal_volume_get_storage_device_udi (volume);
+
+ if (drive_udi == NULL)
+ unknown_error ("Cannot get drive_udi from volume");
+ drive = libhal_drive_from_udi (hal_ctx, drive_udi);
+ if (drive == NULL)
+ unknown_error ("Cannot get drive from hal");
+
+ handle_unmount (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ udi, volume, drive, device, invoked_by_uid,
+ invoked_by_syscon_name, use_lazy, use_force,
+ system_bus);
+
+ }
+
+ unlock_hal_mtab ();
+
+ return 0;
+}
diff --git a/usr/src/cmd/hal/tools/hal-storage-zpool.c b/usr/src/cmd/hal/tools/hal-storage-zpool.c
new file mode 100644
index 0000000000..029b00d25c
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal-storage-zpool.c
@@ -0,0 +1,255 @@
+/***************************************************************************
+ *
+ * hal-storage-zpool.c : ZFS pool methods
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <wait.h>
+#include <unistd.h>
+#include <bsm/adt.h>
+#include <bsm/adt_event.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+
+#include "hal-storage-shared.h"
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+
+void static
+unknown_zpool_error (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+void
+audit_pool(const adt_export_data_t *imported_state, au_event_t event_id,
+ int result, const char *auth_used, const char *pool, const char *device)
+{
+ adt_session_data_t *ah;
+ adt_event_data_t *event;
+
+ if (adt_start_session(&ah, imported_state, 0) != 0) {
+ printf ("adt_start_session failed %d\n", errno);
+ return;
+ }
+ if ((event = adt_alloc_event(ah, event_id)) == NULL) {
+ printf ("adt_alloc_event(ADT_attach)\n", errno);
+ return;
+ }
+
+ switch (event_id) {
+ case ADT_pool_export:
+ event->adt_pool_export.auth_used = (char *)auth_used;
+ event->adt_pool_export.pool = (char *)pool;
+ event->adt_pool_export.device = (char *)device;
+ break;
+ case ADT_pool_import:
+ event->adt_pool_import.auth_used = (char *)auth_used;
+ event->adt_pool_import.pool = (char *)pool;
+ event->adt_pool_import.device = (char *)device;
+ break;
+ default:
+ goto out;
+ }
+
+ if (result == 0) {
+ if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
+ printf ("adt_put_event(%d, success)\n", event_id);
+ }
+ } else {
+ if (adt_put_event(event, ADT_FAILURE, result) != 0) {
+ printf ("adt_put_event(%d, failure)\n", event_id);
+ }
+ }
+out:
+ adt_free_event(event);
+ (void) adt_end_session(ah);
+}
+
+
+void
+handle_zpool (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ char *subcmd, const char *pool, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ DBusConnection *system_bus)
+{
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status = 0;
+ char *args[10];
+ int na;
+ adt_export_data_t *adt_data;
+ size_t adt_data_size;
+ au_event_t event_id;
+
+#ifdef DEBUG
+ printf ("subcmd = %s\n", subcmd);
+ printf ("pool = %s\n", pool);
+ printf ("device = %s\n", device);
+ printf ("invoked by uid = %s\n", invoked_by_uid);
+ printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
+#endif
+
+ na = 0;
+ args[na++] = "/usr/sbin/zpool";
+ args[na++] = subcmd;
+ if ((strcmp (subcmd, "import") == 0) &&
+ (strncmp (device, "/dev/lofi", 9) == 0)) {
+ args[na++] = "-d";
+ args[na++] = "/dev/lofi";
+ }
+ args[na++] = (char *) pool;
+ args[na++] = NULL;
+
+ /* invoke eject command */
+ if (!g_spawn_sync ("/",
+ args,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ printf ("Cannot execute zpool %s\n", subcmd);
+ unknown_zpool_error ("Cannot spawn zpool");
+ }
+
+ if ((adt_data = get_audit_export_data (system_bus,
+ invoked_by_syscon_name, &adt_data_size)) != NULL) {
+ event_id = (strcmp (subcmd, "import") == 0) ?
+ ADT_pool_import : ADT_pool_export;
+ audit_pool (adt_data, event_id, WEXITSTATUS(exit_status),
+ "solaris.device.mount.removable", pool, device);
+ free (adt_data);
+ }
+
+ if (exit_status != 0) {
+ printf ("zpool error %d, stdout='%s', stderr='%s'\n", exit_status, sout, serr);
+
+ unknown_zpool_error (serr);
+ }
+
+ g_free (sout);
+ g_free (serr);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device;
+ const char *drive_udi;
+ LibHalDrive *drive;
+ LibHalVolume *volume;
+ DBusError error;
+ LibHalContext *hal_ctx = NULL;
+ DBusConnection *system_bus = NULL;
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx = NULL;
+#endif
+ char *invoked_by_uid;
+ char *invoked_by_syscon_name;
+
+ device = getenv ("HAL_PROP_BLOCK_DEVICE");
+ if (device == NULL)
+ usage ();
+
+ udi = getenv ("HAL_PROP_INFO_UDI");
+ if (udi == NULL)
+ usage ();
+
+ invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
+
+ invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ printf ("Cannot connect to hald\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+
+ dbus_error_init (&error);
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (system_bus == NULL) {
+ printf ("Cannot connect to the system bus\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+#ifdef HAVE_POLKIT
+ pol_ctx = libpolkit_new_context (system_bus);
+ if (pol_ctx == NULL) {
+ printf ("Cannot get libpolkit context\n");
+ unknown_zpool_error ("Cannot get libpolkit context");
+ }
+#endif
+
+ /* should be a volume */
+ if ((volume = libhal_volume_from_udi (hal_ctx, udi)) == NULL) {
+ unknown_zpool_error ("Invalid volume");
+ }
+ if ((drive_udi = libhal_volume_get_storage_device_udi (volume)) == NULL ) {
+ unknown_zpool_error ("Cannot get drive udi");
+ }
+ if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
+ unknown_zpool_error ("Cannot get drive from udi");
+ }
+ if ((libhal_volume_get_fstype (volume) == NULL) ||
+ (strcmp (libhal_volume_get_fstype (volume), "zfs") != 0)) {
+ unknown_zpool_error ("Not a zpool");
+ }
+ if ((libhal_volume_get_label (volume) == NULL) ||
+ (strlen (libhal_volume_get_label (volume)) == 0)) {
+ unknown_zpool_error ("Invalid zpool name");
+ }
+
+ handle_zpool (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ ZPOOL_SUBCMD,
+ libhal_volume_get_label (volume),
+ device,
+ invoked_by_uid,
+ invoked_by_syscon_name,
+ system_bus);
+
+ return 0;
+}
+
diff --git a/usr/src/cmd/hal/tools/hal_find_by_capability.c b/usr/src/cmd/hal/tools/hal_find_by_capability.c
new file mode 100644
index 0000000000..8433003acc
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal_find_by_capability.c
@@ -0,0 +1,186 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal_find_by_capability.c : Find hal devices
+ *
+ * Copyright (C) 2005 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <libhal.h>
+
+
+/** Print out program usage.
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ */
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr,
+ "\n"
+ "usage : hal-find-by-capability --capability <capability>\n"
+ " [--help] [--verbose] [--version]\n");
+ fprintf (stderr,
+ "\n"
+ " --capability HAL Device Capability to search for\n"
+ " --verbose Be verbose\n"
+ " --version Show version and exit\n"
+ " --help Show this information and exit\n"
+ "\n"
+ "This program prints the Unique Device Identifiers for HAL device\n"
+ "objects of a given capability on stdout and exits with exit code 0\n"
+ "If there is an error, the program exits with an exit code different\n"
+ "from 0.\n"
+ "\n");
+}
+
+/** Entry point
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ * @return Return code
+ */
+int
+main (int argc, char *argv[])
+{
+ int i;
+ int num_udis;
+ char **udis;
+ char *capability = NULL;
+ dbus_bool_t is_verbose = FALSE;
+ dbus_bool_t is_version = FALSE;
+ DBusError error;
+ LibHalContext *hal_ctx;
+
+ if (argc <= 1) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ while (1) {
+ int c;
+ int option_index = 0;
+ const char *opt;
+ static struct option long_options[] = {
+ {"capability", 1, NULL, 0},
+ {"verbose", 0, NULL, 0},
+ {"version", 0, NULL, 0},
+ {"help", 0, NULL, 0},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, "",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ opt = long_options[option_index].name;
+
+ if (strcmp (opt, "help") == 0) {
+ usage (argc, argv);
+ return 0;
+ } else if (strcmp (opt, "verbose") == 0) {
+ is_verbose = TRUE;
+ } else if (strcmp (opt, "version") == 0) {
+ is_version = TRUE;
+ } else if (strcmp (opt, "capability") == 0) {
+ capability = strdup (optarg);
+ }
+ break;
+
+ default:
+ usage (argc, argv);
+ return 1;
+ break;
+ }
+ }
+
+ if (is_version) {
+ printf ("hal-find-by-capability " PACKAGE_VERSION "\n");
+ return 0;
+ }
+
+ if (capability == NULL) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+ fprintf (stderr, "error: libhal_ctx_new\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+ fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ if (!libhal_ctx_init (hal_ctx, &error)) {
+ if (dbus_error_is_set(&error)) {
+ fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ fprintf (stderr, "Could not initialise connection to hald.\n"
+ "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+ return 1;
+ }
+
+
+ udis = libhal_find_device_by_capability (hal_ctx, capability, &num_udis, &error);
+
+ if (dbus_error_is_set (&error)) {
+ fprintf (stderr, "error: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+
+ if (is_verbose)
+ printf ("Found %d device objects of capability '%s'\n", num_udis, capability);
+
+ if (num_udis == 0) {
+ return 1;
+ }
+
+ for (i = 0; i < num_udis; i++) {
+ printf ("%s\n", udis[i]);
+ }
+
+ libhal_free_string_array (udis);
+
+ return 0;
+}
+
+/**
+ * @}
+ */
diff --git a/usr/src/cmd/hal/tools/hal_find_by_property.c b/usr/src/cmd/hal/tools/hal_find_by_property.c
new file mode 100644
index 0000000000..09b1b55e94
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal_find_by_property.c
@@ -0,0 +1,193 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal_find_by_property.c : Find hal devices
+ *
+ * Copyright (C) 2005 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <libhal.h>
+
+
+/** Print out program usage.
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ */
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr,
+ "\n"
+ "usage : hal-find-by-property --key <key> --string <value>\n"
+ " [--help] [--verbose] [--version]\n");
+
+/** @todo support other property types a'la hal-[get|set]-property */
+
+ fprintf (stderr,
+ "\n"
+ " --key Key of the property to check\n"
+ " --string String value of property\n"
+ " --verbose Be verbose\n"
+ " --version Show version and exit\n"
+ " --help Show this information and exit\n"
+ "\n"
+ "This program prints the Unique Device Identifiers for HAL device\n"
+ "objects where a given property assumes a given value. On success\n"
+ "the program exists with exit code 0. If there is an error, the\n"
+ "program exits with an exit code different from 0.\n"
+ "\n");
+}
+
+/** Entry point
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ * @return Return code
+ */
+int
+main (int argc, char *argv[])
+{
+ int i;
+ int num_udis;
+ char **udis;
+ char *key = NULL;
+ char *value = NULL;
+ dbus_bool_t is_verbose = FALSE;
+ dbus_bool_t is_version = FALSE;
+ DBusError error;
+ LibHalContext *hal_ctx;
+
+ if (argc <= 1) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ while (1) {
+ int c;
+ int option_index = 0;
+ const char *opt;
+ static struct option long_options[] = {
+ {"key", 1, NULL, 0},
+ {"string", 1, NULL, 0},
+ {"verbose", 0, NULL, 0},
+ {"version", 0, NULL, 0},
+ {"help", 0, NULL, 0},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, "",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ opt = long_options[option_index].name;
+
+ if (strcmp (opt, "help") == 0) {
+ usage (argc, argv);
+ return 0;
+ } else if (strcmp (opt, "verbose") == 0) {
+ is_verbose = TRUE;
+ } else if (strcmp (opt, "version") == 0) {
+ is_version = TRUE;
+ } else if (strcmp (opt, "key") == 0) {
+ key = strdup (optarg);
+ } else if (strcmp (opt, "string") == 0) {
+ value = strdup (optarg);
+ }
+ break;
+
+ default:
+ usage (argc, argv);
+ return 1;
+ break;
+ }
+ }
+
+ if (is_version) {
+ printf ("hal-find-by-property " PACKAGE_VERSION "\n");
+ return 0;
+ }
+
+ if (key == NULL || value == NULL) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+ fprintf (stderr, "error: libhal_ctx_new\n");
+ return 1;
+ }
+ if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+ fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ if (!libhal_ctx_init (hal_ctx, &error)) {
+ if (dbus_error_is_set(&error)) {
+ fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ fprintf (stderr, "Could not initialise connection to hald.\n"
+ "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+ return 1;
+ }
+
+
+ udis = libhal_manager_find_device_string_match (hal_ctx, key, value, &num_udis, &error);
+
+ if (dbus_error_is_set (&error)) {
+ fprintf (stderr, "error: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+
+ if (is_verbose)
+ printf ("Found %d device objects with string property %s = '%s'\n", num_udis, key, value);
+
+ if (num_udis == 0) {
+ return 1;
+ }
+
+ for (i = 0; i < num_udis; i++) {
+ printf ("%s\n", udis[i]);
+ }
+
+ libhal_free_string_array (udis);
+
+ return 0;
+}
+
+/**
+ * @}
+ */
diff --git a/usr/src/cmd/hal/tools/hal_get_property.c b/usr/src/cmd/hal/tools/hal_get_property.c
new file mode 100644
index 0000000000..51459168d9
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal_get_property.c
@@ -0,0 +1,250 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal_get_property.c : Get property for a device
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <libhal.h>
+
+/**
+ * @defgroup HalGetProperty Get HAL device property
+ * @ingroup HalMisc
+ *
+ * @brief A commandline tool getting a property of a device. Uses libhal
+ *
+ * @{
+ */
+
+static LibHalContext *hal_ctx;
+
+/** Print out program usage.
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ */
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr,
+ "\n"
+ "usage : hal-get-property --udi <udi> --key <key> \n"
+ " [--hex] [--help] [--verbose] [--version]\n");
+ fprintf (stderr,
+ "\n"
+ " --udi Unique Device Id\n"
+ " --key Key of the property to get\n"
+ " --hex Show integer values in hex (without leading 0x)\n"
+ " --verbose Be verbose\n"
+ " --version Show version and exit\n"
+ " --help Show this information and exit\n"
+ "\n"
+ "This program retrieves a property from a device. If the property exist\n"
+ "then it is printed on stdout and this program exits with exit code 0.\n"
+ "On error, the program exits with an exit code different from 0\n"
+ "\n");
+}
+
+/** Entry point
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ * @return Return code
+ */
+int
+main (int argc, char *argv[])
+{
+ char *udi = NULL;
+ char *key = NULL;
+ int type;
+ dbus_bool_t is_hex = FALSE;
+ dbus_bool_t is_verbose = FALSE;
+ dbus_bool_t is_version = FALSE;
+ char *str;
+ DBusError error;
+
+ if (argc <= 1) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ while (1) {
+ int c;
+ int option_index = 0;
+ const char *opt;
+ static struct option long_options[] = {
+ {"udi", 1, NULL, 0},
+ {"key", 1, NULL, 0},
+ {"hex", 0, NULL, 0},
+ {"verbose", 0, NULL, 0},
+ {"version", 0, NULL, 0},
+ {"help", 0, NULL, 0},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, "",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ opt = long_options[option_index].name;
+
+ if (strcmp (opt, "help") == 0) {
+ usage (argc, argv);
+ return 0;
+ } else if (strcmp (opt, "hex") == 0) {
+ is_hex = TRUE;
+ } else if (strcmp (opt, "verbose") == 0) {
+ is_verbose = TRUE;
+ } else if (strcmp (opt, "version") == 0) {
+ is_version = TRUE;
+ } else if (strcmp (opt, "key") == 0) {
+ key = strdup (optarg);
+ } else if (strcmp (opt, "udi") == 0) {
+ udi = strdup (optarg);
+ }
+ break;
+
+ default:
+ usage (argc, argv);
+ return 1;
+ break;
+ }
+ }
+
+ if (is_version) {
+ printf ("hal-get-property " PACKAGE_VERSION "\n");
+ return 0;
+ }
+
+ if (udi == NULL || key == NULL) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+ fprintf (stderr, "error: libhal_ctx_new\n");
+ return 1;
+ }
+ if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+ fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ if (!libhal_ctx_init (hal_ctx, &error)) {
+ if (dbus_error_is_set(&error)) {
+ fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ fprintf (stderr, "Could not initialise connection to hald.\n"
+ "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+ return 1;
+ }
+
+ type = libhal_device_get_property_type (hal_ctx, udi, key, &error);
+ if (type == LIBHAL_PROPERTY_TYPE_INVALID) {
+ fprintf (stderr, "error: libhal_device_get_property_type: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ /* emit the value to stdout */
+ switch (type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ str = libhal_device_get_property_string (hal_ctx, udi, key, &error);
+ if (is_verbose)
+ printf ("Type is string\n");
+ printf ("%s\n", str);
+ libhal_free_string (str);
+ break;
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ if (is_verbose)
+ printf ("Type is integer (shown in %s)\n",
+ (is_hex ? "hexadecimal" : "decimal"));
+ printf ((is_hex ? "%x\n" : "%d\n"),
+ libhal_device_get_property_int (hal_ctx, udi, key, &error));
+ break;
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ if (is_verbose)
+ printf ("Type is uint64 (shown in %s)\n",
+ (is_hex ? "hexadecimal" : "decimal"));
+ printf ((is_hex ? "%llx\n" : "%llu\n"),
+ (long long unsigned int) libhal_device_get_property_uint64 (hal_ctx, udi, key, &error));
+ break;
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ if (is_verbose)
+ printf ("Type is double\n");
+ printf ("%f\n",
+ libhal_device_get_property_double (hal_ctx, udi, key, &error));
+ break;
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ if (is_verbose)
+ printf ("Type is boolean\n");
+ printf ("%s\n",
+ libhal_device_get_property_bool (hal_ctx, udi, key, &error) ? "true" : "false");
+ break;
+
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ {
+ unsigned int i;
+ char **strlist;
+
+ if ((strlist = libhal_device_get_property_strlist (hal_ctx, udi, key, &error)) != NULL) {
+
+ for (i = 0; strlist[i] != 0; i++) {
+ printf ("%s", strlist[i]);
+ if (strlist[i+1] != NULL)
+ printf (" ");
+ }
+ }
+ break;
+ }
+ default:
+ printf ("Unknown type %d='%c'\n", type, type);
+ return 1;
+ break;
+ }
+
+ if (dbus_error_is_set (&error)) {
+ fprintf (stderr, "error: %s: %s\n", error.name, error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+
+
+ return 0;
+}
+
+/**
+ * @}
+ */
diff --git a/usr/src/cmd/hal/tools/hal_set_property.c b/usr/src/cmd/hal/tools/hal_set_property.c
new file mode 100644
index 0000000000..78f24ee8fc
--- /dev/null
+++ b/usr/src/cmd/hal/tools/hal_set_property.c
@@ -0,0 +1,288 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal_set_property.c : Set property for a device
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <libhal.h>
+
+static LibHalContext *hal_ctx;
+
+enum property_op {
+ PROP_INT,
+ PROP_UINT64,
+ PROP_STRING,
+ PROP_DOUBLE,
+ PROP_BOOL,
+ PROP_STRLIST_PRE,
+ PROP_STRLIST_POST,
+ PROP_STRLIST_REM,
+ PROP_INVALID
+};
+
+/**
+ * @defgroup HalSetProperty Set HAL device property
+ * @ingroup HalMisc
+ *
+ * @brief A commandline tool setting a property of a device. Uses libhal
+ *
+ * @{
+ */
+
+/** Print out program usage.
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ */
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr,
+ "\n"
+ "usage : hal-set-property --udi <udi> --key <key>\n"
+ " (--int <value> | --string <value> | --bool <value> |\n"
+ " --strlist-pre <value> | --strlist-post <value> |\n"
+ " --strlist-rem <value> | --double <value> | --remove)\n"
+ " [--help] [--version]\n");
+ fprintf (stderr,
+ "\n" " --udi Unique Device Id\n"
+ " --key Key of the property to set\n"
+ " --int Set value to an integer. Accepts decimal and "
+ " hexadecimal prefixed with 0x or x\n"
+ " --uint64 Set value to an integer. Accepts decimal and "
+ " hexadecimal prefixed with 0x or x\n"
+ " --string Set value to a string\n"
+ " --double Set value to a floating point number\n"
+ " --bool Set value to a boolean, ie. true or false\n"
+ " --strlist-pre Prepend a string to a list\n"
+ " --strlist-post Append a string to a list\n"
+ " --strlist-rem Remove a string from a list\n"
+ " --remove Indicates that the property should be removed\n"
+ " --version Show version and exit\n"
+ " --help Show this information and exit\n"
+ "\n"
+ "This program attempts to set property for a device. Note that, due to\n"
+ "security considerations, it may not be possible to set a property; on\n"
+ "success this program exits with exit code 0. On error, the program exits\n"
+ "with an exit code different from 0\n" "\n");
+}
+
+/** Entry point
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ * @return Return code
+ */
+int
+main (int argc, char *argv[])
+{
+ dbus_bool_t rc = 0;
+ char *udi = NULL;
+ char *key = NULL;
+ char *str_value = NULL;
+ dbus_int32_t int_value = 0;
+ dbus_uint64_t uint64_value = 0;
+ double double_value = 0.0f;
+ dbus_bool_t bool_value = TRUE;
+ dbus_bool_t remove = FALSE;
+ dbus_bool_t is_version = FALSE;
+ int type = PROP_INVALID;
+ DBusError error;
+
+ if (argc <= 1) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ while (1) {
+ int c;
+ int option_index = 0;
+ const char *opt;
+ static struct option long_options[] = {
+ {"udi", 1, NULL, 0},
+ {"key", 1, NULL, 0},
+ {"int", 1, NULL, 0},
+ {"uint64", 1, NULL, 0},
+ {"string", 1, NULL, 0},
+ {"double", 1, NULL, 0},
+ {"bool", 1, NULL, 0},
+ {"strlist-pre", 1, NULL, 0},
+ {"strlist-post", 1, NULL, 0},
+ {"strlist-rem", 1, NULL, 0},
+ {"remove", 0, NULL, 0},
+ {"version", 0, NULL, 0},
+ {"help", 0, NULL, 0},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, "",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ opt = long_options[option_index].name;
+
+ if (strcmp (opt, "help") == 0) {
+ usage (argc, argv);
+ return 0;
+ } else if (strcmp (opt, "key") == 0) {
+ key = strdup (optarg);
+ } else if (strcmp (opt, "string") == 0) {
+ str_value = strdup (optarg);
+ type = PROP_STRING;
+ } else if (strcmp (opt, "int") == 0) {
+ int_value = strtol (optarg, NULL, 0);
+ type = PROP_INT;
+ } else if (strcmp (opt, "uint64") == 0) {
+ uint64_value = strtoull (optarg, NULL, 0);
+ type = PROP_UINT64;
+ } else if (strcmp (opt, "double") == 0) {
+ double_value = (double) atof (optarg);
+ type = PROP_DOUBLE;
+ } else if (strcmp (opt, "bool") == 0) {
+ if (strcmp (optarg, "true") == 0)
+ bool_value = TRUE;
+ else if (strcmp (optarg, "false") == 0)
+ bool_value = FALSE;
+ else {
+ usage (argc, argv);
+ return 1;
+ }
+ type = PROP_BOOL;
+ } else if (strcmp (opt, "strlist-pre") == 0) {
+ str_value = strdup (optarg);
+ type = PROP_STRLIST_PRE;
+ } else if (strcmp (opt, "strlist-post") == 0) {
+ str_value = strdup (optarg);
+ type = PROP_STRLIST_POST;
+ } else if (strcmp (opt, "strlist-rem") == 0) {
+ str_value = strdup (optarg);
+ type = PROP_STRLIST_REM;
+ } else if (strcmp (opt, "remove") == 0) {
+ remove = TRUE;
+ } else if (strcmp (opt, "udi") == 0) {
+ udi = strdup (optarg);
+ } else if (strcmp (opt, "version") == 0) {
+ is_version = TRUE;
+ }
+ break;
+
+ default:
+ usage (argc, argv);
+ return 1;
+ break;
+ }
+ }
+
+ if (is_version) {
+ printf ("hal-set-property " PACKAGE_VERSION "\n");
+ return 0;
+ }
+
+ /* must have at least one, but not neither or both */
+ if ((remove && type != PROP_INVALID) || ((!remove) && type == PROP_INVALID)) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ fprintf (stderr, "\n");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+ fprintf (stderr, "error: libhal_ctx_new\n");
+ return 1;
+ }
+ if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+ fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ if (!libhal_ctx_init (hal_ctx, &error)) {
+ if (dbus_error_is_set(&error)) {
+ fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ fprintf (stderr, "Could not initialise connection to hald.\n"
+ "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+ return 1;
+ }
+
+ if (remove) {
+ rc = libhal_device_remove_property (hal_ctx, udi, key, &error);
+ if (!rc) {
+ fprintf (stderr, "error: libhal_device_remove_property: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ } else {
+ switch (type) {
+ case PROP_STRING:
+ rc = libhal_device_set_property_string (hal_ctx, udi, key, str_value, &error);
+ break;
+ case PROP_INT:
+ rc = libhal_device_set_property_int (hal_ctx, udi, key, int_value, &error);
+ break;
+ case PROP_UINT64:
+ rc = libhal_device_set_property_uint64 (hal_ctx, udi, key, uint64_value, &error);
+ break;
+ case PROP_DOUBLE:
+ rc = libhal_device_set_property_double (hal_ctx, udi, key, double_value, &error);
+ break;
+ case PROP_BOOL:
+ rc = libhal_device_set_property_bool (hal_ctx, udi, key, bool_value, &error);
+ break;
+ case PROP_STRLIST_PRE:
+ rc = libhal_device_property_strlist_prepend (hal_ctx, udi, key, str_value, &error);
+ break;
+ case PROP_STRLIST_POST:
+ rc = libhal_device_property_strlist_append (hal_ctx, udi, key, str_value, &error);
+ break;
+ case PROP_STRLIST_REM:
+ rc = libhal_device_property_strlist_remove (hal_ctx, udi, key, str_value, &error);
+ break;
+ }
+ if (!rc) {
+ fprintf (stderr, "error: libhal_device_set_property: %s: %s\n", error.name, error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+ }
+
+ return rc ? 0 : 1;
+}
+
+/**
+ * @}
+ */
diff --git a/usr/src/cmd/hal/tools/lshal.c b/usr/src/cmd/hal/tools/lshal.c
new file mode 100644
index 0000000000..c072858b87
--- /dev/null
+++ b/usr/src/cmd/hal/tools/lshal.c
@@ -0,0 +1,737 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * lshal.c : Show devices managed by HAL
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2005 Pierre Ossman, <drzeus@drzeus.cx>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+#include <libhal.h>
+
+#ifdef __SUNPRO_C
+#define __FUNCTION__ __func__
+#endif
+
+/**
+ * @defgroup HalLsHal List HAL devices
+ * @ingroup HalMisc
+ *
+ * @brief A commandline tool, lshal, for displaying and, optionally,
+ * monitor the devices managed by the HAL daemon. Uses libhal.
+ *
+ * @{
+ */
+
+/** Macro for terminating the program on an unrecoverable error */
+#define DIE(expr) do {printf("*** [DIE] %s:%s():%d : ", __FILE__, __FUNCTION__, __LINE__); printf expr; printf("\n"); exit(1); } while(0)
+
+#define UDI_BASE "/org/freedesktop/Hal/devices/"
+
+static LibHalContext *hal_ctx;
+static dbus_bool_t long_list = FALSE;
+static dbus_bool_t tree_view = FALSE;
+static dbus_bool_t short_list = FALSE;
+static char *show_device = NULL;
+
+struct Device {
+ char *name;
+ char *parent;
+};
+
+/** Generate a short name for a device
+ *
+ * @param udi Universal Device Id
+ */
+static const char *
+short_name (const char *udi)
+{
+ return &udi[sizeof(UDI_BASE) - 1];
+}
+
+/** Print all properties of a device
+ *
+ * @param udi Universal Device Id
+ */
+
+static void
+print_props (const char *udi)
+{
+ DBusError error;
+ LibHalPropertySet *props;
+ LibHalPropertySetIterator it;
+ int type;
+
+ dbus_error_init (&error);
+
+ props = libhal_device_get_all_properties (hal_ctx, udi, &error);
+
+ /* NOTE : This may be NULL if the device was removed
+ * in the daemon; this is because
+ * hal_device_get_all_properties() is a in
+ * essence an IPC call and other stuff may
+ * be happening..
+ */
+ if (props == NULL) {
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return;
+ }
+
+ for (libhal_psi_init (&it, props); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
+ type = libhal_psi_get_type (&it);
+ switch (type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ printf (" %s = '%s' (string)\n",
+ libhal_psi_get_key (&it),
+ libhal_psi_get_string (&it));
+ break;
+
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ printf (" %s = %d (0x%x) (int)\n",
+ libhal_psi_get_key (&it),
+ libhal_psi_get_int (&it),
+ libhal_psi_get_int (&it));
+ break;
+
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ printf (" %s = %llu (0x%llx) (uint64)\n",
+ libhal_psi_get_key (&it),
+ (long long unsigned int) libhal_psi_get_uint64 (&it),
+ (long long unsigned int) libhal_psi_get_uint64 (&it));
+ break;
+
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ printf (" %s = %g (double)\n",
+ libhal_psi_get_key (&it),
+ libhal_psi_get_double (&it));
+ break;
+
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ printf (" %s = %s (bool)\n",
+ libhal_psi_get_key (&it),
+ libhal_psi_get_bool (&it) ? "true" :
+ "false");
+ break;
+
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ {
+ unsigned int i;
+ char **strlist;
+
+ printf (" %s = {", libhal_psi_get_key (&it));
+
+ strlist = libhal_psi_get_strlist (&it);
+ for (i = 0; strlist[i] != 0; i++) {
+ printf ("'%s'", strlist[i]);
+ if (strlist[i+1] != NULL)
+ printf (", ");
+ }
+ printf ("} (string list)\n");
+ break;
+ }
+
+ default:
+ printf ("Unknown type %d=0x%02x\n", type, type);
+ break;
+ }
+ }
+
+ libhal_free_property_set (props);
+}
+
+/** Dumps information about a single device
+ *
+ * @param udi Universal Device Id
+ */
+
+static void
+dump_device (const char *udi)
+{
+ DBusError error;
+
+ dbus_error_init (&error);
+
+ if (!libhal_device_exists (hal_ctx, udi, &error)) {
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return;
+ }
+
+ if (long_list) {
+ printf ("udi = '%s'\n", udi);
+
+ print_props (udi);
+ printf ("\n");
+ }
+ else
+ printf ("%s\n", short_name (udi));
+}
+
+/** Dump all children of device
+ *
+ * @param udi Universal Device Id of parent
+ * @param num_devices Total number of devices in device list
+ * @param devices List of devices
+ * @param depth Current recursion depth
+ */
+
+static void
+dump_children (char *udi, int num_devices, struct Device *devices, int depth)
+{
+ int i;
+
+ for (i = 0; i < num_devices; i++) {
+ if (!udi) {
+ if (devices[i].parent)
+ continue;
+ }
+ else {
+ if (!devices[i].parent)
+ continue;
+ if (strcmp (devices[i].parent, udi))
+ continue;
+ }
+
+ if (long_list)
+ printf ("udi = '%s'\n", devices[i].name);
+ else {
+ int j;
+ if (tree_view) {
+ for (j = 0;j < depth;j++)
+ printf(" ");
+ }
+ printf ("%s\n", short_name (devices[i].name));
+ }
+
+ if (long_list) {
+ print_props (devices[i].name);
+ printf ("\n");
+ }
+
+ dump_children(devices[i].name, num_devices, devices, depth + 1);
+ }
+}
+
+/** Dump all devices to stdout
+ *
+ */
+static void
+dump_devices (void)
+{
+ int i;
+ int num_devices;
+ char **device_names;
+ struct Device *devices;
+ DBusError error;
+
+ dbus_error_init (&error);
+
+ device_names = libhal_get_all_devices (hal_ctx, &num_devices, &error);
+ if (device_names == NULL) {
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ DIE (("Couldn't obtain list of devices\n"));
+ }
+
+ devices = malloc (sizeof(struct Device) * num_devices);
+ if (!devices) {
+ libhal_free_string_array (device_names);
+ return;
+ }
+
+ for (i = 0;i < num_devices;i++) {
+ devices[i].name = device_names[i];
+ devices[i].parent = libhal_device_get_property_string (hal_ctx,
+ device_names[i], "info.parent", &error);
+
+ if (dbus_error_is_set (&error)) {
+ /* Free the error (which include a dbus_error_init())
+ This should prevent errors if a call above fails */
+ dbus_error_free (&error);
+ }
+ }
+
+ if (long_list) {
+ printf ("\n"
+ "Dumping %d device(s) from the Global Device List:\n"
+ "-------------------------------------------------\n",
+ num_devices);
+ }
+
+ dump_children(NULL, num_devices, devices, 0);
+
+ for (i = 0;i < num_devices;i++) {
+ if (devices[i].parent)
+ libhal_free_string (devices[i].parent);
+ }
+
+ free (devices);
+ libhal_free_string_array (device_names);
+
+ if (long_list) {
+ printf ("\n"
+ "Dumped %d device(s) from the Global Device List.\n"
+ "------------------------------------------------\n",
+ num_devices);
+
+ printf ("\n");
+ }
+}
+
+/** Invoked when a device is added to the Global Device List. Simply prints
+ * a message on stdout.
+ *
+ * @param udi Universal Device Id
+ */
+static void
+device_added (LibHalContext *ctx,
+ const char *udi)
+{
+ if (show_device && strcmp(show_device, udi))
+ return;
+
+ if (long_list) {
+ printf ("*** lshal: device_added, udi='%s'\n", udi);
+ print_props (udi);
+ } else
+ printf ("%s added\n", short_name (udi));
+}
+
+/** Invoked when a device is removed from the Global Device List. Simply
+ * prints a message on stdout.
+ *
+ * @param udi Universal Device Id
+ */
+static void
+device_removed (LibHalContext *ctx,
+ const char *udi)
+{
+ if (show_device && strcmp(show_device, udi))
+ return;
+
+ if (long_list)
+ printf ("*** lshal: device_removed, udi='%s'\n", udi);
+ else
+ printf ("%s removed\n", short_name (udi));
+}
+
+/** Invoked when device in the Global Device List acquires a new capability.
+ * Prints the name of the capability to stdout.
+ *
+ * @param udi Universal Device Id
+ * @param capability Name of capability
+ */
+static void
+device_new_capability (LibHalContext *ctx,
+ const char *udi,
+ const char *capability)
+{
+ if (show_device && strcmp(show_device, udi))
+ return;
+
+ if (long_list) {
+ printf ("*** lshal: new_capability, udi='%s'\n", udi);
+ printf ("*** capability: %s\n", capability);
+ } else
+ printf ("%s capability %s added\n", short_name (udi),
+ capability);
+}
+
+/** Invoked when device in the Global Device List loses a capability.
+ * Prints the name of the capability to stdout.
+ *
+ * @param udi Universal Device Id
+ * @param capability Name of capability
+ */
+static void
+device_lost_capability (LibHalContext *ctx,
+ const char *udi,
+ const char *capability)
+{
+ if (show_device && strcmp(show_device, udi))
+ return;
+
+ if (long_list) {
+ printf ("*** lshal: lost_capability, udi='%s'\n", udi);
+ printf ("*** capability: %s\n", capability);
+ } else
+ printf ("%s capability %s lost\n", short_name (udi),
+ capability);
+}
+
+/** Acquires and prints the value of of a property to stdout.
+ *
+ * @param udi Universal Device Id
+ * @param key Key of property
+ */
+static void
+print_property (const char *udi, const char *key)
+{
+ int type;
+ char *str;
+ DBusError error;
+
+ dbus_error_init (&error);
+
+ type = libhal_device_get_property_type (hal_ctx, udi, key, &error);
+
+ switch (type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ str = libhal_device_get_property_string (hal_ctx, udi, key, &error);
+ printf (long_list?"*** new value: '%s' (string)\n":"'%s'", str);
+ libhal_free_string (str);
+ break;
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ {
+ dbus_int32_t value = libhal_device_get_property_int (hal_ctx, udi, key, &error);
+ printf (long_list?"*** new value: %d (0x%x) (int)\n":"%d (0x%x)",
+ value, value);
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ {
+ dbus_uint64_t value = libhal_device_get_property_uint64 (hal_ctx, udi, key, &error);
+ printf (long_list?"*** new value: %llu (0x%llx) (uint64)\n":"%llu (0x%llx)",
+ (long long unsigned int) value, (long long unsigned int) value);
+ }
+ break;
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ printf (long_list?"*** new value: %g (double)\n":"%g",
+ libhal_device_get_property_double (hal_ctx, udi, key, &error));
+ break;
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ printf (long_list?"*** new value: %s (bool)\n":"%s",
+ libhal_device_get_property_bool (hal_ctx, udi, key, &error) ? "true" : "false");
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ {
+ unsigned int i;
+ char **strlist;
+
+ if (long_list)
+ printf ("*** new value: {");
+ else
+ printf ("{");
+
+ strlist = libhal_device_get_property_strlist (hal_ctx, udi, key, &error);
+ for (i = 0; strlist[i] != 0; i++) {
+ printf ("'%s'", strlist[i]);
+ if (strlist[i+1] != NULL)
+ printf (", ");
+ }
+ if (long_list)
+ printf ("} (string list)\n");
+ else
+ printf ("}");
+ libhal_free_string_array (strlist);
+ break;
+ }
+
+ default:
+ fprintf (stderr, "Unknown type %d='%c'\n", type, type);
+ break;
+ }
+
+ if (dbus_error_is_set (&error))
+ dbus_error_free (&error);
+}
+
+/** Invoked when a property of a device in the Global Device List is
+ * changed, and we have we have subscribed to changes for that device.
+ *
+ * @param udi Univerisal Device Id
+ * @param key Key of property
+ */
+static void
+property_modified (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ dbus_bool_t is_removed,
+ dbus_bool_t is_added)
+{
+ if (show_device && strcmp(show_device, udi))
+ return;
+
+ if (long_list) {
+ printf ("*** lshal: property_modified, udi=%s, key=%s\n",
+ udi, key);
+ printf (" is_removed=%s, is_added=%s\n",
+ is_removed ? "true" : "false",
+ is_added ? "true" : "false");
+ if (!is_removed)
+ print_property (udi, key);
+ printf ("\n");
+ } else {
+ printf ("%s property %s ", short_name (udi), key);
+ if (is_removed)
+ printf ("removed");
+ else {
+ printf ("= ");
+ print_property (udi, key);
+
+ if (is_added)
+ printf (" (new)");
+ }
+ printf ("\n");
+ }
+}
+
+
+/** Invoked when a property of a device in the Global Device List is
+ * changed, and we have we have subscribed to changes for that device.
+ *
+ * @param udi Univerisal Device Id
+ * @param condition_name Name of condition
+ * @param message D-BUS message with parameters
+ */
+static void
+device_condition (LibHalContext *ctx,
+ const char *udi,
+ const char *condition_name,
+ const char *condition_details)
+{
+ if (show_device && strcmp(show_device, udi))
+ return;
+
+ if (long_list) {
+ printf ("*** lshal: device_condition, udi=%s\n", udi);
+ printf (" condition_name=%s\n", condition_name);
+ printf (" condition_details=%s\n", condition_details);
+ printf ("\n");
+ } else {
+ printf ("%s condition %s = %s\n", short_name (udi),
+ condition_name, condition_details);
+ }
+}
+
+
+/** Print out program usage.
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ */
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr, "lshal version " PACKAGE_VERSION "\n");
+
+ fprintf (stderr, "\n" "usage : %s [options]\n", argv[0]);
+ fprintf (stderr,
+ "\n"
+ "Options:\n"
+ " -m, --monitor Monitor device list\n"
+ " -s, --short short output (print only nonstatic part of udi)\n"
+ " -l, --long Long output\n"
+ " -t, --tree Tree view\n"
+ " -u, --show <udi> Show only the specified device\n"
+ "\n"
+ " -h, --help Show this information and exit\n"
+ " -V, --version Print version number\n"
+ "\n"
+ "Without any given options lshal will start with option --long."
+ "\n"
+ "Shows all devices and their properties. If the --monitor option is given\n"
+ "then the device list and all devices are monitored for changes.\n"
+ "\n");
+}
+
+/** Entry point
+ *
+ * @param argc Number of arguments given to program
+ * @param argv Arguments given to program
+ * @return Return code
+ */
+int
+main (int argc, char *argv[])
+{
+ DBusError error;
+ dbus_bool_t do_monitor = FALSE;
+ GMainLoop *loop;
+ DBusConnection *conn;
+
+ if (argc == 1) {
+ /* This is the default case lshal without any options */
+ long_list = TRUE;
+ }
+ else {
+ static const struct option long_options[] = {
+ {"monitor", no_argument, NULL, 'm'},
+ {"long", no_argument, NULL, 'l'},
+ {"short", no_argument, NULL, 's'},
+ {"tree", no_argument, NULL, 't'},
+ {"show", required_argument, NULL, 'u'},
+ {"help", no_argument, NULL, 'h'},
+ {"usage", no_argument, NULL, 'U'},
+ {"version", no_argument, NULL, 'V'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while (1) {
+ int c;
+
+ c = getopt_long (argc, argv, "mlstu:hUV", long_options, NULL);
+
+ if (c == -1) {
+ /* this should happen e.g. if 'lshal -' and this is incorrect/incomplete option */
+ if (!do_monitor && !long_list && !short_list && !tree_view && !show_device) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ break;
+ }
+
+ switch (c) {
+ case 'm':
+ do_monitor = TRUE;
+ break;
+
+ case 'l':
+ long_list = TRUE;
+ break;
+
+ case 's':
+ short_list = TRUE;
+ long_list = FALSE;
+ break;
+
+ case 't':
+ tree_view = TRUE;
+ break;
+
+ case 'u':
+ if (strchr(optarg, '/') != NULL)
+ show_device = strdup(optarg);
+ else {
+ show_device = malloc(strlen(UDI_BASE) + strlen(optarg) + 1);
+ memcpy(show_device, UDI_BASE, strlen(UDI_BASE));
+ memcpy(show_device + strlen(UDI_BASE), optarg, strlen(optarg) + 1);
+ }
+
+ break;
+
+ case 'h':
+ case 'U':
+ usage (argc, argv);
+ return 0;
+
+ case 'V':
+ printf ("lshal version " PACKAGE_VERSION "\n");
+ return 0;
+
+ default:
+ usage (argc, argv);
+ return 1;
+ }
+ }
+ }
+
+ if (do_monitor)
+ loop = g_main_loop_new (NULL, FALSE);
+ else
+ loop = NULL;
+
+ dbus_error_init (&error);
+ conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (conn == NULL) {
+ fprintf (stderr, "error: dbus_bus_get: %s: %s\n",
+ error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+
+ if (do_monitor)
+ dbus_connection_setup_with_g_main (conn, NULL);
+
+ if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+ fprintf (stderr, "error: libhal_ctx_new\n");
+ return 1;
+ }
+ if (!libhal_ctx_set_dbus_connection (hal_ctx, conn)) {
+ fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n",
+ error.name, error.message);
+ return 1;
+ }
+ if (!libhal_ctx_init (hal_ctx, &error)) {
+ if (dbus_error_is_set(&error)) {
+ fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ }
+ fprintf (stderr, "Could not initialise connection to hald.\n"
+ "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+ return 1;
+ }
+
+ libhal_ctx_set_device_added (hal_ctx, device_added);
+ libhal_ctx_set_device_removed (hal_ctx, device_removed);
+ libhal_ctx_set_device_new_capability (hal_ctx, device_new_capability);
+ libhal_ctx_set_device_lost_capability (hal_ctx, device_lost_capability);
+ libhal_ctx_set_device_property_modified (hal_ctx, property_modified);
+ libhal_ctx_set_device_condition (hal_ctx, device_condition);
+
+ if (show_device)
+ dump_device (show_device);
+ else if (!do_monitor)
+ dump_devices ();
+
+ /* run the main loop only if we should monitor */
+ if (do_monitor && loop != NULL) {
+ if( long_list || short_list || tree_view )
+ dump_devices ();
+
+ if ( libhal_device_property_watch_all (hal_ctx, &error) == FALSE) {
+ fprintf (stderr, "error: monitoring devicelist - libhal_device_property_watch_all: %s: %s\n",
+ error.name, error.message);
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ return 1;
+ }
+ printf ("\nStart monitoring devicelist:\n"
+ "-------------------------------------------------\n");
+ g_main_loop_run (loop);
+ }
+
+ if ( libhal_ctx_shutdown (hal_ctx, &error) == FALSE)
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ libhal_ctx_free (hal_ctx);
+
+ dbus_connection_close (conn);
+ dbus_connection_unref (conn);
+
+ if (show_device)
+ free(show_device);
+
+ return 0;
+}
+
+/**
+ * @}
+ */
diff --git a/usr/src/cmd/hal/utils/cdutils.c b/usr/src/cmd/hal/utils/cdutils.c
new file mode 100644
index 0000000000..804ee0ffda
--- /dev/null
+++ b/usr/src/cmd/hal/utils/cdutils.c
@@ -0,0 +1,484 @@
+/***************************************************************************
+ *
+ * cdutils.h : CD/DVD utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/scsi/impl/uscsi.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/dkio.h>
+#include <libintl.h>
+
+#include <logger.h>
+
+#include "cdutils.h"
+
+#define RQLEN 32
+#define SENSE_KEY(rqbuf) (rqbuf[2]) /* scsi error category */
+#define ASC(rqbuf) (rqbuf[12]) /* additional sense code */
+#define ASCQ(rqbuf) (rqbuf[13]) /* ASC qualifier */
+
+#define GET16(a) (((a)[0] << 8) | (a)[1])
+#define GET32(a) (((a)[0] << 24) | ((a)[1] << 16) | ((a)[2] << 8) | (a)[3])
+
+#define CD_USCSI_TIMEOUT 60
+
+void
+uscsi_cmd_init(struct uscsi_cmd *scmd, char *cdb, int cdblen)
+{
+ bzero(scmd, sizeof (*scmd));
+ bzero(cdb, cdblen);
+ scmd->uscsi_cdb = cdb;
+}
+
+int
+uscsi(int fd, struct uscsi_cmd *scmd)
+{
+ char rqbuf[RQLEN];
+ int ret;
+ int i, retries, total_retries;
+ int max_retries = 20;
+
+ scmd->uscsi_flags |= USCSI_RQENABLE;
+ scmd->uscsi_rqlen = RQLEN;
+ scmd->uscsi_rqbuf = rqbuf;
+
+ for (retries = 0; retries < max_retries; retries++) {
+ scmd->uscsi_status = 0;
+ memset(rqbuf, 0, RQLEN);
+
+ ret = ioctl(fd, USCSICMD, scmd);
+
+ if ((ret == 0) && (scmd->uscsi_status == 2)) {
+ ret = -1;
+ errno = EIO;
+ }
+ if ((ret < 0) && (scmd->uscsi_status == 2)) {
+ /*
+ * The drive is not ready to recieve commands but
+ * may be in the process of becoming ready.
+ * sleep for a short time then retry command.
+ * SENSE/ASC = 2/4 : not ready
+ * ASCQ = 0 Not Reportable.
+ * ASCQ = 1 Becoming ready.
+ * ASCQ = 4 FORMAT in progress.
+ * ASCQ = 7 Operation in progress.
+ */
+ if ((SENSE_KEY(rqbuf) == 2) && (ASC(rqbuf) == 4) &&
+ ((ASCQ(rqbuf) == 0) || (ASCQ(rqbuf) == 1) ||
+ (ASCQ(rqbuf) == 4)) || (ASCQ(rqbuf) == 7)) {
+ total_retries++;
+ sleep(1);
+ continue;
+ }
+
+ /*
+ * Device is not ready to transmit or a device reset
+ * has occurred. wait for a short period of time then
+ * retry the command.
+ */
+ if ((SENSE_KEY(rqbuf) == 6) && ((ASC(rqbuf) == 0x28) ||
+ (ASC(rqbuf) == 0x29))) {
+ sleep(1);
+ total_retries++;
+ continue;
+ }
+ /*
+ * Blank Sense, we don't know what the error is or if
+ * the command succeeded, Hope for the best. Some
+ * drives return blank sense periodically and will
+ * fail if this is removed.
+ */
+ if ((SENSE_KEY(rqbuf) == 0) && (ASC(rqbuf) == 0) &&
+ (ASCQ(rqbuf) == 0)) {
+ ret = 0;
+ break;
+ }
+
+ HAL_DEBUG (("cmd: 0x%02x ret:%i status:%02x "
+ " sense: %02x ASC: %02x ASCQ:%02x\n",
+ (uchar_t)scmd->uscsi_cdb[0], ret,
+ scmd->uscsi_status,
+ (uchar_t)SENSE_KEY(rqbuf),
+ (uchar_t)ASC(rqbuf), (uchar_t)ASCQ(rqbuf)));
+ }
+
+ break;
+ }
+
+ if (retries) {
+ HAL_DEBUG (("total retries: %d\n", total_retries));
+ }
+
+ return (ret);
+}
+
+int
+mode_sense(int fd, uchar_t pc, int dbd, int page_len, uchar_t *buffer)
+{
+ struct uscsi_cmd scmd;
+ char cdb[16];
+
+ uscsi_cmd_init(&scmd, cdb, sizeof (cdb));
+ scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+ scmd.uscsi_buflen = page_len;
+ scmd.uscsi_bufaddr = (char *)buffer;
+ scmd.uscsi_timeout = CD_USCSI_TIMEOUT;
+ scmd.uscsi_cdblen = 0xa;
+ scmd.uscsi_cdb[0] = 0x5a; /* MODE SENSE 10 */
+ if (dbd) {
+ scmd.uscsi_cdb[1] = 0x8; /* no block descriptors */
+ }
+ scmd.uscsi_cdb[2] = pc;
+ scmd.uscsi_cdb[7] = (page_len >> 8) & 0xff;
+ scmd.uscsi_cdb[8] = page_len & 0xff;
+
+ return (uscsi(fd, &scmd) == 0);
+}
+
+/*
+ * will get the mode page only i.e. will strip off the header.
+ */
+int
+get_mode_page(int fd, int page_no, int pc, int buf_len, uchar_t *buffer, int *plen)
+{
+ int ret;
+ uchar_t byte2;
+ uchar_t buf[256];
+ uint_t header_len, page_len, copy_cnt;
+
+ byte2 = (uchar_t)(((pc << 6) & 0xC0) | (page_no & 0x3f));
+
+ /* Ask 254 bytes only to make our IDE driver happy */
+ if ((ret = mode_sense(fd, byte2, 1, 254, buf)) == 0) {
+ return (0);
+ }
+
+ header_len = 8 + GET16(&buf[6]);
+ page_len = buf[header_len + 1] + 2;
+
+ copy_cnt = (page_len > buf_len) ? buf_len : page_len;
+ (void) memcpy(buffer, &buf[header_len], copy_cnt);
+
+ if (plen) {
+ *plen = page_len;
+ }
+
+ return (1);
+}
+
+/* Get information about the Logical Unit's capabilities */
+int
+get_configuration(int fd, uint16_t feature, int bufsize, uchar_t *buf)
+{
+ struct uscsi_cmd scmd;
+ char cdb[16];
+
+ uscsi_cmd_init(&scmd, cdb, sizeof (cdb));
+ scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+ scmd.uscsi_timeout = CD_USCSI_TIMEOUT;
+ scmd.uscsi_cdb[0] = 0x46; /* GET CONFIGURATION */
+ scmd.uscsi_cdb[1] = 0x2; /* request type */
+ scmd.uscsi_cdb[2] = (feature >> 8) & 0xff; /* starting feature # */
+ scmd.uscsi_cdb[3] = feature & 0xff;
+ scmd.uscsi_cdb[7] = (bufsize >> 8) & 0xff; /* allocation length */
+ scmd.uscsi_cdb[8] = bufsize & 0xff;
+ scmd.uscsi_cdblen = 10;
+ scmd.uscsi_bufaddr = (char *)buf;
+ scmd.uscsi_buflen = bufsize;
+
+ return (uscsi(fd, &scmd) == 0);
+}
+
+boolean_t
+get_current_profile(int fd, int *profile)
+{
+ size_t i;
+ uchar_t smallbuf[4];
+ size_t buflen;
+ uchar_t *bufp;
+ int ret = B_FALSE;
+
+ /* first determine amount of memory needed to hold all profiles */
+ if (get_configuration(fd, 0, 4, &smallbuf[0])) {
+ buflen = GET32(smallbuf) + 4;
+ bufp = (uchar_t *)malloc(buflen);
+
+ /* now get all profiles */
+ if (get_configuration(fd, 0, buflen, bufp)) {
+ *profile = GET16(&bufp[6]);
+ ret = B_TRUE;
+ }
+ free(bufp);
+ }
+
+ return (ret);
+}
+
+void
+walk_profiles(int fd, int (*f)(void *, int, boolean_t), void *arg)
+{
+ size_t i;
+ uint16_t profile, current_profile;
+ uchar_t smallbuf[4];
+ size_t buflen;
+ uchar_t *bufp;
+ int ret;
+
+ /* first determine amount of memory needed to hold all profiles */
+ if (get_configuration(fd, 0, 4, &smallbuf[0])) {
+ buflen = GET32(smallbuf) + 4;
+ bufp = (uchar_t *)malloc(buflen);
+
+ /* now get all profiles */
+ if (get_configuration(fd, 0, buflen, bufp)) {
+ current_profile = GET16(&bufp[6]);
+ for (i = 8 + 4; i < buflen; i += 4) {
+ profile = GET16(&bufp[i]);
+ ret = f(arg, profile, (profile == current_profile));
+ if (ret == CDUTIL_WALK_STOP) {
+ break;
+ }
+ }
+ }
+
+ free(bufp);
+ }
+}
+
+/* retrieve speed list from the Write Speed Performance Descriptor Blocks
+ */
+void
+get_write_speeds(uchar_t *page, int n, intlist_t **speeds, int *n_speeds, intlist_t **speeds_mem)
+{
+ uchar_t *p = page + 2;
+ int i;
+ intlist_t **nextp;
+ intlist_t *current;
+ boolean_t skip;
+
+ *n_speeds = 0;
+ *speeds = NULL;
+ *speeds_mem = (intlist_t *)calloc(n, sizeof (intlist_t));
+ if (*speeds_mem == NULL) {
+ return;
+ }
+
+ for (i = 0; i < n; i++, p += 4) {
+ current = &(*speeds_mem)[i];
+ current->val = GET16(p);
+
+ /* keep the list sorted */
+ skip = B_FALSE;
+ for (nextp = speeds; *nextp != NULL; nextp = &((*nextp)->next)) {
+ if (current->val == (*nextp)->val) {
+ skip = B_TRUE; /* skip duplicates */
+ break;
+ } else if (current->val > (*nextp)->val) {
+ break;
+ }
+ }
+ if (!skip) {
+ current->next = *nextp;
+ *nextp = current;
+ *n_speeds++;
+ }
+ }
+}
+
+void
+get_read_write_speeds(int fd, int *read_speed, int *write_speed,
+ intlist_t **speeds, int *n_speeds, intlist_t **speeds_mem)
+{
+ int page_len;
+ uchar_t p[254];
+ int n; /* number of write speed performance descriptor blocks */
+
+ *read_speed = *write_speed = 0;
+ *speeds = *speeds_mem = NULL;
+
+ if (!get_mode_page(fd, 0x2A, 0, sizeof (p), p, &page_len)) {
+ return;
+ }
+
+ if (page_len > 8) {
+ *read_speed = GET16(&p[8]);
+ }
+ if (page_len > 18) {
+ *write_speed = GET16(&p[18]);
+ }
+ if (page_len < 28) {
+ printf("MMC-2\n");
+ return;
+ } else {
+ printf("MMC-3\n");
+ }
+
+ *write_speed = GET16(&p[28]);
+
+ if (page_len < 30) {
+ return;
+ }
+
+ /* retrieve speed list */
+ n = GET16(&p[30]);
+ n = min(n, (sizeof (p) - 32) / 4);
+
+ get_write_speeds(&p[32], n, speeds, n_speeds, speeds_mem);
+
+ if (*speeds != NULL) {
+ *write_speed = max(*write_speed, (*speeds)[0].val);
+ }
+}
+
+boolean_t
+get_disc_info(int fd, disc_info_t *di)
+{
+ struct uscsi_cmd scmd;
+ char cdb[16];
+ uint8_t buf[32];
+ int bufsize = sizeof (buf);
+
+ bzero(buf, bufsize);
+ uscsi_cmd_init(&scmd, cdb, sizeof (cdb));
+ scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+ scmd.uscsi_timeout = CD_USCSI_TIMEOUT;
+ scmd.uscsi_cdb[0] = 0x51; /* READ DISC INFORMATION */
+ scmd.uscsi_cdb[7] = (bufsize >> 8) & 0xff; /* allocation length */
+ scmd.uscsi_cdb[8] = bufsize & 0xff;
+ scmd.uscsi_cdblen = 10;
+ scmd.uscsi_bufaddr = (char *)buf;
+ scmd.uscsi_buflen = bufsize;
+
+ if ((uscsi(fd, &scmd)) != 0) {
+ return (B_FALSE);
+ }
+
+ di->disc_status = buf[2] & 0x03;
+ di->erasable = buf[2] & 0x10;
+ if ((buf[21] != 0) && (buf[21] != 0xff)) {
+ di->capacity = ((buf[21] * 60) + buf[22]) * 75;
+ } else {
+ di->capacity = 0;
+ }
+
+ return (B_TRUE);
+}
+
+/*
+ * returns current/maximum format capacity in bytes
+ */
+boolean_t
+read_format_capacity(int fd, uint64_t *capacity)
+{
+ struct uscsi_cmd scmd;
+ char cdb[16];
+ uint8_t buf[32];
+ int bufsize = sizeof (buf);
+ uint32_t num_blocks;
+ uint32_t block_len;
+
+ bzero(buf, bufsize);
+ uscsi_cmd_init(&scmd, cdb, sizeof (cdb));
+ scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+ scmd.uscsi_timeout = CD_USCSI_TIMEOUT;
+ scmd.uscsi_cdb[0] = 0x23; /* READ FORMAT CAPACITIRES */
+ scmd.uscsi_cdb[7] = (bufsize >> 8) & 0xff; /* allocation length */
+ scmd.uscsi_cdb[8] = bufsize & 0xff;
+ scmd.uscsi_cdblen = 12;
+ scmd.uscsi_bufaddr = (char *)buf;
+ scmd.uscsi_buflen = bufsize;
+
+ if ((uscsi(fd, &scmd)) != 0) {
+ return (B_FALSE);
+ }
+
+ num_blocks = (uint32_t)(buf[4] << 24) + (buf[5] << 16) + (buf[6] << 8) + buf[7];
+ block_len = (uint32_t)(buf[9] << 16) + (buf[10] << 8) + buf[11];
+ *capacity = (uint64_t)num_blocks * block_len;
+
+ return (B_TRUE);
+}
+
+boolean_t
+get_media_info(int fd, struct dk_minfo *minfop)
+{
+ return (ioctl(fd, DKIOCGMEDIAINFO, minfop) != -1);
+}
+
+/*
+ * given current profile, use the best method for determining
+ * disc capacity (in bytes)
+ */
+boolean_t
+get_disc_capacity_for_profile(int fd, int profile, uint64_t *capacity)
+{
+ struct dk_minfo mi;
+ disc_info_t di;
+ boolean_t ret = B_FALSE;
+
+ switch (profile) {
+ case 0x08: /* CD-ROM */
+ case 0x10: /* DVD-ROM */
+ if (get_media_info(fd, &mi) && (mi.dki_capacity > 1)) {
+ *capacity = mi.dki_capacity * mi.dki_lbsize;
+ ret = B_TRUE;
+ }
+ break;
+ default:
+ if (read_format_capacity(fd, capacity) && (*capacity > 0)) {
+ ret = B_TRUE;
+ } else if (get_disc_info(fd, &di) && (di.capacity > 0)) {
+ if (get_media_info(fd, &mi)) {
+ *capacity = di.capacity * mi.dki_lbsize;
+ ret = B_TRUE;
+ }
+ }
+ }
+
+ return (ret);
+}
+
+boolean_t
+read_toc(int fd, int format, int trackno, int buflen, uchar_t *buf)
+{
+ struct uscsi_cmd scmd;
+ char cdb[16];
+
+ bzero(buf, buflen);
+ uscsi_cmd_init(&scmd, cdb, sizeof (cdb));
+ scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+ scmd.uscsi_timeout = CD_USCSI_TIMEOUT;
+ scmd.uscsi_cdb[0] = 0x43 /* READ_TOC_CMD */;
+ scmd.uscsi_cdb[2] = format & 0xf;
+ scmd.uscsi_cdb[6] = trackno;
+ scmd.uscsi_cdb[8] = buflen & 0xff;
+ scmd.uscsi_cdb[7] = (buflen >> 8) & 0xff;
+ scmd.uscsi_cdblen = 10;
+ scmd.uscsi_bufaddr = (char *)buf;
+ scmd.uscsi_buflen = buflen;
+
+ if ((uscsi(fd, &scmd)) != 0) {
+ return (B_FALSE);
+ }
+
+ return (B_TRUE);
+}
diff --git a/usr/src/cmd/hal/utils/cdutils.h b/usr/src/cmd/hal/utils/cdutils.h
new file mode 100644
index 0000000000..b0add974cb
--- /dev/null
+++ b/usr/src/cmd/hal/utils/cdutils.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *
+ * cdutils.h : definitions for CD/DVD utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef CDUTILS_H
+#define CDUTILS_H
+
+#include <sys/types.h>
+#include <sys/dkio.h>
+#include <sys/cdio.h>
+#include <sys/scsi/impl/uscsi.h>
+
+enum {
+ CDUTIL_WALK_CONTINUE,
+ CDUTIL_WALK_STOP
+};
+
+typedef struct intlist {
+ int val;
+ struct intlist *next;
+} intlist_t;
+
+typedef struct disc_info {
+ int disc_status;
+ int erasable;
+ uint_t capacity;
+} disc_info_t;
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+void uscsi_cmd_init(struct uscsi_cmd *scmd, char *cdb, int cdblen);
+int uscsi(int fd, struct uscsi_cmd *scmd);
+int mode_sense(int fd, uchar_t pc, int dbd, int page_len,
+ uchar_t *buffer);
+int get_mode_page(int fd, int page_no, int pc, int buf_len,
+ uchar_t *buffer, int *plen);
+int get_configuration(int fd, uint16_t feature, int bufsize,
+ uchar_t *buf);
+boolean_t get_current_profile(int fd, int *profile);
+void walk_profiles(int fd, int (*f)(void *, int, boolean_t), void *);
+void get_read_write_speeds(int fd, int *read_speed, int *write_speed,
+ intlist_t **wspeeds, int *n_wspeeds, intlist_t **wspeeds_mem);
+boolean_t get_disc_info(int fd, disc_info_t *);
+boolean_t read_format_capacity(int fd, uint64_t *capacity);
+boolean_t get_media_info(int fd, struct dk_minfo *minfop);
+boolean_t get_disc_capacity_for_profile(int fd, int profile,
+ uint64_t *capacity);
+boolean_t read_toc(int fd, int format, int trackno, int buflen,
+ uchar_t *buf);
+
+#endif /* CDUTILS_H */
diff --git a/usr/src/cmd/hal/utils/fsutils.c b/usr/src/cmd/hal/utils/fsutils.c
new file mode 100644
index 0000000000..5dfada0a37
--- /dev/null
+++ b/usr/src/cmd/hal/utils/fsutils.c
@@ -0,0 +1,250 @@
+/***************************************************************************
+ *
+ * fsutils.c : filesystem utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/scsi/impl/uscsi.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/dkio.h>
+#include <libintl.h>
+#include <sys/dktp/fdisk.h>
+#include <sys/fs/pc_label.h>
+
+#include <libhal.h>
+#include "fsutils.h"
+
+/*
+ * Separates dos notation device spec into device and drive number
+ */
+boolean_t
+dos_to_dev(char *path, char **devpath, int *num)
+{
+ char *p;
+
+ if ((p = strrchr(path, ':')) == NULL) {
+ return (B_FALSE);
+ }
+ if ((*num = atoi(p + 1)) == 0) {
+ return (B_FALSE);
+ }
+ p[0] = '\0';
+ *devpath = strdup(path);
+ p[0] = ':';
+ return (*devpath != NULL);
+}
+
+char *
+get_slice_name (char *devlink)
+{
+ char *part, *slice, *disk;
+ char *s = NULL;
+ char *p;
+
+ if ((p = strstr(devlink, "/lofi/")) != 0) {
+ return (p + sizeof ("/lofi/") - 1);
+ }
+
+ part = strrchr(devlink, 'p');
+ slice = strrchr(devlink, 's');
+ disk = strrchr(devlink, 'd');
+
+ if ((part != NULL) && (part > slice) && (part > disk)) {
+ s = part;
+ } else if ((slice != NULL) && (slice > disk)) {
+ s = slice;
+ } else {
+ s = disk;
+ }
+ if ((s != NULL) && isdigit(s[1])) {
+ return (s);
+ } else {
+ return ("");
+ }
+}
+
+boolean_t
+is_dos_drive(uchar_t type)
+{
+ return ((type == 1) || (type == 4) || (type == 5) || (type == 6) ||
+ ((type >= 8) && (type <= 0xf)));
+}
+
+boolean_t
+is_dos_extended(uchar_t id)
+{
+ return ((id == EXTDOS) || (id == FDISK_EXTLBA));
+}
+
+struct part_find_s {
+ int num;
+ int count;
+ int systid;
+ int r_systid;
+ int r_relsect;
+ int r_numsect;
+};
+
+enum { WALK_CONTINUE, WALK_TERMINATE };
+
+/*
+ * Walk partition tables and invoke a callback for each.
+ */
+static void
+walk_partitions(int fd, int startsec, int (*f)(void *, int, int, int),
+ void *arg)
+{
+ uint32_t buf[1024/4];
+ int bufsize = 1024;
+ struct mboot *mboot = (struct mboot *)&buf[0];
+ struct ipart ipart[FD_NUMPART];
+ int sec = startsec;
+ int lastsec = sec + 1;
+ int relsect;
+ int ext = 0;
+ int systid;
+ boolean_t valid;
+ int i;
+
+ while (sec != lastsec) {
+ if (pread(fd, buf, bufsize, (off_t)sec * 512) != bufsize) {
+ break;
+ }
+ lastsec = sec;
+ if (ltohs(mboot->signature) != MBB_MAGIC) {
+ break;
+ }
+ bcopy(mboot->parts, ipart, FD_NUMPART * sizeof (struct ipart));
+
+ for (i = 0; i < FD_NUMPART; i++) {
+ systid = ipart[i].systid;
+ relsect = sec + ltohi(ipart[i].relsect);
+ if (systid == 0) {
+ continue;
+ }
+ valid = B_TRUE;
+ if (is_dos_extended(systid) && (sec == lastsec)) {
+ sec = startsec + ltohi(ipart[i].relsect);
+ if (ext++ == 0) {
+ relsect = startsec = sec;
+ } else {
+ valid = B_FALSE;
+ }
+ }
+ if (valid && f(arg, ipart[i].systid, relsect,
+ ltohi(ipart[i].numsect)) == WALK_TERMINATE) {
+ return;
+ }
+ }
+ }
+}
+
+static int
+find_dos_drive_cb(void *arg, int systid, int relsect, int numsect)
+{
+ struct part_find_s *p = arg;
+
+ if (is_dos_drive(systid)) {
+ if (++p->count == p->num) {
+ p->r_relsect = relsect;
+ p->r_numsect = numsect;
+ p->r_systid = systid;
+ return (WALK_TERMINATE);
+ }
+ }
+
+ return (WALK_CONTINUE);
+}
+
+/*
+ * Given a dos drive number, return its relative sector number,
+ * number of sectors in partition and the system id.
+ */
+boolean_t
+find_dos_drive(int fd, int num, int *relsect, int *numsect, int *systid)
+{
+ struct part_find_s p = { 0, 0, 0, 0, 0, 0 };
+
+ p.num = num;
+
+ if (num > 0) {
+ walk_partitions(fd, 0, find_dos_drive_cb, &p);
+ if (p.count == num) {
+ *relsect = p.r_relsect;
+ *numsect = p.r_numsect;
+ *systid = p.r_systid;
+ return (B_TRUE);
+ }
+ }
+
+ return (B_FALSE);
+}
+
+static int
+get_num_dos_drives_cb(void *arg, int systid, int relsect, int numsect)
+{
+ if (is_dos_drive(systid)) {
+ (*(int *)arg)++;
+ }
+ return (WALK_CONTINUE);
+}
+
+int
+get_num_dos_drives(int fd)
+{
+ int count = 0;
+
+ walk_partitions(fd, 0, get_num_dos_drives_cb, &count);
+
+ return (count);
+}
+
+/*
+ * Return true if all non-empty slices in vtoc have identical start/size and
+ * are tagged backup/entire disk.
+ */
+boolean_t
+vtoc_one_slice_entire_disk(struct vtoc *vtoc)
+{
+ int i;
+ struct partition *p;
+ daddr_t prev_start;
+ long prev_size;
+
+ for (i = 0; i < vtoc->v_nparts; i++) {
+ p = &vtoc->v_part[i];
+ if (p->p_size == 0) {
+ continue;
+ }
+ if ((p->p_tag != V_BACKUP) && ((p->p_tag != V_UNASSIGNED))) {
+ return (B_FALSE);
+ }
+ if ((i > 0) &&
+ ((p->p_start != prev_start) || (p->p_size != prev_size))) {
+ return (B_FALSE);
+ }
+ prev_start = p->p_start;
+ prev_size = p->p_size;
+ }
+
+ return (B_TRUE);
+}
diff --git a/usr/src/cmd/hal/utils/fsutils.h b/usr/src/cmd/hal/utils/fsutils.h
new file mode 100644
index 0000000000..f6dbd55e9e
--- /dev/null
+++ b/usr/src/cmd/hal/utils/fsutils.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ *
+ * fsutils.h : definitions for filesystem utilities
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef FSUTILS_H
+#define FSUTILS_H
+
+#include <sys/types.h>
+#include <sys/vtoc.h>
+
+boolean_t dos_to_dev(char *path, char **devpath, int *num);
+char *get_slice_name (char *devlink);
+boolean_t is_dos_drive(uchar_t id);
+boolean_t is_dos_extended(uchar_t id);
+boolean_t find_dos_drive(int fd, int num, int *relsect, int *numsect, int *systid);
+int get_num_dos_drives(int fd);
+boolean_t vtoc_one_slice_entire_disk(struct vtoc *vtoc);
+
+#endif /* FSUTILS_H */
diff --git a/usr/src/cmd/hwdata/Makefile b/usr/src/cmd/hwdata/Makefile
new file mode 100644
index 0000000000..a40d65e6a1
--- /dev/null
+++ b/usr/src/cmd/hwdata/Makefile
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.cmd
+
+HWDATA = pci.ids usb.ids
+HWDATADIR = $(ROOT)/usr/share/hwdata
+ROOTHWDATA = $(HWDATA:%=$(HWDATADIR)/%)
+
+$(ROOTHWDATA) := FILEMODE = 444
+$(ROOTHWDATA) := OWNER = root
+$(ROOTHWDATA) := GROUP = bin
+
+all:
+
+install: $(ROOTHWDATA)
+
+$(HWDATADIR)/%: %
+ $(INS.file)
+
+lint check clean clobber:
+
+FRC:
+
diff --git a/usr/src/cmd/hwdata/pci.ids b/usr/src/cmd/hwdata/pci.ids
new file mode 100644
index 0000000000..f8dfd4dd9a
--- /dev/null
+++ b/usr/src/cmd/hwdata/pci.ids
@@ -0,0 +1,12419 @@
+#
+# List of PCI ID's
+#
+# Maintained by Martin Mares <mj@ucw.cz> and other volunteers from the
+# Linux PCI ID's Project at http://pciids.sf.net/.
+#
+# New data are always welcome, especially if accurate. If you have
+# anything to contribute, please follow the instructions at the web site
+# or send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
+#
+# This file can be distributed under either the GNU General Public License
+# (version 2 or higher) or the 3-clause BSD License.
+#
+# Daily snapshot on Fri 2006-08-04 01:05:03
+#
+
+# Vendors, devices and subsystems. Please keep sorted.
+
+# Syntax:
+# vendor vendor_name
+# device device_name <-- single tab
+# subvendor subdevice subsystem_name <-- two tabs
+
+0000 Gammagraphx, Inc.
+001a Ascend Communications, Inc.
+0033 Paradyne corp.
+003d Lockheed Martin-Marietta Corp
+# Real TJN ID is e159, but they got it wrong several times --mj
+0059 Tiger Jet Network Inc. (Wrong ID)
+0070 Hauppauge computer works Inc.
+0071 Nebula Electronics Ltd.
+0095 Silicon Image, Inc. (Wrong ID)
+ 0680 Ultra ATA/133 IDE RAID CONTROLLER CARD
+# Wrong ID used in subsystem ID of the TELES.S0/PCI 2.x ISDN adapter
+00a7 Teles AG (Wrong ID)
+00f5 BFG Technologies, Inc.
+0100 Ncipher Corp Ltd
+0123 General Dynamics
+# 018a is not LevelOne but there is a board misprogrammed
+018a LevelOne
+ 0106 FPC-0106TX misprogrammed [RTL81xx]
+# 021b is not Compaq but there is a board misprogrammed
+021b Compaq Computer Corporation
+ 8139 HNE-300 (RealTek RTL8139c) [iPaq Networking]
+0270 Hauppauge computer works Inc. (Wrong ID)
+0291 Davicom Semiconductor, Inc.
+ 8212 DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40)
+# SpeedStream is Efficient Networks, Inc, a Siemens Company
+02ac SpeedStream
+ 1012 1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
+0315 SK-Electronics Co., Ltd.
+0357 TTTech AG
+ 000a TTP-Monitoring Card V2.0
+0432 SCM Microsystems, Inc.
+ 0001 Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
+045e Microsoft
+ 006e MN-510 802.11b wireless USB paddle
+ 00c2 MN-710 wireless USB paddle
+0482 Kyocera
+04cf Myson Century, Inc
+ 8818 CS8818 USB2.0-to-ATAPI Bridge Controller with Embedded PHY
+050d Belkin
+ 001a FSD7000 802.11g PCI Wireless card
+ 0109 F5U409-CU USB/Serial Portable Adapter
+ 7050 F5D7050 802.11g Wireless USB Adapter
+05e3 CyberDoor
+ 0701 CBD516
+066f Sigmatel Inc.
+ 3410 SMTP3410
+ 3500 SMTP3500
+0675 Dynalink
+ 1700 IS64PH ISDN Adapter
+ 1702 IS64PH ISDN Adapter
+ 1703 ISDN Adapter (PCI Bus, DV, W)
+ 1704 ISDN Adapter (PCI Bus, D, C)
+067b Prolific Technology, Inc.
+ 3507 PL-3507 Hi-Speed USB & IEEE 1394 Combo to IDE Bridge Controller
+# Found on Sapphire Radeon X700 (www.saphiretech.com)
+0721 Sapphire, Inc.
+07e2 ELMEG Communication Systems GmbH
+# Wrong ID used in subsystem ID of VIA USB controllers.
+0925 VIA Technologies, Inc. (Wrong ID)
+09c1 Arris
+ 0704 CM 200E Cable Modem
+0a89 BREA Technologies Inc
+0b0b Rhino Equiment Corp.
+ 0105 Rhino R1T1
+ 0205 Rhino R4FXO
+ 0305 Rhino R4T1
+ 0405 Rhino R8FXX
+ 0505 Rhino R24FXX
+ 0506 Rhino R2T1
+ 0605 Rhino R2T1
+# =
+ 0705 Rhino R24FXS
+0b49 ASCII Corporation
+ 064f Trance Vibrator
+0e11 Compaq Computer Corporation
+ 0001 PCI to EISA Bridge
+ 0002 PCI to ISA Bridge
+ 0046 Smart Array 64xx
+ 0e11 409a Smart Array 641
+ 0e11 409b Smart Array 642
+ 0e11 409c Smart Array 6400
+ 0e11 409d Smart Array 6400 EM
+ 0049 NC7132 Gigabit Upgrade Module
+ 004a NC6136 Gigabit Server Adapter
+ 005a Remote Insight II board - Lights-Out
+ 007c NC7770 1000BaseTX
+ 007d NC6770 1000BaseTX
+ 0085 NC7780 1000BaseTX
+ 00b1 Remote Insight II board - PCI device
+ 00bb NC7760
+ 00ca NC7771
+ 00cb NC7781
+ 00cf NC7772
+ 00d0 NC7782
+ 00d1 NC7783
+ 00e3 NC7761
+ 0508 Netelligent 4/16 Token Ring
+ 1000 Triflex/Pentium Bridge, Model 1000
+ 2000 Triflex/Pentium Bridge, Model 2000
+ 3032 QVision 1280/p
+ 3033 QVision 1280/p
+ 3034 QVision 1280/p
+ 4000 4000 [Triflex]
+ 4030 SMART-2/P
+ 4031 SMART-2SL
+ 4032 Smart Array 3200
+ 4033 Smart Array 3100ES
+ 4034 Smart Array 221
+ 4040 Integrated Array
+ 4048 Compaq Raid LC2
+ 4050 Smart Array 4200
+ 4051 Smart Array 4250ES
+ 4058 Smart Array 431
+ 4070 Smart Array 5300
+ 4080 Smart Array 5i
+ 4082 Smart Array 532
+ 4083 Smart Array 5312
+ 4091 Smart Array 6i
+ 409a Smart Array 641
+ 409b Smart Array 642
+ 409c Smart Array 6400
+ 409d Smart Array 6400 EM
+ 6010 HotPlug PCI Bridge 6010
+ 7020 USB Controller
+ a0ec Fibre Channel Host Controller
+ a0f0 Advanced System Management Controller
+ a0f3 Triflex PCI to ISA Bridge
+ a0f7 PCI Hotplug Controller
+ 8086 002a PCI Hotplug Controller A
+ 8086 002b PCI Hotplug Controller B
+ a0f8 ZFMicro Chipset USB
+ a0fc FibreChannel HBA Tachyon
+ ae10 Smart-2/P RAID Controller
+ 0e11 4030 Smart-2/P Array Controller
+ 0e11 4031 Smart-2SL Array Controller
+ 0e11 4032 Smart Array Controller
+ 0e11 4033 Smart 3100ES Array Controller
+ ae29 MIS-L
+ ae2a MPC
+ ae2b MIS-E
+ ae31 System Management Controller
+ ae32 Netelligent 10/100 TX PCI UTP
+ ae33 Triflex Dual EIDE Controller
+ ae34 Netelligent 10 T PCI UTP
+ ae35 Integrated NetFlex-3/P
+ ae40 Netelligent Dual 10/100 TX PCI UTP
+ ae43 Netelligent Integrated 10/100 TX UTP
+ ae69 CETUS-L
+ ae6c Northstar
+ ae6d NorthStar CPU to PCI Bridge
+ b011 Netelligent 10/100 TX Embedded UTP
+ b012 Netelligent 10 T/2 PCI UTP/Coax
+ b01e NC3120 Fast Ethernet NIC
+ b01f NC3122 Fast Ethernet NIC
+ b02f NC1120 Ethernet NIC
+ b030 Netelligent 10/100 TX UTP
+ b04a 10/100 TX PCI Intel WOL UTP Controller
+ b060 Smart Array 5300 Controller
+ b0c6 NC3161 Fast Ethernet NIC
+ b0c7 NC3160 Fast Ethernet NIC
+ b0d7 NC3121 Fast Ethernet NIC
+ b0dd NC3131 Fast Ethernet NIC
+ b0de NC3132 Fast Ethernet Module
+ b0df NC6132 Gigabit Module
+ b0e0 NC6133 Gigabit Module
+ b0e1 NC3133 Fast Ethernet Module
+ b123 NC6134 Gigabit NIC
+ b134 NC3163 Fast Ethernet NIC
+ b13c NC3162 Fast Ethernet NIC
+ b144 NC3123 Fast Ethernet NIC
+ b163 NC3134 Fast Ethernet NIC
+ b164 NC3165 Fast Ethernet Upgrade Module
+ b178 Smart Array 5i/532
+ 0e11 4080 Smart Array 5i
+ 0e11 4082 Smart Array 532
+ 0e11 4083 Smart Array 5312
+ b1a4 NC7131 Gigabit Server Adapter
+# HP Memory Hot-Plug Controller
+ b200 Memory Hot-Plug Controller
+ b203 Integrated Lights Out Controller
+ b204 Integrated Lights Out Processor
+ f130 NetFlex-3/P ThunderLAN 1.0
+ f150 NetFlex-3/P ThunderLAN 2.3
+0e21 Cowon Systems, Inc.
+0e55 HaSoTec GmbH
+0eac SHF Communication Technologies AG
+# Formerly NCR
+1000 LSI Logic / Symbios Logic
+ 0001 53c810
+ 1000 1000 LSI53C810AE PCI to SCSI I/O Processor
+ 0002 53c820
+ 0003 53c825
+ 1000 1000 LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
+ 0004 53c815
+ 0005 53c810AP
+ 0006 53c860
+ 1000 1000 LSI53C860E PCI to Ultra SCSI I/O Processor
+ 000a 53c1510
+ 0e11 b143 Integrated Dual Channel Wide Ultra2 SCSI Controller
+ 1000 1000 LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
+ 000b 53C896/897
+ 0e11 6004 EOB003 Series SCSI host adapter
+ 1000 1000 LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
+ 1000 1010 LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
+ 1000 1020 LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
+# multifunction PCI card: Dual U2W SCSI, dual 10/100TX, graphics
+ 13e9 1000 6221L-4U
+ 000c 53c895
+ 1000 1010 LSI8951U PCI to Ultra2 SCSI host adapter
+ 1000 1020 LSI8952U PCI to Ultra2 SCSI host adapter
+ 1de1 3906 DC-390U2B SCSI adapter
+ 1de1 3907 DC-390U2W
+ 000d 53c885
+ 000f 53c875
+ 0e11 7004 Embedded Ultra Wide SCSI Controller
+ 1000 1000 LSI53C876/E PCI to Dual Channel SCSI Controller
+ 1000 1010 LSI22801 PCI to Dual Channel Ultra SCSI host adapter
+ 1000 1020 LSI22802 PCI to Dual Channel Ultra SCSI host adapter
+ 1092 8760 FirePort 40 Dual SCSI Controller
+ 1de1 3904 DC390F/U Ultra Wide SCSI Adapter
+ 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ 4c53 1050 CT7 mainboard
+ 0010 53C1510
+ 0e11 4040 Integrated Array Controller
+ 0e11 4048 RAID LC2 Controller
+ 1000 1000 53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
+ 0012 53c895a
+ 1000 1000 LSI53C895A PCI to Ultra2 SCSI Controller
+ 0013 53c875a
+ 1000 1000 LSI53C875A PCI to Ultra SCSI Controller
+ 0020 53c1010 Ultra3 SCSI Adapter
+ 1000 1000 LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
+ 107b 1040 Server Onboard 53C1010-33
+ 1de1 1020 DC-390U3W
+ 0021 53c1010 66MHz Ultra3 SCSI Adapter
+ 1000 1000 LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
+ 1000 1010 Asus TR-DLS onboard 53C1010-66
+ 103c 1330 Ultra160 SCSI [A7059A]
+ 103c 1340 Ultra160 SCSI [A7060A]
+ 124b 1070 PMC-USCSI3
+ 4c53 1080 CT8 mainboard
+ 4c53 1300 P017 mezzanine (32-bit PMC)
+ 4c53 1310 P017 mezzanine (64-bit PMC)
+ 0030 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
+ 0e11 00da ProLiant ML 350
+ 1028 0123 PowerEdge 2600
+ 1028 014a PowerEdge 1750
+ 1028 016c PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
+ 1028 0183 PowerEdge 1800
+ 1028 1010 LSI U320 SCSI Controller
+ 103c 12c5 Ultra320 SCSI [A7173A]
+ 124b 1170 PMC-USCSI320
+ 1734 1052 Primergy RX300 S2
+ 0031 53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
+ 0032 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
+ 1000 1000 LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
+ 0033 1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
+ 0040 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
+ 1000 0033 MegaRAID SCSI 320-2XR
+ 1000 0066 MegaRAID SCSI 320-2XRWS
+ 0041 53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
+ 0050 SAS1064 PCI-X Fusion-MPT SAS
+ 0054 SAS1068 PCI-X Fusion-MPT SAS
+ 0056 SAS1064E PCI-Express Fusion-MPT SAS
+ 0058 SAS1068E PCI-Express Fusion-MPT SAS
+ 005a SAS1066E PCI-Express Fusion-MPT SAS
+ 005c SAS1064A PCI-X Fusion-MPT SAS
+ 005e SAS1066 PCI-X Fusion-MPT SAS
+ 0060 SAS1078 PCI-X Fusion-MPT SAS
+ 0062 SAS1078 PCI-Express Fusion-MPT SAS
+ 1000 0062 SAS1078 PCI-Express Fusion-MPT SAS
+ 008f 53c875J
+ 1092 8000 FirePort 40 SCSI Controller
+ 1092 8760 FirePort 40 Dual SCSI Host Adapter
+ 0407 MegaRAID
+ 1000 0530 MegaRAID 530 SCSI 320-0X RAID Controller
+ 1000 0531 MegaRAID 531 SCSI 320-4X RAID Controller
+ 1000 0532 MegaRAID 532 SCSI 320-2X RAID Controller
+ 1028 0531 PowerEdge Expandable RAID Controller 4/QC
+ 1028 0533 PowerEdge Expandable RAID Controller 4/QC
+ 8086 0530 MegaRAID Intel RAID Controller SRCZCRX
+ 8086 0532 MegaRAID Intel RAID Controller SRCU42X
+ 0408 MegaRAID
+ 1000 0001 MegaRAID SCSI 320-1E RAID Controller
+ 1000 0002 MegaRAID SCSI 320-2E RAID Controller
+ 1025 004d MegaRAID ACER ROMB-2E RAID Controller
+ 1028 0001 PowerEdge RAID Controller PERC4e/SC
+ 1028 0002 PowerEdge RAID Controller PERC4e/DC
+ 1734 1065 FSC MegaRAID PCI Express ROMB
+ 8086 0002 MegaRAID Intel RAID Controller SRCU42E
+ 0409 MegaRAID
+ 1000 3004 MegaRAID SATA 300-4X RAID Controller
+ 1000 3008 MegaRAID SATA 300-8X RAID Controller
+ 8086 3008 MegaRAID RAID Controller SRCS28X
+ 8086 3431 MegaRAID RAID Controller Alief SROMBU42E
+ 8086 3499 MegaRAID RAID Controller Harwich SROMBU42E
+ 0621 FC909 Fibre Channel Adapter
+ 0622 FC929 Fibre Channel Adapter
+ 1000 1020 44929 O Dual Fibre Channel card
+ 0623 FC929 LAN
+ 0624 FC919 Fibre Channel Adapter
+ 0625 FC919 LAN
+ 0626 FC929X Fibre Channel Adapter
+ 1000 1010 7202-XP-LC Dual Fibre Channel card
+ 0627 FC929X LAN
+ 0628 FC919X Fibre Channel Adapter
+ 0629 FC919X LAN
+ 0640 FC949X Fibre Channel Adapter
+ 0642 FC939X Fibre Channel Adapter
+ 0646 FC949ES Fibre Channel Adapter
+ 0701 83C885 NT50 DigitalScape Fast Ethernet
+ 0702 Yellowfin G-NIC gigabit ethernet
+ 1318 0000 PEI100X
+ 0804 SA2010
+ 0805 SA2010ZC
+ 0806 SA2020
+ 0807 SA2020ZC
+ 0901 61C102
+ 1000 63C815
+ 1960 MegaRAID
+ 1000 0518 MegaRAID 518 SCSI 320-2 Controller
+ 1000 0520 MegaRAID 520 SCSI 320-1 Controller
+ 1000 0522 MegaRAID 522 i4 133 RAID Controller
+ 1000 0523 MegaRAID SATA 150-6 RAID Controller
+ 1000 4523 MegaRAID SATA 150-4 RAID Controller
+ 1000 a520 MegaRAID ZCR SCSI 320-0 Controller
+ 1028 0518 MegaRAID 518 DELL PERC 4/DC RAID Controller
+ 1028 0520 MegaRAID 520 DELL PERC 4/SC RAID Controller
+ 1028 0531 PowerEdge Expandable RAID Controller 4/QC
+ 1028 0533 PowerEdge Expandable RAID Controller 4/QC
+ 8086 0520 MegaRAIDRAID Controller SRCU41L
+ 8086 0523 MegaRAID RAID Controller SRCS16
+1001 Kolter Electronic
+ 0010 PCI 1616 Measurement card with 32 digital I/O lines
+ 0011 OPTO-PCI Opto-Isolated digital I/O board
+ 0012 PCI-AD/DA Analogue I/O board
+ 0013 PCI-OPTO-RELAIS Digital I/O board with relay outputs
+ 0014 PCI-Counter/Timer Counter Timer board
+ 0015 PCI-DAC416 Analogue output board
+ 0016 PCI-MFB Analogue I/O board
+ 0017 PROTO-3 PCI Prototyping board
+ 9100 INI-9100/9100W SCSI Host
+1002 ATI Technologies Inc
+ 3150 M24 1P [Radeon Mobility X600]
+ 3152 M22 [Radeon Mobility X300]
+ 3154 M24 1T [FireGL M24 GL]
+ 3e50 RV380 0x3e50 [Radeon X600]
+ 3e54 RV380 0x3e54 [FireGL V3200]
+ 3e70 RV380 [Radeon X600] Secondary
+ 4136 Radeon IGP 320 M
+ 4137 Radeon IGP330/340/350
+ 4144 R300 AD [Radeon 9500 Pro]
+ 4145 R300 AE [Radeon 9700 Pro]
+ 4146 R300 AF [Radeon 9700 Pro]
+ 4147 R300 AG [FireGL Z1/X1]
+ 4148 R350 AH [Radeon 9800]
+ 4149 R350 AI [Radeon 9800]
+ 414a R350 AJ [Radeon 9800]
+ 414b R350 AK [Fire GL X2]
+ 4150 RV350 AP [Radeon 9600]
+ 1002 0002 R9600 Pro primary (Asus OEM for HP)
+ 1002 0003 R9600 Pro secondary (Asus OEM for HP)
+ 1002 4722 All-in-Wonder 2006 AGP Edition
+ 1458 4024 Giga-Byte GV-R96128D Primary
+ 148c 2064 PowerColor R96A-C3N
+ 148c 2066 PowerColor R96A-C3N
+ 174b 7c19 Sapphire Atlantis Radeon 9600 Pro
+ 174b 7c29 GC-R9600PRO Primary [Sapphire]
+ 17ee 2002 Radeon 9600 256Mb Primary
+ 18bc 0101 GC-R9600PRO Primary
+ 4151 RV350 AQ [Radeon 9600]
+ 1043 c004 A9600SE
+ 4152 RV350 AR [Radeon 9600]
+ 1002 0002 Radeon 9600XT
+ 1002 4772 All-in-Wonder 9600 XT
+ 1043 c002 Radeon 9600 XT TVD
+ 1043 c01a A9600XT/TD
+ 174b 7c29 Sapphire Radeon 9600XT
+ 1787 4002 Radeon 9600 XT
+ 4153 RV350 AS [Radeon 9550]
+ 1462 932c 865PE Neo2-V (MS-6788) mainboard
+ 4154 RV350 AT [Fire GL T2]
+ 4155 RV350 AU [Fire GL T2]
+ 4156 RV350 AV [Fire GL T2]
+ 4157 RV350 AW [Fire GL T2]
+ 4158 68800AX [Mach32]
+ 4164 R300 AD [Radeon 9500 Pro] (Secondary)
+ 4165 R300 AE [Radeon 9700 Pro] (Secondary)
+ 4166 R300 AF [Radeon 9700 Pro] (Secondary)
+ 4168 Radeon R350 [Radeon 9800] (Secondary)
+ 4170 RV350 AP [Radeon 9600] (Secondary)
+ 1002 0003 R9600 Pro secondary (Asus OEM for HP)
+ 1002 4723 All-in-Wonder 2006 AGP Edition (Secondary)
+ 1458 4025 Giga-Byte GV-R96128D Secondary
+ 148c 2067 PowerColor R96A-C3N (Secondary)
+ 174b 7c28 GC-R9600PRO Secondary [Sapphire]
+ 17ee 2003 Radeon 9600 256Mb Secondary
+ 18bc 0100 GC-R9600PRO Secondary
+ 4171 RV350 AQ [Radeon 9600] (Secondary)
+ 1043 c005 A9600SE (Secondary)
+ 4172 RV350 AR [Radeon 9600] (Secondary)
+ 1002 0003 Radeon 9600XT (Secondary)
+ 1002 4773 All-in-Wonder 9600 XT (Secondary)
+ 1043 c003 A9600XT (Secondary)
+ 1043 c01b A9600XT/TD (Secondary)
+ 174b 7c28 Sapphire Radeon 9600XT (Secondary)
+ 1787 4003 Radeon 9600 XT (Secondary)
+ 4173 RV350 ?? [Radeon 9550] (Secondary)
+ 4237 Radeon 7000 IGP
+ 4242 R200 BB [Radeon All in Wonder 8500DV]
+ 1002 02aa Radeon 8500 AIW DV Edition
+ 4243 R200 BC [Radeon All in Wonder 8500]
+ 4336 Radeon Mobility U1
+ 1002 4336 Pavilion ze4300 ATI Radeon Mobility U1 (IGP 320 M)
+ 103c 0024 Pavilion ze4400 builtin Video
+ 161f 2029 eMachines M5312 builtin Video
+ 4337 Radeon IGP 330M/340M/350M
+ 1014 053a ThinkPad R40e (2684-HVG) builtin VGA controller
+ 103c 0850 Radeon IGP 345M
+ 4341 IXP150 AC'97 Audio Controller
+ 4345 EHCI USB Controller
+ 4347 OHCI USB Controller #1
+ 4348 OHCI USB Controller #2
+ 4349 ATI Dual Channel Bus Master PCI IDE Controller
+ 434d IXP AC'97 Modem
+ 4353 ATI SMBus
+ 4354 215CT [Mach64 CT]
+ 4358 210888CX [Mach64 CX]
+ 4363 ATI SMBus
+ 436e ATI 436E Serial ATA Controller
+ 4370 IXP SB400 AC'97 Audio Controller
+ 1025 0079 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 107b 0300 MX6421
+ 4371 IXP SB400 PCI-PCI Bridge
+ 103c 308b MX6125
+ 4372 IXP SB400 SMBus Controller
+ 1025 0080 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 4373 IXP SB400 USB2 Host Controller
+ 1025 0080 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 4374 IXP SB400 USB Host Controller
+ 103c 308b MX6125
+ 4375 IXP SB400 USB Host Controller
+ 1025 0080 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 4376 Standard Dual Channel PCI IDE Controller ATI
+ 1025 0080 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 4377 IXP SB400 PCI-ISA Bridge
+ 1025 0080 Aspire 5024WLMi
+ 103c 308b MX6125
+ 4378 ATI SB400 - AC'97 Modem Controller
+ 1025 0080 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 4379 ATI 4379 Serial ATA Controller
+ 437a ATI 437A Serial ATA Controller
+ 437b SB450 HDA Audio
+ 4380 SB600 Non-Raid-5 SATA
+ 4381 SB600 Raid-5 SATA
+ 4382 SB600 AC97 Audio
+ 4383 SB600 Azalia
+ 4384 SB600 PCI to PCI Bridge
+ 4385 SB600 SMBus
+ 4386 SB600 USB Controller (EHCI)
+ 4387 SB600 USB (OHCI0)
+ 4388 SB600 USB (OHCI1)
+ 4389 SB600 USB (OHCI2)
+ 438a SB600 USB (OHCI3)
+ 438b SB600 USB (OHCI4)
+ 438c SB600 IDE
+ 438d SB600 PCI to LPC Bridge
+ 438e SB600 AC97 Modem
+ 4437 Radeon Mobility 7000 IGP
+ 4554 210888ET [Mach64 ET]
+ 4654 Mach64 VT
+ 4742 3D Rage Pro AGP 1X/2X
+ 1002 0040 Rage Pro Turbo AGP 2X
+ 1002 0044 Rage Pro Turbo AGP 2X
+ 1002 0061 Rage Pro AIW AGP 2X
+ 1002 0062 Rage Pro AIW AGP 2X
+ 1002 0063 Rage Pro AIW AGP 2X
+ 1002 0080 Rage Pro Turbo AGP 2X
+ 1002 0084 Rage Pro Turbo AGP 2X
+ 1002 4742 Rage Pro Turbo AGP 2X
+ 1002 8001 Rage Pro Turbo AGP 2X
+ 1028 0082 Rage Pro Turbo AGP 2X
+ 1028 4082 Optiplex GX1 Onboard Display Adapter
+ 1028 8082 Rage Pro Turbo AGP 2X
+ 1028 c082 Rage Pro Turbo AGP 2X
+ 8086 4152 Xpert 98D AGP 2X
+ 8086 464a Rage Pro Turbo AGP 2X
+ 4744 3D Rage Pro AGP 1X
+ 1002 4744 Rage Pro Turbo AGP
+ 4747 3D Rage Pro
+ 4749 3D Rage Pro
+ 1002 0061 Rage Pro AIW
+ 1002 0062 Rage Pro AIW
+ 474c Rage XC
+ 474d Rage XL AGP 2X
+ 1002 0004 Xpert 98 RXL AGP 2X
+ 1002 0008 Xpert 98 RXL AGP 2X
+ 1002 0080 Rage XL AGP 2X
+ 1002 0084 Xpert 98 AGP 2X
+ 1002 474d Rage XL AGP
+ 1033 806a Rage XL AGP
+ 474e Rage XC AGP
+ 1002 474e Rage XC AGP
+ 474f Rage XL
+ 1002 0008 Rage XL
+ 1002 474f Rage XL
+ 4750 3D Rage Pro 215GP
+ 1002 0040 Rage Pro Turbo
+ 1002 0044 Rage Pro Turbo
+ 1002 0080 Rage Pro Turbo
+ 1002 0084 Rage Pro Turbo
+ 1002 4750 Rage Pro Turbo
+ 4751 3D Rage Pro 215GQ
+ 4752 Rage XL
+ 0e11 001e Proliant Rage XL
+ 1002 0008 Rage XL
+ 1002 4752 Proliant Rage XL
+ 1002 8008 Rage XL
+ 1028 00ce PowerEdge 1400
+ 1028 00d1 PowerEdge 2550
+ 1028 00d9 PowerEdge 2500
+ 1028 0134 PowerEdge 600SC
+ 103c 10e1 NetServer Rage XL
+ 107b 6400 6400 Server
+ 1734 007a Primergy RX300
+ 8086 3411 SDS2 Mainboard
+ 8086 3427 S875WP1-E mainboard
+ 4753 Rage XC
+ 1002 4753 Rage XC
+ 4754 3D Rage I/II 215GT [Mach64 GT]
+ 4755 3D Rage II+ 215GTB [Mach64 GTB]
+ 4756 3D Rage IIC 215IIC [Mach64 GT IIC]
+ 1002 4756 Rage IIC
+ 4757 3D Rage IIC AGP
+ 1002 4757 Rage IIC AGP
+ 1028 0089 Rage 3D IIC
+ 1028 008e PowerEdge 1300 onboard video
+ 1028 4082 Rage 3D IIC
+ 1028 8082 Rage 3D IIC
+ 1028 c082 Rage 3D IIC
+ 4758 210888GX [Mach64 GX]
+ 4759 3D Rage IIC
+ 475a 3D Rage IIC AGP
+ 1002 0084 Rage 3D Pro AGP 2x XPERT 98
+ 1002 0087 Rage 3D IIC
+ 1002 475a Rage IIC AGP
+ 4964 Radeon RV250 Id [Radeon 9000]
+ 4965 Radeon RV250 Ie [Radeon 9000]
+ 4966 Radeon RV250 If [Radeon 9000]
+ 10f1 0002 RV250 If [Tachyon G9000 PRO]
+ 148c 2039 RV250 If [Radeon 9000 Pro "Evil Commando"]
+ 1509 9a00 RV250 If [Radeon 9000 "AT009"]
+# New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified.
+ 1681 0040 RV250 If [3D prophet 9000]
+ 174b 7176 RV250 If [Sapphire Radeon 9000 Pro]
+ 174b 7192 RV250 If [Radeon 9000 "Atlantis"]
+ 17af 2005 RV250 If [Excalibur Radeon 9000 Pro]
+ 17af 2006 RV250 If [Excalibur Radeon 9000]
+ 4967 Radeon RV250 Ig [Radeon 9000]
+ 496e Radeon RV250 [Radeon 9000] (Secondary)
+ 4a48 R420 JH [Radeon X800]
+ 4a49 R420 JI [Radeon X800PRO]
+ 4a4a R420 JJ [Radeon X800SE]
+ 4a4b R420 JK [Radeon X800]
+ 4a4c R420 JL [Radeon X800]
+ 4a4d R420 JM [FireGL X3]
+ 4a4e M18 JN [Radeon Mobility 9800]
+ 4a50 R420 JP [Radeon X800XT]
+ 4a54 R420 [Radeon X800 VE]
+ 4a69 R420 [Radeon X800 PRO/GTO] (Secondary)
+ 4a6a R420 [Radeon X800] (Secondary)
+ 4a6b R420 [Radeon X800] (Secondary)
+ 4a70 R420 [X800XT-PE] (Secondary)
+ 4a74 R420 [Radeon X800 VE] (Secondary)
+ 4b49 R480 [Radeon X850XT]
+ 4b4b R480 [Radeon X850Pro]
+ 4b4c R481 [Radeon X850XT-PE]
+ 4b69 R480 [Radeon X850XT] (Secondary)
+ 4b6b R480 [Radeon X850Pro] (Secondary)
+ 4b6c R481 [Radeon X850XT-PE] (Secondary)
+ 4c42 3D Rage LT Pro AGP-133
+ 0e11 b0e7 Rage LT Pro (Compaq Presario 5240)
+ 0e11 b0e8 Rage 3D LT Pro
+ 0e11 b10e 3D Rage LT Pro (Compaq Armada 1750)
+ 1002 0040 Rage LT Pro AGP 2X
+ 1002 0044 Rage LT Pro AGP 2X
+ 1002 4c42 Rage LT Pro AGP 2X
+ 1002 8001 Rage LT Pro AGP 2X
+ 1028 0085 Rage 3D LT Pro
+ 4c44 3D Rage LT Pro AGP-66
+ 4c45 Rage Mobility M3 AGP
+ 4c46 Rage Mobility M3 AGP 2x
+ 1028 00b1 Latitude C600
+ 4c47 3D Rage LT-G 215LG
+ 4c49 3D Rage LT Pro
+ 1002 0004 Rage LT Pro
+ 1002 0040 Rage LT Pro
+ 1002 0044 Rage LT Pro
+ 1002 4c49 Rage LT Pro
+ 4c4d Rage Mobility P/M AGP 2x
+ 0e11 b111 Armada M700
+ 0e11 b160 Armada E500
+ 1002 0084 Xpert 98 AGP 2X (Mobility)
+ 1014 0154 ThinkPad A20m/A21m
+ 1028 00aa Latitude CPt
+ 1028 00bb Latitude CPx
+ 10e1 10cf Fujitsu Siemens LifeBook C Series
+ 1179 ff00 Satellite 1715XCDS laptop
+ 13bd 1019 PC-AR10
+ 4c4e Rage Mobility L AGP 2x
+ 4c50 3D Rage LT Pro
+ 1002 4c50 Rage LT Pro
+ 4c51 3D Rage LT Pro
+ 4c52 Rage Mobility P/M
+ 1033 8112 Versa Note VXi
+ 4c53 Rage Mobility L
+ 4c54 264LT [Mach64 LT]
+ 4c57 Radeon Mobility M7 LW [Radeon Mobility 7500]
+ 1014 0517 ThinkPad T30
+ 1028 00e6 Radeon Mobility M7 LW (Dell Inspiron 8100)
+ 1028 012a Latitude C640
+ 144d c006 Radeon Mobility M7 LW in vpr Matrix 170B4
+ 4c58 Radeon RV200 LX [Mobility FireGL 7800 M7]
+ 4c59 Radeon Mobility M6 LY
+ 0e11 b111 Evo N600c
+ 1014 0235 ThinkPad A30/A30p (2652/2653)
+ 1014 0239 ThinkPad X22/X23/X24
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 104d 8140 PCG-Z1SP laptop
+ 1509 1930 Medion MD9703
+ 4c5a Radeon Mobility M6 LZ
+ 4c64 Radeon R250 Ld [Radeon Mobility 9000 M9]
+ 4c65 Radeon R250 Le [Radeon Mobility 9000 M9]
+ 4c66 Radeon R250 [Mobility FireGL 9000]
+ 4c67 Radeon R250 Lg [Radeon Mobility 9000 M9]
+# Secondary chip to the Lf
+ 4c6e Radeon R250 Ln [Radeon Mobility 9000 M9] [Secondary]
+ 4d46 Rage Mobility M4 AGP
+ 4d4c Rage Mobility M4 AGP
+ 4e44 Radeon R300 ND [Radeon 9700 Pro]
+ 1002 515e Radeon ES1000
+ 1002 5965 Radeon ES1000
+ 4e45 Radeon R300 NE [Radeon 9500 Pro]
+ 1002 0002 Radeon R300 NE [Radeon 9500 Pro]
+ 1681 0002 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
+ 4e46 RV350 NF [Radeon 9600]
+ 4e47 Radeon R300 NG [FireGL X1]
+ 4e48 Radeon R350 [Radeon 9800 Pro]
+ 4e49 Radeon R350 [Radeon 9800]
+ 4e4a RV350 NJ [Radeon 9800 XT]
+ 4e4b R350 NK [Fire GL X2]
+ 4e50 RV350 [Mobility Radeon 9600 M10]
+ 1025 005a TravelMate 290
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 1462 0311 MSI M510A
+ 1734 1055 Amilo M1420W
+ 4e51 M10 NQ [Radeon Mobility 9600]
+ 4e52 RV350 [Mobility Radeon 9600 M10]
+ 4e53 M10 NS [Radeon Mobility 9600]
+ 4e54 M10 NT [FireGL Mobility T2]
+ 4e56 M11 NV [FireGL Mobility T2e]
+ 4e64 Radeon R300 [Radeon 9700 Pro] (Secondary)
+ 4e65 Radeon R300 [Radeon 9500 Pro] (Secondary)
+ 1002 0003 Radeon R300 NE [Radeon 9500 Pro]
+ 1681 0003 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
+ 4e66 RV350 NF [Radeon 9600] (Secondary)
+ 4e67 Radeon R300 [FireGL X1] (Secondary)
+ 4e68 Radeon R350 [Radeon 9800 Pro] (Secondary)
+ 4e69 Radeon R350 [Radeon 9800] (Secondary)
+ 4e6a RV350 NJ [Radeon 9800 XT] (Secondary)
+ 1002 4e71 ATI Technologies Inc M10 NQ [Radeon Mobility 9600]
+ 4e71 M10 NQ [Radeon Mobility 9600] (Secondary)
+ 4f72 RV250 [Radeon 9000 Series]
+ 4f73 Radeon RV250 [Radeon 9000 Series] (Secondary)
+ 5041 Rage 128 PA/PRO
+ 5042 Rage 128 PB/PRO AGP 2x
+ 5043 Rage 128 PC/PRO AGP 4x
+ 5044 Rage 128 PD/PRO TMDS
+ 1002 0028 Rage 128 AIW
+ 1002 0029 Rage 128 AIW
+ 5045 Rage 128 PE/PRO AGP 2x TMDS
+ 5046 Rage 128 PF/PRO AGP 4x TMDS
+ 1002 0004 Rage Fury Pro
+ 1002 0008 Rage Fury Pro/Xpert 2000 Pro
+ 1002 0014 Rage Fury Pro
+ 1002 0018 Rage Fury Pro/Xpert 2000 Pro
+ 1002 0028 Rage 128 Pro AIW AGP
+ 1002 002a Rage 128 Pro AIW AGP
+ 1002 0048 Rage Fury Pro
+ 1002 2000 Rage Fury MAXX AGP 4x (TMDS) (VGA device)
+ 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
+ 5047 Rage 128 PG/PRO
+ 5048 Rage 128 PH/PRO AGP 2x
+ 5049 Rage 128 PI/PRO AGP 4x
+ 504a Rage 128 PJ/PRO TMDS
+ 504b Rage 128 PK/PRO AGP 2x TMDS
+ 504c Rage 128 PL/PRO AGP 4x TMDS
+ 504d Rage 128 PM/PRO
+ 504e Rage 128 PN/PRO AGP 2x
+ 504f Rage 128 PO/PRO AGP 4x
+ 5050 Rage 128 PP/PRO TMDS [Xpert 128]
+ 1002 0008 Xpert 128
+ 5051 Rage 128 PQ/PRO AGP 2x TMDS
+ 5052 Rage 128 PR/PRO AGP 4x TMDS
+ 5053 Rage 128 PS/PRO
+ 5054 Rage 128 PT/PRO AGP 2x
+ 5055 Rage 128 PU/PRO AGP 4x
+ 5056 Rage 128 PV/PRO TMDS
+ 5057 Rage 128 PW/PRO AGP 2x TMDS
+ 5058 Rage 128 PX/PRO AGP 4x TMDS
+ 5144 Radeon R100 QD [Radeon 7200]
+ 1002 0008 Radeon 7000/Radeon VE
+ 1002 0009 Radeon 7000/Radeon
+ 1002 000a Radeon 7000/Radeon
+ 1002 001a Radeon 7000/Radeon
+ 1002 0029 Radeon AIW
+ 1002 0038 Radeon 7000/Radeon
+ 1002 0039 Radeon 7000/Radeon
+ 1002 008a Radeon 7000/Radeon
+ 1002 00ba Radeon 7000/Radeon
+ 1002 0139 Radeon 7000/Radeon
+ 1002 028a Radeon 7000/Radeon
+ 1002 02aa Radeon AIW
+ 1002 053a Radeon 7000/Radeon
+ 5145 Radeon R100 QE
+ 5146 Radeon R100 QF
+ 5147 Radeon R100 QG
+ 5148 Radeon R200 QH [Radeon 8500]
+ 1002 010a FireGL 8800 64Mb
+ 1002 0152 FireGL 8800 128Mb
+ 1002 0162 FireGL 8700 32Mb
+ 1002 0172 FireGL 8700 64Mb
+ 5149 Radeon R200 QI
+ 514a Radeon R200 QJ
+ 514b Radeon R200 QK
+ 514c Radeon R200 QL [Radeon 8500 LE]
+ 1002 003a Radeon R200 QL [Radeon 8500 LE]
+ 1002 013a Radeon 8500
+ 148c 2026 R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
+ 1681 0010 Radeon 8500 [3D Prophet 8500 128Mb]
+ 174b 7149 Radeon R200 QL [Sapphire Radeon 8500 LE]
+ 514d Radeon R200 QM [Radeon 9100]
+ 514e Radeon R200 QN [Radeon 8500LE]
+ 514f Radeon R200 QO [Radeon 8500LE]
+ 5154 R200 QT [Radeon 8500]
+ 5155 R200 QU [Radeon 9100]
+ 5157 Radeon RV200 QW [Radeon 7500]
+ 1002 013a Radeon 7500
+ 1002 103a Dell Optiplex GX260
+ 1458 4000 RV200 QW [RADEON 7500 PRO MAYA AR]
+ 148c 2024 RV200 QW [Radeon 7500LE Dual Display]
+ 148c 2025 RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
+ 148c 2036 RV200 QW [Radeon 7500 PCI Dual Display]
+ 174b 7146 RV200 QW [Radeon 7500 LE]
+ 174b 7147 RV200 QW [Sapphire Radeon 7500LE]
+ 174b 7161 Radeon RV200 QW [Radeon 7500 LE]
+ 17af 0202 RV200 QW [Excalibur Radeon 7500LE]
+ 5158 Radeon RV200 QX [Radeon 7500]
+ 5159 Radeon RV100 QY [Radeon 7000/VE]
+ 1002 000a Radeon 7000/Radeon VE
+ 1002 000b Radeon 7000
+ 1002 0038 Radeon 7000/Radeon VE
+ 1002 003a Radeon 7000/Radeon VE
+ 1002 00ba Radeon 7000/Radeon VE
+ 1002 013a Radeon 7000/Radeon VE
+ 1002 0908 XVR-100 (supplied by Sun)
+# The IBM card doubles as an ATI PCI video adapter
+ 1014 029a Remote Supervisor Adapter II (RSA2)
+ 1014 02c8 IBM eServer xSeries server mainboard
+ 1028 019a PowerEdge SC1425
+ 1458 4002 RV100 QY [RADEON 7000 PRO MAYA AV Series]
+ 148c 2003 RV100 QY [Radeon 7000 Multi-Display Edition]
+ 148c 2023 RV100 QY [Radeon 7000 Evil Master Multi-Display]
+ 174b 7112 RV100 QY [Sapphire Radeon VE 7000]
+ 174b 7c28 Sapphire Radeon VE 7000 DDR
+ 1787 0202 RV100 QY [Excalibur Radeon 7000]
+ 17ee 1001 Radeon 7000 64MB DDR + DVI
+ 515a Radeon RV100 QZ [Radeon 7000/VE]
+ 515e ES1000
+ 515f ES1000
+ 5168 Radeon R200 Qh
+ 5169 Radeon R200 Qi
+ 516a Radeon R200 Qj
+ 516b Radeon R200 Qk
+# This one is not in ATI documentation, but is in XFree86 source code
+ 516c Radeon R200 Ql
+ 5245 Rage 128 RE/SG
+ 1002 0008 Xpert 128
+ 1002 0028 Rage 128 AIW
+ 1002 0029 Rage 128 AIW
+ 1002 0068 Rage 128 AIW
+ 5246 Rage 128 RF/SG AGP
+ 1002 0004 Magnum/Xpert 128/Xpert 99
+ 1002 0008 Magnum/Xpert128/X99/Xpert2000
+ 1002 0028 Rage 128 AIW AGP
+ 1002 0044 Rage Fury/Xpert 128/Xpert 2000
+ 1002 0068 Rage 128 AIW AGP
+ 1002 0448 Rage Fury
+ 5247 Rage 128 RG
+ 524b Rage 128 RK/VR
+ 524c Rage 128 RL/VR AGP
+ 1002 0008 Xpert 99/Xpert 2000
+ 1002 0088 Xpert 99
+ 5345 Rage 128 SE/4x
+ 5346 Rage 128 SF/4x AGP 2x
+ 1002 0048 RAGE 128 16MB VGA TVOUT AMC PAL
+ 5347 Rage 128 SG/4x AGP 4x
+ 5348 Rage 128 SH
+ 534b Rage 128 SK/4x
+ 534c Rage 128 SL/4x AGP 2x
+ 534d Rage 128 SM/4x AGP 4x
+ 1002 0008 Xpert 99/Xpert 2000
+ 1002 0018 Xpert 2000
+ 534e Rage 128 4x
+ 5354 Mach 64 VT
+ 1002 5654 Mach 64 reference
+ 5446 Rage 128 Pro Ultra TF
+ 1002 0004 Rage Fury Pro
+ 1002 0008 Rage Fury Pro/Xpert 2000 Pro
+ 1002 0018 Rage Fury Pro/Xpert 2000 Pro
+ 1002 0028 Rage 128 AIW Pro AGP
+ 1002 0029 Rage 128 AIW
+ 1002 002a Rage 128 AIW Pro AGP
+ 1002 002b Rage 128 AIW
+ 1002 0048 Xpert 2000 Pro
+ 544c Rage 128 Pro Ultra TL
+ 5452 Rage 128 Pro Ultra TR
+ 1002 001c Rage 128 Pro 4XL
+ 103c 1279 Rage 128 Pro 4XL
+ 5453 Rage 128 Pro Ultra TS
+ 5454 Rage 128 Pro Ultra TT
+ 5455 Rage 128 Pro Ultra TU
+ 5460 M22 [Radeon Mobility M300]
+ 5462 M24 [Radeon Mobility X600]
+ 5464 M22 [FireGL GL]
+ 5548 R423 UH [Radeon X800 (PCIE)]
+ 5549 R423 UI [Radeon X800PRO (PCIE)]
+ 554a R423 UJ [Radeon X800LE (PCIE)]
+ 554b R423 UK [Radeon X800SE (PCIE)]
+ 554d R430 [Radeon X800 XL] (PCIe)
+ 554f R430 [Radeon X800 (PCIE)]
+ 5550 R423 [Fire GL V7100]
+ 5551 R423 UQ [FireGL V7200 (PCIE)]
+ 5552 R423 UR [FireGL V5100 (PCIE)]
+ 5554 R423 UT [FireGL V7100 (PCIE)]
+ 5569 R423 UI [Radeon X800PRO (PCIE)] Secondary
+ 556b Radeon R423 UK (PCIE) [X800 SE] (Secondary)
+ 556d R430 [Radeon X800 XL] (PCIe) Secondary
+ 556f R430 [Radeon X800 (PCIE) Secondary]
+ 5571 R423GL-SE ATI FIREGL V5100 PCI-EX Secondary
+ 564a M26 [Mobility FireGL V5000]
+ 564b M26 [Mobility FireGL V5000]
+ 564f M26 [Radeon Mobility X700 XL] (PCIE)
+ 5652 M26 [Radeon Mobility X700]
+ 5653 Radeon Mobility X700 (PCIE)
+ 1025 0080 Aspire 5024WLMi
+ 5654 264VT [Mach64 VT]
+ 1002 5654 Mach64VT Reference
+ 5655 264VT3 [Mach64 VT3]
+ 5656 264VT4 [Mach64 VT4]
+ 5830 RS300 Host Bridge
+ 5831 RS300 Host Bridge
+ 5832 RS300 Host Bridge
+ 5833 Radeon 9100 IGP Host Bridge
+ 5834 Radeon 9100 IGP
+ 5835 RS300M AGP [Radeon Mobility 9100IGP]
+ 5838 Radeon 9100 IGP AGP Bridge
+ 5940 RV280 [Radeon 9200 PRO] (Secondary)
+ 5941 RV280 [Radeon 9200] (Secondary)
+ 1458 4019 Gigabyte Radeon 9200
+ 174b 7c12 Sapphire Radeon 9200
+ 17af 200d Excalibur Radeon 9200
+ 18bc 0050 GeXcube GC-R9200-C3 (Secondary)
+ 5944 RV280 [Radeon 9200 SE (PCI)]
+ 5950 RS480 Host Bridge
+ 1025 0080 Aspire 5024WLMMi
+ 103c 308b MX6125
+ 5951 ATI Radeon Xpress 200 (RS480/RS482/RX480/RX482) Chipset - Host bridge
+ 5954 RS480 [Radeon Xpress 200G Series]
+ 1002 5954 RV370 [Radeon Xpress 200G Series]
+ 5955 ATI Radeon XPRESS 200M 5955 (PCIE)
+ 1002 5955 RS480 0x5955 [ATI Radeon XPRESS 200M 5955 (PCIE)]
+ 103c 308b MX6125
+ 5960 RV280 [Radeon 9200 PRO]
+ 5961 RV280 [Radeon 9200]
+ 1002 2f72 All-in-Wonder 9200 Series
+ 1019 4c30 Radeon 9200 VIVO
+ 12ab 5961 YUAN SMARTVGA Radeon 9200
+ 1458 4018 Gigabyte Radeon 9200
+ 174b 7c13 Sapphire Radeon 9200
+ 17af 200c Excalibur Radeon 9200
+ 18bc 0050 Radeon 9200 Game Buster
+ 18bc 0051 GeXcube GC-R9200-C3
+ 18bc 0053 Radeon 9200 Game Buster VIVO
+ 5962 RV280 [Radeon 9200]
+ 5964 RV280 [Radeon 9200 SE]
+ 1043 c006 ASUS Radeon 9200 SE / TD / 128M
+ 1458 4018 Radeon 9200 SE
+ 1458 4032 Radeon 9200 SE 128MB
+ 147b 6191 R9200SE-DT
+ 148c 2073 CN-AG92E
+ 174b 7c13 Sapphire Radeon 9200 SE
+ 1787 5964 Excalibur 9200SE VIVO 128M
+ 17af 2012 Radeon 9200 SE Excalibur
+ 18bc 0170 Sapphire Radeon 9200 SE 128MB Game Buster
+ 18bc 0173 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
+ 5969 ES1000
+ 5974 RS482 [Radeon Xpress 200]
+ 5975 RS482 [Radeon Xpress 200M]
+ 5a33 Radeon Xpress 200 Host Bridge
+ 5a34 RS480 PCI-X Root Port
+# Comes in pair with 5a3f
+ 5a36 RS480 PCI Bridge
+ 5a38 RS480 PCI Bridge
+# Comes in pair with 5a38
+ 5a39 RS480 PCI Bridge
+ 5a3f RS480 PCI Bridge
+ 5a41 RS400 [Radeon Xpress 200]
+ 5a42 RS400 [Radeon Xpress 200M]
+ 5a61 RC410 [Radeon Xpress 200]
+ 5a62 RC410 [Radeon Xpress 200M]
+ 5b60 RV370 5B60 [Radeon X300 (PCIE)]
+ 1043 002a Extreme AX300SE-X
+ 1043 032e Extreme AX300/TD
+ 1462 0400 RX300SE-TD128E (MS-8940 REV:200)
+ 1462 0402 RX300SE-TD128E (MS-8940)
+ 196d 1086 X300SE HM
+ 5b62 RV380 [Radeon X600 (PCIE)]
+ 5b63 RV370 [Sapphire X550 Silent]
+ 5b64 RV370 5B64 [FireGL V3100 (PCIE)]
+ 5b65 RV370 5B65 [FireGL D1100 (PCIE)]
+ 5b70 RV370 [Radeon X300SE]
+ 1462 0403 RX300SE-TD128E (MS-8940) (secondary display)
+ 196d 1087 X300SE HM
+ 5b72 RV380 [Radeon X600]
+ 5b73 RV370 secondary [Sapphire X550 Silent]
+ 5b74 RV370 5B64 [FireGL V3100 (PCIE)] (Secondary)
+ 5c61 M9+ 5C61 [Radeon Mobility 9200 (AGP)]
+ 5c63 M9+ 5C63 [Radeon Mobility 9200 (AGP)]
+ 1002 5c63 Apple iBook G4 2004
+ 5d44 RV280 [Radeon 9200 SE] (Secondary)
+ 1458 4019 Radeon 9200 SE (Secondary)
+ 1458 4032 Radeon 9200 SE 128MB
+ 174b 7c12 Sapphire Radeon 9200 SE (Secondary)
+ 1787 5965 Excalibur 9200SE VIVO 128M (Secondary)
+ 17af 2013 Radeon 9200 SE Excalibur (Secondary)
+ 18bc 0171 Radeon 9200 SE 128MB Game Buster (Secondary)
+ 18bc 0172 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
+ 5d48 M28 [Radeon Mobility X800XT]
+ 5d49 M28 [Mobility FireGL V5100]
+ 5d4a Mobility Radeon X800
+ 5d4d R480 [Radeon X850XT Platinum (PCIE)]
+ 5d4f R480 [Radeon X800 GTO (PCIE)]
+ 5d52 R480 [Radeon X850XT (PCIE)] (Primary)
+ 1002 0b12 PowerColor X850XT PCIe Primary
+ 1002 0b13 PowerColor X850XT PCIe Secondary
+ 5d57 R423 5F57 [Radeon X800XT (PCIE)]
+ 5d6d R480 [Radeon X850XT Platinum (PCIE)] (Secondary)
+ 5d6f R480 [Radeon X800 GTO (PCIE)] (Secondary)
+ 5d72 R480 [Radeon X850XT (PCIE)] (Secondary)
+ 5d77 R423 5F57 [Radeon X800XT (PCIE)] (Secondary)
+ 5e48 RV410 [FireGL V5000]
+ 5e49 RV410 [FireGL V3300]
+ 5e4a RV410 [Radeon X700XT]
+ 5e4b RV410 [Radeon X700 Pro (PCIE)]
+ 5e4c RV410 [Radeon X700SE]
+ 5e4d RV410 [Radeon X700 (PCIE)]
+ 148c 2116 PowerColor Bravo X700
+ 5e4f RV410 [Radeon X700]
+ 5e6b RV410 [Radeon X700 Pro (PCIE)] Secondary
+ 5e6d RV410 [Radeon X700 (PCIE)] (Secondary)
+ 148c 2117 PowerColor Bravo X700
+ 5f57 R423 [Radeon X800XT (PCIE)]
+ 700f PCI Bridge [IGP 320M]
+ 7010 PCI Bridge [IGP 340M]
+ 7100 R520 [Radeon X1800]
+ 7104 R520 GL ATI FireGL V7200 Primary
+ 7105 R520 [FireGL]
+ 7109 R520 [Radeon X1800]
+ 1002 0322 All-in-Wonder X1800XL
+ 1002 0d02 Radeon X1800 CrossFire Edition
+ 7120 R520 [Radeon X1800] (Secondary)
+ 7124 R520 GL ATI FireGL V7200 Secondary
+ 7129 R520 [Radeon X1800] (Secondary)
+ 1002 0323 All-in-Wonder X1800XL (Secondary)
+ 1002 0d03 Radeon X1800 CrossFire Edition (Secondary)
+ 7142 RV515 [Radeon X1300]
+ 1002 0322 All-in-Wonder 2006 PCI-E Edition
+ 7145 Radeon Mobility X1400
+ 7146 RV515 [Radeon X1300]
+ 1002 0322 All-in-Wonder 2006 PCI-E Edition
+ 7149 M52 [ATI Mobility Radeon X1300]
+ 714a M52 [ATI Mobility Radeon X1300]
+ 714b M52 [ATI Mobility Radeon X1300]
+ 714c M52 [ATI Mobility Radeon X1300]
+ 7152 RV515 GL ATI FireGL V3300 Primary
+ 7162 RV515 [Radeon X1300] (Secondary)
+ 1002 0323 All-in-Wonder 2006 PCI-E Edition (Secondary)
+ 7166 RV515 [Radeon X1300] (Secondary)
+ 1002 0323 All-in-Wonder 2006 PCI-E Edition (Secondary)
+ 7172 RV515 GL ATI FireGL V3300 Secondary
+ 7181 RV516 XT Radeon X1600 Series Primary
+ 71a1 RV516 XT Radeon X1600 Series Secondary
+ 71c0 RV530 [Radeon X1600]
+ 71c2 RV530 [Radeon X1600]
+ 71c4 M56GL [ATI Mobility FireGL V5200]
+ 71c5 M56P [Radeon Mobility X1600]
+ 71d5 M66-P ATI Mobility Radeon X1700
+ 71d6 M66-XT ATI Mobility Radeon X1700
+ 71e0 RV530 [Radeon X1600] (Secondary)
+ 71e2 RV530 [Radeon X1600] (Secondary)
+ 7249 R580 [Radeon X1900 XT] Primary
+ 724e R580 [FireGL V7300/V7350] Primary (PCIE)
+ 7269 R580 [Radeon X1900 XT] Secondary
+ 726e R580 [FireGL V7300/V7350] Secondary (PCIE)
+ 7833 Radeon 9100 IGP Host Bridge
+ 7834 Radeon 9100 PRO IGP
+ 7835 Radeon Mobility 9200 IGP
+ 7838 Radeon 9100 IGP PCI/AGP Bridge
+ 7c37 RV350 AQ [Radeon 9600 SE]
+ cab0 AGP Bridge [IGP 320M]
+ cab2 RS200/RS200M AGP Bridge [IGP 340M]
+ cab3 R200 AGP Bridge [Mobility Radeon 7000 IGP]
+ cbb2 RS200/RS200M AGP Bridge [IGP 340M]
+1003 ULSI Systems
+ 0201 US201
+1004 VLSI Technology Inc
+ 0005 82C592-FC1
+ 0006 82C593-FC1
+ 0007 82C594-AFC2
+ 0008 82C596/7 [Wildcat]
+ 0009 82C597-AFC2
+ 000c 82C541 [Lynx]
+ 000d 82C543 [Lynx]
+ 0101 82C532
+ 0102 82C534 [Eagle]
+ 0103 82C538
+ 0104 82C535
+ 0105 82C147
+ 0200 82C975
+ 0280 82C925
+ 0304 QSound ThunderBird PCI Audio
+ 1004 0304 QSound ThunderBird PCI Audio
+ 122d 1206 DSP368 Audio
+ 1483 5020 XWave Thunder 3D Audio
+ 0305 QSound ThunderBird PCI Audio Gameport
+ 1004 0305 QSound ThunderBird PCI Audio Gameport
+ 122d 1207 DSP368 Audio Gameport
+ 1483 5021 XWave Thunder 3D Audio Gameport
+ 0306 QSound ThunderBird PCI Audio Support Registers
+ 1004 0306 QSound ThunderBird PCI Audio Support Registers
+ 122d 1208 DSP368 Audio Support Registers
+ 1483 5022 XWave Thunder 3D Audio Support Registers
+ 0307 Thunderbird
+ 0308 Thunderbird
+ 0702 VAS96011 [Golden Gate II]
+ 0703 Tollgate
+1005 Avance Logic Inc. [ALI]
+ 2064 ALG2032/2064
+ 2128 ALG2364A
+ 2301 ALG2301
+ 2302 ALG2302
+ 2364 ALG2364
+ 2464 ALG2364A
+ 2501 ALG2564A/25128A
+1006 Reply Group
+1007 NetFrame Systems Inc
+1008 Epson
+100a Phoenix Technologies
+100b National Semiconductor Corporation
+ 0001 DP83810
+ 0002 87415/87560 IDE
+ 000e 87560 Legacy I/O
+ 000f FireWire Controller
+ 0011 NS87560 National PCI System I/O
+ 0012 USB Controller
+ 0020 DP83815 (MacPhyter) Ethernet Controller
+ 103c 0024 Pavilion ze4400 builtin Network
+ 12d9 000c Aculab E1/T1 PMXc cPCI carrier card
+ 1385 f311 FA311 / FA312 (FA311 with WoL HW)
+ 0021 PC87200 PCI to ISA Bridge
+ 0022 DP83820 10/100/1000 Ethernet Controller
+ 0028 Geode GX2 Host Bridge
+ 002a CS5535 South Bridge
+ 002b CS5535 ISA bridge
+ 002d CS5535 IDE
+ 002e CS5535 Audio
+ 002f CS5535 USB
+ 0030 Geode GX2 Graphics Processor
+ 0035 DP83065 [Saturn] 10/100/1000 Ethernet Controller
+ 0500 SCx200 Bridge
+ 0501 SCx200 SMI
+ 0502 SCx200 IDE
+ 0503 SCx200 Audio
+ 0504 SCx200 Video
+ 0505 SCx200 XBus
+ 0510 SC1100 Bridge
+ 0511 SC1100 SMI
+ 0515 SC1100 XBus
+ d001 87410 IDE
+100c Tseng Labs Inc
+ 3202 ET4000/W32p rev A
+ 3205 ET4000/W32p rev B
+ 3206 ET4000/W32p rev C
+ 3207 ET4000/W32p rev D
+ 3208 ET6000
+ 4702 ET6300
+100d AST Research Inc
+100e Weitek
+ 9000 P9000 Viper
+ 9001 P9000 Viper
+ 9002 P9000 Viper
+ 9100 P9100 Viper Pro/SE
+1010 Video Logic, Ltd.
+1011 Digital Equipment Corporation
+ 0001 DECchip 21050
+ 0002 DECchip 21040 [Tulip]
+ 0004 DECchip 21030 [TGA]
+ 0007 NVRAM [Zephyr NVRAM]
+ 0008 KZPSA [KZPSA]
+ 0009 DECchip 21140 [FasterNet]
+ 1025 0310 21140 Fast Ethernet
+ 10b8 2001 SMC9332BDT EtherPower 10/100
+ 10b8 2002 SMC9332BVT EtherPower T4 10/100
+ 10b8 2003 SMC9334BDT EtherPower 10/100 (1-port)
+ 1109 2400 ANA-6944A/TX Fast Ethernet
+ 1112 2300 RNS2300 Fast Ethernet
+ 1112 2320 RNS2320 Fast Ethernet
+ 1112 2340 RNS2340 Fast Ethernet
+ 1113 1207 EN-1207-TX Fast Ethernet
+ 1186 1100 DFE-500TX Fast Ethernet
+ 1186 1112 DFE-570TX Fast Ethernet
+ 1186 1140 DFE-660 Cardbus Ethernet 10/100
+ 1186 1142 DFE-660 Cardbus Ethernet 10/100
+ 11f6 0503 Freedomline Fast Ethernet
+ 1282 9100 AEF-380TXD Fast Ethernet
+ 1385 1100 FA310TX Fast Ethernet
+ 2646 0001 KNE100TX Fast Ethernet
+ 000a 21230 Video Codec
+ 000d PBXGB [TGA2]
+ 000f PCI-to-PDQ Interface Chip [PFI]
+ 1011 def1 FDDI controller (DEFPA)
+ 103c def1 FDDI controller (3X-DEFPA)
+ 0014 DECchip 21041 [Tulip Pass 3]
+ 1186 0100 DE-530+
+ 0016 DGLPB [OPPO]
+ 0017 PV-PCI Graphics Controller (ZLXp-L)
+ 0019 DECchip 21142/43
+ 1011 500a DE500A Fast Ethernet
+ 1011 500b DE500B Fast Ethernet
+ 1014 0001 10/100 EtherJet Cardbus
+ 1025 0315 ALN315 Fast Ethernet
+ 1033 800c PC-9821-CS01 100BASE-TX Interface Card
+ 1033 800d PC-9821NR-B06 100BASE-TX Interface Card
+ 108d 0016 Rapidfire 2327 10/100 Ethernet
+ 108d 0017 GoCard 2250 Ethernet 10/100 Cardbus
+ 10b8 2005 SMC8032DT Extreme Ethernet 10/100
+ 10b8 8034 SMC8034 Extreme Ethernet 10/100
+ 10ef 8169 Cardbus Fast Ethernet
+ 1109 2a00 ANA-6911A/TX Fast Ethernet
+ 1109 2b00 ANA-6911A/TXC Fast Ethernet
+ 1109 3000 ANA-6922/TX Fast Ethernet
+ 1113 1207 Cheetah Fast Ethernet
+ 1113 2220 Cardbus Fast Ethernet
+ 115d 0002 Cardbus Ethernet 10/100
+ 1179 0203 Fast Ethernet
+ 1179 0204 Cardbus Fast Ethernet
+ 1186 1100 DFE-500TX Fast Ethernet
+ 1186 1101 DFE-500TX Fast Ethernet
+ 1186 1102 DFE-500TX Fast Ethernet
+ 1186 1112 DFE-570TX Quad Fast Ethernet
+ 1259 2800 AT-2800Tx Fast Ethernet
+ 1266 0004 Eagle Fast EtherMAX
+ 12af 0019 NetFlyer Cardbus Fast Ethernet
+ 1374 0001 Cardbus Ethernet Card 10/100
+ 1374 0002 Cardbus Ethernet Card 10/100
+ 1374 0007 Cardbus Ethernet Card 10/100
+ 1374 0008 Cardbus Ethernet Card 10/100
+ 1385 2100 FA510
+ 1395 0001 10/100 Ethernet CardBus PC Card
+ 13d1 ab01 EtherFast 10/100 Cardbus (PCMPC200)
+ 1498 000a TPMC880-10 10/100Base-T and 10Base2 PMC Ethernet Adapter
+ 1498 000b TPMC880-11 Single 10/100Base-T PMC Ethernet Adapter
+ 1498 000c TPMC880-12 Single 10Base2 PMC Ethernet Adapter
+ 14cb 0100 LNDL-100N 100Base-TX Ethernet PC Card
+ 8086 0001 EtherExpress PRO/100 Mobile CardBus 32
+ 001a Farallon PN9000SX Gigabit Ethernet
+ 0021 DECchip 21052
+ 0022 DECchip 21150
+ 0023 DECchip 21150
+ 0024 DECchip 21152
+ 0025 DECchip 21153
+ 0026 DECchip 21154
+ 0034 56k Modem Cardbus
+ 1374 0003 56k Modem Cardbus
+ 0045 DECchip 21553
+ 0046 DECchip 21554
+ 0e11 4050 Integrated Smart Array
+ 0e11 4051 Integrated Smart Array
+ 0e11 4058 Integrated Smart Array
+ 103c 10c2 Hewlett-Packard NetRAID-4M
+ 12d9 000a IP Telephony card
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ 9005 0364 5400S (Mustang)
+ 9005 0365 5400S (Mustang)
+ 9005 1364 Dell PowerEdge RAID Controller 2
+ 9005 1365 Dell PowerEdge RAID Controller 2
+ e4bf 1000 CC8-1-BLUES
+ 1065 StrongARM DC21285
+ 1069 0020 DAC960P / DAC1164P
+1012 Micronics Computers Inc
+1013 Cirrus Logic
+ 0038 GD 7548
+ 0040 GD 7555 Flat Panel GUI Accelerator
+ 004c GD 7556 Video/Graphics LCD/CRT Ctrlr
+ 00a0 GD 5430/40 [Alpine]
+ 00a2 GD 5432 [Alpine]
+ 00a4 GD 5434-4 [Alpine]
+ 00a8 GD 5434-8 [Alpine]
+ 00ac GD 5436 [Alpine]
+ 00b0 GD 5440
+ 00b8 GD 5446
+ 00bc GD 5480
+ 1013 00bc CL-GD5480
+ 00d0 GD 5462
+ 00d2 GD 5462 [Laguna I]
+ 00d4 GD 5464 [Laguna]
+ 00d5 GD 5464 BD [Laguna]
+ 00d6 GD 5465 [Laguna]
+ 13ce 8031 Barco Metheus 2 Megapixel, Dual Head
+ 13cf 8031 Barco Metheus 2 Megapixel, Dual Head
+ 00e8 GD 5436U
+ 1100 CL 6729
+ 1110 PD 6832 PCMCIA/CardBus Ctrlr
+ 1112 PD 6834 PCMCIA/CardBus Ctrlr
+ 1113 PD 6833 PCMCIA/CardBus Ctrlr
+ 1200 GD 7542 [Nordic]
+ 1202 GD 7543 [Viking]
+ 1204 GD 7541 [Nordic Light]
+ 4000 MD 5620 [CLM Data Fax Voice]
+ 4400 CD 4400
+ 6001 CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
+ 1014 1010 CS4610 SoundFusion Audio Accelerator
+ 6003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
+ 1013 4280 Crystal SoundFusion PCI Audio Accelerator
+ 1014 0153 ThinkPad A20m
+ 153b 1136 SiXPack 5.1+
+ 1681 0050 Game Theater XP
+ 1681 a011 Fortissimo III 7.1
+ 5053 3357 Santa Cruz
+ 6004 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
+ 6005 Crystal CS4281 PCI Audio
+ 1013 4281 Crystal CS4281 PCI Audio
+ 10cf 10a8 Crystal CS4281 PCI Audio
+ 10cf 10a9 Crystal CS4281 PCI Audio
+ 10cf 10aa Crystal CS4281 PCI Audio
+ 10cf 10ab Crystal CS4281 PCI Audio
+ 10cf 10ac Crystal CS4281 PCI Audio
+ 10cf 10ad Crystal CS4281 PCI Audio
+ 10cf 10b4 Crystal CS4281 PCI Audio
+ 1179 0001 Crystal CS4281 PCI Audio
+ 14c0 000c Crystal CS4281 PCI Audio
+1014 IBM
+ 0002 PCI to MCA Bridge
+ 0005 Alta Lite
+ 0007 Alta MP
+ 000a Fire Coral
+ 0017 CPU to PCI Bridge
+ 0018 TR Auto LANstreamer
+ 001b GXT-150P
+ 001c Carrera
+ 001d 82G2675
+ 0020 GXT1000 Graphics Adapter
+ 0022 IBM27-82351
+ 002d Python
+# [official name in AIX 5]
+ 002e SCSI RAID Adapter [ServeRAID]
+ 1014 002e ServeRAID-3x
+ 1014 022e ServeRAID-4H
+ 0031 2 Port Serial Adapter
+# AS400 iSeries PCI sync serial card
+ 1014 0031 2721 WAN IOA - 2 Port Sync Serial Adapter
+ 0036 Miami
+ 0037 82660 CPU to PCI Bridge
+ 003a CPU to PCI Bridge
+ 003c GXT250P/GXT255P Graphics Adapter
+ 003e 16/4 Token ring UTP/STP controller
+ 1014 003e Token-Ring Adapter
+ 1014 00cd Token-Ring Adapter + Wake-On-LAN
+ 1014 00ce 16/4 Token-Ring Adapter 2
+ 1014 00cf 16/4 Token-Ring Adapter Special
+ 1014 00e4 High-Speed 100/16/4 Token-Ring Adapter
+ 1014 00e5 16/4 Token-Ring Adapter 2 + Wake-On-LAN
+ 1014 016d iSeries 2744 Card
+ 0045 SSA Adapter
+ 0046 MPIC interrupt controller
+ 0047 PCI to PCI Bridge
+ 0048 PCI to PCI Bridge
+ 0049 Warhead SCSI Controller
+ 004e ATM Controller (14104e00)
+ 004f ATM Controller (14104f00)
+ 0050 ATM Controller (14105000)
+ 0053 25 MBit ATM Controller
+ 0054 GXT500P/GXT550P Graphics Adapter
+ 0057 MPEG PCI Bridge
+ 005c i82557B 10/100
+ 005e GXT800P Graphics Adapter
+ 007c ATM Controller (14107c00)
+ 007d 3780IDSP [MWave]
+ 008b EADS PCI to PCI Bridge
+ 008e GXT3000P Graphics Adapter
+ 0090 GXT 3000P
+ 1014 008e GXT-3000P
+ 0091 SSA Adapter
+ 0095 20H2999 PCI Docking Bridge
+ 0096 Chukar chipset SCSI controller
+ 1014 0097 iSeries 2778 DASD IOA
+ 1014 0098 iSeries 2763 DASD IOA
+ 1014 0099 iSeries 2748 DASD IOA
+ 009f PCI 4758 Cryptographic Accelerator
+ 00a5 ATM Controller (1410a500)
+ 00a6 ATM 155MBPS MM Controller (1410a600)
+ 00b7 256-bit Graphics Rasterizer [Fire GL1]
+ 1092 00b8 FireGL1 AGP 32Mb
+ 00b8 GXT2000P Graphics Adapter
+ 00be ATM 622MBPS Controller (1410be00)
+ 00dc Advanced Systems Management Adapter (ASMA)
+ 00fc CPC710 Dual Bridge and Memory Controller (PCI-64)
+ 0104 Gigabit Ethernet-SX Adapter
+ 0105 CPC710 Dual Bridge and Memory Controller (PCI-32)
+ 010f Remote Supervisor Adapter (RSA)
+ 0142 Yotta Video Compositor Input
+ 1014 0143 Yotta Input Controller (ytin)
+ 0144 Yotta Video Compositor Output
+ 1014 0145 Yotta Output Controller (ytout)
+ 0156 405GP PLB to PCI Bridge
+ 015e 622Mbps ATM PCI Adapter
+ 0160 64bit/66MHz PCI ATM 155 MMF
+ 016e GXT4000P Graphics Adapter
+ 0170 GXT6000P Graphics Adapter
+ 017d GXT300P Graphics Adapter
+ 0180 Snipe chipset SCSI controller
+ 1014 0241 iSeries 2757 DASD IOA
+ 1014 0264 Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
+ 0188 EADS-X PCI-X to PCI-X Bridge
+ 01a7 PCI-X to PCI-X Bridge
+ 01bd ServeRAID Controller
+ 1014 01be ServeRAID-4M
+ 1014 01bf ServeRAID-4L
+ 1014 0208 ServeRAID-4Mx
+ 1014 020e ServeRAID-4Lx
+ 1014 022e ServeRAID-4H
+ 1014 0258 ServeRAID-5i
+ 1014 0259 ServeRAID-5i
+ 01c1 64bit/66MHz PCI ATM 155 UTP
+ 01e6 Cryptographic Accelerator
+ 01ff 10/100 Mbps Ethernet
+ 0219 Multiport Serial Adapter
+ 1014 021a Dual RVX
+ 1014 0251 Internal Modem/RVX
+ 1014 0252 Quad Internal Modem
+ 021b GXT6500P Graphics Adapter
+ 021c GXT4500P Graphics Adapter
+ 0233 GXT135P Graphics Adapter
+ 0266 PCI-X Dual Channel SCSI
+ 0268 Gigabit Ethernet-SX Adapter (PCI-X)
+ 0269 10/100/1000 Base-TX Ethernet Adapter (PCI-X)
+ 028c Citrine chipset SCSI controller
+ 1014 028d Dual Channel PCI-X DDR SAS RAID Adapter (572E)
+ 1014 02be Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
+ 1014 02c0 Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
+ 1014 030d PCI-X DDR Auxiliary Cache Adapter (575B)
+ 02a1 Calgary PCI-X Host Bridge
+ 02bd Obsidian chipset SCSI controller
+ 1014 02c1 PCI-X DDR 3Gb SAS Adapter (572A/572C)
+ 1014 02c2 PCI-X DDR 3Gb SAS RAID Adapter (572B/571D)
+ 0302 Winnipeg PCI-X Host Bridge
+ 0308 CalIOC2 PCI-E Root Port
+ 0314 ZISC 036 Neural accelerator card
+ 3022 QLA3022 Network Adapter
+ 4022 QLA3022 Network Adapter
+ ffff MPIC-2 interrupt controller
+1015 LSI Logic Corp of Canada
+1016 ICL Personal Systems
+1017 SPEA Software AG
+ 5343 SPEA 3D Accelerator
+1018 Unisys Systems
+1019 Elitegroup Computer Systems
+101a AT&T GIS (NCR)
+ 0005 100VG ethernet
+101b Vitesse Semiconductor
+101c Western Digital
+ 0193 33C193A
+ 0196 33C196A
+ 0197 33C197A
+ 0296 33C296A
+ 3193 7193
+ 3197 7197
+ 3296 33C296A
+ 4296 34C296
+ 9710 Pipeline 9710
+ 9712 Pipeline 9712
+ c24a 90C
+101e American Megatrends Inc.
+ 0009 MegaRAID 428 Ultra RAID Controller (rev 03)
+ 1960 MegaRAID
+ 101e 0471 MegaRAID 471 Enterprise 1600 RAID Controller
+ 101e 0475 MegaRAID 475 Express 500/500LC RAID Controller
+ 101e 0477 MegaRAID 477 Elite 3100 RAID Controller
+ 101e 0493 MegaRAID 493 Elite 1600 RAID Controller
+ 101e 0494 MegaRAID 494 Elite 1650 RAID Controller
+ 101e 0503 MegaRAID 503 Enterprise 1650 RAID Controller
+ 101e 0511 MegaRAID 511 i4 IDE RAID Controller
+ 101e 0522 MegaRAID 522 i4133 RAID Controller
+ 1028 0471 PowerEdge RAID Controller 3/QC
+ 1028 0475 PowerEdge RAID Controller 3/SC
+ 1028 0493 PowerEdge RAID Controller 3/DC
+ 1028 0511 PowerEdge Cost Effective RAID Controller ATA100/4Ch
+ 103c 60e7 NetRAID-1M
+ 9010 MegaRAID 428 Ultra RAID Controller
+ 9030 EIDE Controller
+ 9031 EIDE Controller
+ 9032 EIDE & SCSI Controller
+ 9033 SCSI Controller
+ 9040 Multimedia card
+ 9060 MegaRAID 434 Ultra GT RAID Controller
+ 9063 MegaRAC
+ 101e 0767 Dell Remote Assistant Card 2
+101f PictureTel
+1020 Hitachi Computer Products
+1021 OKI Electric Industry Co. Ltd.
+1022 Advanced Micro Devices [AMD]
+ 1100 K8 [Athlon64/Opteron] HyperTransport Technology Configuration
+ 1101 K8 [Athlon64/Opteron] Address Map
+ 1102 K8 [Athlon64/Opteron] DRAM Controller
+ 1103 K8 [Athlon64/Opteron] Miscellaneous Control
+ 2000 79c970 [PCnet32 LANCE]
+ 1014 2000 NetFinity 10/100 Fast Ethernet
+ 1022 2000 PCnet - Fast 79C971
+ 103c 104c Ethernet with LAN remote power Adapter
+ 103c 1064 Ethernet with LAN remote power Adapter
+ 103c 1065 Ethernet with LAN remote power Adapter
+ 103c 106c Ethernet with LAN remote power Adapter
+ 103c 106e Ethernet with LAN remote power Adapter
+ 103c 10ea Ethernet with LAN remote power Adapter
+ 1113 1220 EN1220 10/100 Fast Ethernet
+ 1259 2450 AT-2450 10/100 Fast Ethernet
+ 1259 2454 AT-2450v4 10Mb Ethernet Adapter
+ 1259 2700 AT-2700TX 10/100 Fast Ethernet
+ 1259 2701 AT-2700FX 100Mb Ethernet
+ 1259 2702 AT-2700FTX 10/100 Mb Fiber/Copper Fast Ethernet
+ 1259 2703 AT-2701FX
+ 1259 2704 AT-2701FTX 10/100 Mb Fiber/Copper Fast Ethernet
+ 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ 4c53 1010 CP5/CR6 mainboard
+ 4c53 1020 VR6 mainboard
+ 4c53 1030 PC5 mainboard
+ 4c53 1040 CL7 mainboard
+ 4c53 1060 PC7 mainboard
+ 2001 79c978 [HomePNA]
+ 1092 0a78 Multimedia Home Network Adapter
+ 1668 0299 ActionLink Home Network Adapter
+ 2003 Am 1771 MBW [Alchemy]
+ 2020 53c974 [PCscsi]
+ 2040 79c974
+ 2081 Geode LX Video
+ 2082 Geode LX AES Security Block
+ 208f CS5536 GeodeLink PCI South Bridge
+ 2090 CS5536 [Geode companion] ISA
+ 2091 CS5536 [Geode companion] FLASH
+ 2093 CS5536 [Geode companion] Audio
+ 2094 CS5536 [Geode companion] OHC
+ 2095 CS5536 [Geode companion] EHC
+ 2096 CS5536 [Geode companion] UDC
+ 2097 CS5536 [Geode companion] UOC
+ 209a CS5536 [Geode companion] IDE
+ 3000 ELanSC520 Microcontroller
+ 7006 AMD-751 [Irongate] System Controller
+ 7007 AMD-751 [Irongate] AGP Bridge
+ 700a AMD-IGR4 AGP Host to PCI Bridge
+ 700b AMD-IGR4 PCI to PCI Bridge
+ 700c AMD-760 MP [IGD4-2P] System Controller
+ 700d AMD-760 MP [IGD4-2P] AGP Bridge
+ 700e AMD-760 [IGD4-1P] System Controller
+ 700f AMD-760 [IGD4-1P] AGP Bridge
+ 7400 AMD-755 [Cobra] ISA
+ 7401 AMD-755 [Cobra] IDE
+ 7403 AMD-755 [Cobra] ACPI
+ 7404 AMD-755 [Cobra] USB
+ 7408 AMD-756 [Viper] ISA
+ 7409 AMD-756 [Viper] IDE
+ 740b AMD-756 [Viper] ACPI
+ 740c AMD-756 [Viper] USB
+ 7410 AMD-766 [ViperPlus] ISA
+ 7411 AMD-766 [ViperPlus] IDE
+ 7413 AMD-766 [ViperPlus] ACPI
+ 7414 AMD-766 [ViperPlus] USB
+ 7440 AMD-768 [Opus] ISA
+ 1043 8044 A7M-D Mainboard
+ 7441 AMD-768 [Opus] IDE
+ 7443 AMD-768 [Opus] ACPI
+ 1043 8044 A7M-D Mainboard
+ 7445 AMD-768 [Opus] Audio
+ 7446 AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible)
+ 7448 AMD-768 [Opus] PCI
+ 7449 AMD-768 [Opus] USB
+ 7450 AMD-8131 PCI-X Bridge
+ 7451 AMD-8131 PCI-X IOAPIC
+ 7454 AMD-8151 System Controller
+ 7455 AMD-8151 AGP Bridge
+ 7458 AMD-8132 PCI-X Bridge
+ 7459 AMD-8132 PCI-X IOAPIC
+ 7460 AMD-8111 PCI
+ 161f 3017 HDAMB
+ 7461 AMD-8111 USB
+ 7462 AMD-8111 Ethernet
+ 7464 AMD-8111 USB
+ 161f 3017 HDAMB
+ 7468 AMD-8111 LPC
+ 161f 3017 HDAMB
+ 7469 AMD-8111 IDE
+ 1022 2b80 AMD-8111 IDE [Quartet]
+ 161f 3017 HDAMB
+ 746a AMD-8111 SMBus 2.0
+ 746b AMD-8111 ACPI
+ 161f 3017 HDAMB
+ 746d AMD-8111 AC97 Audio
+ 161f 3017 HDAMB
+ 746e AMD-8111 MC97 Modem
+ 756b AMD-8111 ACPI
+1023 Trident Microsystems
+ 0194 82C194
+ 2000 4DWave DX
+ 2001 4DWave NX
+ 122d 1400 Trident PCI288-Q3DII (NX)
+ 2100 CyberBlade XP4m32
+ 2200 XGI Volari XP5
+ 8400 CyberBlade/i7
+ 1023 8400 CyberBlade i7 AGP
+ 8420 CyberBlade/i7d
+ 0e11 b15a CyberBlade i7 AGP
+ 8500 CyberBlade/i1
+ 8520 CyberBlade i1
+ 0e11 b16e CyberBlade i1 AGP
+ 1023 8520 CyberBlade i1 AGP
+ 8620 CyberBlade/i1
+ 1014 0502 ThinkPad R30/T30
+ 1014 1025 Travelmate 352TE
+ 8820 CyberBlade XPAi1
+ 9320 TGUI 9320
+ 9350 GUI Accelerator
+ 9360 Flat panel GUI Accelerator
+ 9382 Cyber 9382 [Reference design]
+ 9383 Cyber 9383 [Reference design]
+ 9385 Cyber 9385 [Reference design]
+ 9386 Cyber 9386
+ 9388 Cyber 9388
+ 9397 Cyber 9397
+ 939a Cyber 9397DVD
+ 9420 TGUI 9420
+ 9430 TGUI 9430
+ 9440 TGUI 9440
+ 9460 TGUI 9460
+ 9470 TGUI 9470
+ 9520 Cyber 9520
+ 9525 Cyber 9525
+ 10cf 1094 Lifebook C6155
+ 9540 Cyber 9540
+ 9660 TGUI 9660/938x/968x
+ 9680 TGUI 9680
+ 9682 TGUI 9682
+ 9683 TGUI 9683
+ 9685 ProVIDIA 9685
+ 9750 3DImage 9750
+ 1014 9750 3DImage 9750
+ 1023 9750 3DImage 9750
+ 9753 TGUI 9753
+ 9754 TGUI 9754
+ 9759 TGUI 975
+ 9783 TGUI 9783
+ 9785 TGUI 9785
+ 9850 3DImage 9850
+ 9880 Blade 3D PCI/AGP
+ 1023 9880 Blade 3D
+ 9910 CyberBlade/XP
+ 9930 CyberBlade/XPm
+1024 Zenith Data Systems
+1025 Acer Incorporated [ALI]
+ 1435 M1435
+ 1445 M1445
+ 1449 M1449
+ 1451 M1451
+ 1461 M1461
+ 1489 M1489
+ 1511 M1511
+ 1512 ALI M1512 Aladdin
+ 1513 M1513
+ 1521 ALI M1521 Aladdin III CPU Bridge
+ 10b9 1521 ALI M1521 Aladdin III CPU Bridge
+ 1523 ALI M1523 ISA Bridge
+ 10b9 1523 ALI M1523 ISA Bridge
+ 1531 M1531 Northbridge [Aladdin IV/IV+]
+ 1533 M1533 PCI-to-ISA Bridge
+ 10b9 1533 ALI M1533 Aladdin IV/V ISA South Bridge
+ 1535 M1535 PCI Bridge + Super I/O + FIR
+ 1541 M1541 Northbridge [Aladdin V]
+ 10b9 1541 ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
+ 1542 M1542 Northbridge [Aladdin V]
+ 1543 M1543 PCI-to-ISA Bridge + Super I/O + FIR
+ 1561 M1561 Northbridge [Aladdin 7]
+ 1621 M1621 Northbridge [Aladdin-Pro II]
+ 1631 M1631 Northbridge+3D Graphics [Aladdin TNT2]
+ 1641 M1641 Northbridge [Aladdin-Pro IV]
+ 1647 M1647 [MaGiK1] PCI North Bridge
+ 1671 M1671 Northbridge [ALADDiN-P4]
+ 1672 Northbridge [CyberALADDiN-P4]
+ 3141 M3141
+ 3143 M3143
+ 3145 M3145
+ 3147 M3147
+ 3149 M3149
+ 3151 M3151
+ 3307 M3307 MPEG-I Video Controller
+ 3309 M3309 MPEG-II Video w/ Software Audio Decoder
+ 3321 M3321 MPEG-II Audio/Video Decoder
+ 5212 M4803
+ 5215 ALI PCI EIDE Controller
+ 5217 M5217H
+ 5219 M5219
+ 5225 M5225
+ 5229 M5229
+ 5235 M5235
+ 5237 M5237 PCI USB Host Controller
+ 5240 EIDE Controller
+ 5241 PCMCIA Bridge
+ 5242 General Purpose Controller
+ 5243 PCI to PCI Bridge Controller
+ 5244 Floppy Disk Controller
+ 5247 M1541 PCI to PCI Bridge
+ 5251 M5251 P1394 Controller
+ 5427 PCI to AGP Bridge
+ 5451 M5451 PCI AC-Link Controller Audio Device
+ 5453 M5453 PCI AC-Link Controller Modem Device
+ 7101 M7101 PCI PMU Power Management Controller
+ 10b9 7101 M7101 PCI PMU Power Management Controller
+1028 Dell
+ 0001 PowerEdge Expandable RAID Controller 2/Si
+ 1028 0001 PowerEdge 2400
+ 0002 PowerEdge Expandable RAID Controller 3/Di
+ 1028 0002 PowerEdge 4400
+ 0003 PowerEdge Expandable RAID Controller 3/Si
+ 1028 0003 PowerEdge 2450
+ 0006 PowerEdge Expandable RAID Controller 3/Di
+ 0007 Remote Access Card III
+ 0008 Remote Access Card III
+ 0009 Remote Access Card III: BMC/SMIC device not present
+ 000a PowerEdge Expandable RAID Controller 3/Di
+ 000c Embedded Remote Access or ERA/O
+ 000d Embedded Remote Access: BMC/SMIC device
+ 000e PowerEdge Expandable RAID controller 4/Di
+ 000f PowerEdge Expandable RAID controller 4/Di
+ 0010 Remote Access Card 4
+ 0011 Remote Access Card 4 Daughter Card
+ 0012 Remote Access Card 4 Daughter Card Virtual UART
+ 0013 PowerEdge Expandable RAID controller 4
+ 1028 016c PowerEdge Expandable RAID Controller 4e/Si
+ 1028 016d PowerEdge Expandable RAID Controller 4e/Di
+ 1028 016e PowerEdge Expandable RAID Controller 4e/Di
+ 1028 016f PowerEdge Expandable RAID Controller 4e/Di
+ 1028 0170 PowerEdge Expandable RAID Controller 4e/Di
+ 0014 Remote Access Card 4 Daughter Card SMIC interface
+ 0015 PowerEdge Expandable RAID controller 5
+1029 Siemens Nixdorf IS
+102a LSI Logic
+ 0000 HYDRA
+ 0010 ASPEN
+ 001f AHA-2940U2/U2W /7890/7891 SCSI Controllers
+ 9005 000f 2940U2W SCSI Controller
+ 9005 0106 2940U2W SCSI Controller
+ 9005 a180 2940U2W SCSI Controller
+ 00c5 AIC-7899 U160/m SCSI Controller
+ 1028 00c5 PowerEdge 2550/2650/4600
+ 00cf AIC-7899P U160/m
+ 1028 0106 PowerEdge 4600
+ 1028 0121 PowerEdge 2650
+102b Matrox Graphics, Inc.
+# DJ: I've a suspicion that 0010 is a duplicate of 0d10.
+ 0010 MGA-I [Impression?]
+ 0100 MGA 1064SG [Mystique]
+ 0518 MGA-II [Athena]
+ 0519 MGA 2064W [Millennium]
+ 051a MGA 1064SG [Mystique]
+ 102b 0100 MGA-1064SG Mystique
+ 102b 1100 MGA-1084SG Mystique
+ 102b 1200 MGA-1084SG Mystique
+ 1100 102b MGA-1084SG Mystique
+ 110a 0018 Scenic Pro C5 (D1025)
+ 051b MGA 2164W [Millennium II]
+ 102b 051b MGA-2164W Millennium II
+ 102b 1100 MGA-2164W Millennium II
+ 102b 1200 MGA-2164W Millennium II
+ 051e MGA 1064SG [Mystique] AGP
+ 051f MGA 2164W [Millennium II] AGP
+ 0520 MGA G200
+ 102b dbc2 G200 Multi-Monitor
+ 102b dbc8 G200 Multi-Monitor
+ 102b dbe2 G200 Multi-Monitor
+ 102b dbe8 G200 Multi-Monitor
+ 102b ff03 Millennium G200 SD
+ 102b ff04 Marvel G200
+ 0521 MGA G200 AGP
+ 1014 ff03 Millennium G200 AGP
+ 102b 48e9 Mystique G200 AGP
+ 102b 48f8 Millennium G200 SD AGP
+ 102b 4a60 Millennium G200 LE AGP
+ 102b 4a64 Millennium G200 AGP
+ 102b c93c Millennium G200 AGP
+ 102b c9b0 Millennium G200 AGP
+ 102b c9bc Millennium G200 AGP
+ 102b ca60 Millennium G250 LE AGP
+ 102b ca6c Millennium G250 AGP
+ 102b dbbc Millennium G200 AGP
+ 102b dbc2 Millennium G200 MMS (Dual G200)
+ 102b dbc3 G200 Multi-Monitor
+ 102b dbc8 Millennium G200 MMS (Dual G200)
+ 102b dbd2 G200 Multi-Monitor
+ 102b dbd3 G200 Multi-Monitor
+ 102b dbd4 G200 Multi-Monitor
+ 102b dbd5 G200 Multi-Monitor
+ 102b dbd8 G200 Multi-Monitor
+ 102b dbd9 G200 Multi-Monitor
+ 102b dbe2 Millennium G200 MMS (Quad G200)
+ 102b dbe3 G200 Multi-Monitor
+ 102b dbe8 Millennium G200 MMS (Quad G200)
+ 102b dbf2 G200 Multi-Monitor
+ 102b dbf3 G200 Multi-Monitor
+ 102b dbf4 G200 Multi-Monitor
+ 102b dbf5 G200 Multi-Monitor
+ 102b dbf8 G200 Multi-Monitor
+ 102b dbf9 G200 Multi-Monitor
+ 102b f806 Mystique G200 Video AGP
+ 102b ff00 MGA-G200 AGP
+ 102b ff02 Mystique G200 AGP
+ 102b ff03 Millennium G200 AGP
+ 102b ff04 Marvel G200 AGP
+ 110a 0032 MGA-G200 AGP
+ 0522 MGA G200e [Pilot] ServerEngines (SEP1)
+ 0525 MGA G400/G450
+ 0e11 b16f MGA-G400 AGP
+ 102b 0328 Millennium G400 16Mb SDRAM
+ 102b 0338 Millennium G400 16Mb SDRAM
+ 102b 0378 Millennium G400 32Mb SDRAM
+ 102b 0541 Millennium G450 Dual Head
+ 102b 0542 Millennium G450 Dual Head LX
+ 102b 0543 Millennium G450 Single Head LX
+ 102b 0641 Millennium G450 32Mb SDRAM Dual Head
+ 102b 0642 Millennium G450 32Mb SDRAM Dual Head LX
+ 102b 0643 Millennium G450 32Mb SDRAM Single Head LX
+ 102b 07c0 Millennium G450 Dual Head LE
+ 102b 07c1 Millennium G450 SDR Dual Head LE
+ 102b 0d41 Millennium G450 Dual Head PCI
+ 102b 0d42 Millennium G450 Dual Head LX PCI
+ 102b 0d43 Millennium G450 32Mb Dual Head PCI
+ 102b 0e00 Marvel G450 eTV
+ 102b 0e01 Marvel G450 eTV
+ 102b 0e02 Marvel G450 eTV
+ 102b 0e03 Marvel G450 eTV
+ 102b 0f80 Millennium G450 Low Profile
+ 102b 0f81 Millennium G450 Low Profile
+ 102b 0f82 Millennium G450 Low Profile DVI
+ 102b 0f83 Millennium G450 Low Profile DVI
+ 102b 19d8 Millennium G400 16Mb SGRAM
+ 102b 19f8 Millennium G400 32Mb SGRAM
+ 102b 2159 Millennium G400 Dual Head 16Mb
+ 102b 2179 Millennium G400 MAX/Dual Head 32Mb
+ 102b 217d Millennium G400 Dual Head Max
+ 102b 23c0 Millennium G450
+ 102b 23c1 Millennium G450
+ 102b 23c2 Millennium G450 DVI
+ 102b 23c3 Millennium G450 DVI
+ 102b 2f58 Millennium G400
+ 102b 2f78 Millennium G400
+ 102b 3693 Marvel G400 AGP
+ 102b 5dd0 4Sight II
+ 102b 5f50 4Sight II
+ 102b 5f51 4Sight II
+ 102b 5f52 4Sight II
+ 102b 9010 Millennium G400 Dual Head
+ 1458 0400 GA-G400
+ 1705 0001 Millennium G450 32MB SGRAM
+ 1705 0002 Millennium G450 16MB SGRAM
+ 1705 0003 Millennium G450 32MB
+ 1705 0004 Millennium G450 16MB
+ 0527 MGA Parhelia AGP
+ 102b 0840 Parhelia 128Mb
+ 102b 0850 Parhelia 256MB AGP 4X
+ 0528 Parhelia 8X
+ 102b 1020 Parhelia 128MB
+ 102b 1030 Parhelia 256 MB Dual DVI
+ 102b 14e1 Parhelia PCI 256MB
+ 102b 2021 QID Pro
+ 0d10 MGA Ultima/Impression
+ 1000 MGA G100 [Productiva]
+ 102b ff01 Productiva G100
+ 102b ff05 Productiva G100 Multi-Monitor
+ 1001 MGA G100 [Productiva] AGP
+ 102b 1001 MGA-G100 AGP
+ 102b ff00 MGA-G100 AGP
+ 102b ff01 MGA-G100 Productiva AGP
+ 102b ff03 Millennium G100 AGP
+ 102b ff04 MGA-G100 AGP
+ 102b ff05 MGA-G100 Productiva AGP Multi-Monitor
+ 110a 001e MGA-G100 AGP
+ 2007 MGA Mistral
+ 2527 MGA G550 AGP
+ 102b 0f83 Millennium G550
+ 102b 0f84 Millennium G550 Dual Head DDR 32Mb
+ 102b 1e41 Millennium G550
+ 2537 Millenium P650/P750
+ 102b 1820 Millennium P750 64MB
+ 102b 1830 Millennium P650 64MB
+ 102b 1c10 QID 128MB
+ 102b 2811 Millennium P650 Low-profile PCI 64MB
+ 102b 2c11 QID Low-profile PCI
+ 2538 Millenium P650 PCIe
+ 102b 08c7 Millennium P650 PCIe 128MB
+ 102b 0907 Millennium P650 PCIe 64MB
+ 102b 1047 Millennium P650 LP PCIe 128MB
+ 102b 1087 Millennium P650 LP PCIe 64MB
+ 102b 2538 Parhelia APVe
+ 102b 3007 QID Low-profile PCIe
+ 4536 VIA Framegrabber
+ 4cdc Morphis Vision System Jpeg2000
+ 4fc5 Morphis Vision System
+ 5e10 Morphis Vision System Aux/IO
+ 6573 Shark 10/100 Multiport SwitchNIC
+102c Chips and Technologies
+ 00b8 F64310
+ 00c0 F69000 HiQVideo
+ 102c 00c0 F69000 HiQVideo
+ 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ 4c53 1010 CP5/CR6 mainboard
+ 4c53 1020 VR6 mainboard
+ 4c53 1030 PC5 mainboard
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ 00d0 F65545
+ 00d8 F65545
+ 00dc F65548
+ 00e0 F65550
+ 00e4 F65554
+ 00e5 F65555 HiQVPro
+ 0e11 b049 Armada 1700 Laptop Display Controller
+ 1179 0001 Satellite Pro
+ 00f0 F68554
+ 00f4 F68554 HiQVision
+ 00f5 F68555
+ 0c30 F69030
+ 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ 4c53 1080 CT8 mainboard
+102d Wyse Technology Inc.
+ 50dc 3328 Audio
+102e Olivetti Advanced Technology
+102f Toshiba America
+ 0009 r4x00
+ 000a TX3927 MIPS RISC PCI Controller
+ 0020 ATM Meteor 155
+ 102f 00f8 ATM Meteor 155
+ 0030 TC35815CF PCI 10/100 Mbit Ethernet Controller
+ 0031 TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL
+ 0105 TC86C001 [goku-s] IDE
+ 0106 TC86C001 [goku-s] USB 1.1 Host
+ 0107 TC86C001 [goku-s] USB Device Controller
+ 0108 TC86C001 [goku-s] I2C/SIO/GPIO Controller
+ 0180 TX4927/38 MIPS RISC PCI Controller
+ 0181 TX4925 MIPS RISC PCI Controller
+ 0182 TX4937 MIPS RISC PCI Controller
+1030 TMC Research
+1031 Miro Computer Products AG
+ 5601 DC20 ASIC
+ 5607 Video I/O & motion JPEG compressor
+ 5631 Media 3D
+ 6057 MiroVideo DC10/DC30+
+1032 Compaq
+1033 NEC Corporation
+ 0000 Vr4181A USB Host or Function Control Unit
+ 0001 PCI to 486-like bus Bridge
+ 0002 PCI to VL98 Bridge
+ 0003 ATM Controller
+ 0004 R4000 PCI Bridge
+ 0005 PCI to 486-like bus Bridge
+ 0006 PC-9800 Graphic Accelerator
+ 0007 PCI to UX-Bus Bridge
+ 0008 PC-9800 Graphic Accelerator
+ 0009 PCI to PC9800 Core-Graph Bridge
+ 0016 PCI to VL Bridge
+ 001a [Nile II]
+ 0021 Vrc4373 [Nile I]
+ 0029 PowerVR PCX1
+ 002a PowerVR 3D
+ 002c Star Alpha 2
+ 002d PCI to C-bus Bridge
+ 0035 USB
+ 1033 0035 Hama USB 2.0 CardBus
+ 1179 0001 USB
+ 12ee 7000 Root Hub
+ 14c2 0105 PTI-205N USB 2.0 Host Controller
+ 1799 0001 Root Hub
+ 1931 000a GlobeTrotter Fusion Quad Lite (PPP data)
+ 1931 000b GlobeTrotter Fusion Quad Lite (GSM data)
+ 807d 0035 PCI-USB2 (OHCI subsystem)
+ 003b PCI to C-bus Bridge
+ 003e NAPCCARD Cardbus Controller
+ 0046 PowerVR PCX2 [midas]
+ 005a Vrc5074 [Nile 4]
+ 0063 Firewarden
+ 0067 PowerVR Neon 250 Chipset
+ 1010 0020 PowerVR Neon 250 AGP 32Mb
+ 1010 0080 PowerVR Neon 250 AGP 16Mb
+ 1010 0088 PowerVR Neon 250 16Mb
+ 1010 0090 PowerVR Neon 250 AGP 16Mb
+ 1010 0098 PowerVR Neon 250 16Mb
+ 1010 00a0 PowerVR Neon 250 AGP 32Mb
+ 1010 00a8 PowerVR Neon 250 32Mb
+ 1010 0120 PowerVR Neon 250 AGP 32Mb
+ 0072 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
+ 0074 56k Voice Modem
+ 1033 8014 RCV56ACF 56k Voice Modem
+ 009b Vrc5476
+ 00a5 VRC4173
+ 00a6 VRC5477 AC97
+ 00cd IEEE 1394 [OrangeLink] Host Controller
+ 12ee 8011 Root hub
+ 00ce IEEE 1394 Host Controller
+ 00df Vr4131
+ 00e0 USB 2.0
+ 12ee 7001 Root hub
+ 14c2 0205 PTI-205N USB 2.0 Host Controller
+ 1799 0002 Root Hub
+ 807d 1043 PCI-USB2 (EHCI subsystem)
+ 00e7 IEEE 1394 Host Controller
+ 00f2 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
+ 00f3 uPD6113x Multimedia Decoder/Processor [EMMA2]
+ 010c VR7701
+ 0125 uPD720400 PCI Express - PCI/PCI-X Bridge
+1034 Framatome Connectors USA Inc.
+1035 Comp. & Comm. Research Lab
+1036 Future Domain Corp.
+ 0000 TMC-18C30 [36C70]
+1037 Hitachi Micro Systems
+1038 AMP, Inc
+1039 Silicon Integrated Systems [SiS]
+ 0001 Virtual PCI-to-PCI bridge (AGP)
+ 0002 SG86C202
+ 0003 SiS AGP Port (virtual PCI-to-PCI bridge)
+ 0004 PCI-to-PCI bridge
+ 0006 85C501/2/3
+ 0008 SiS85C503/5513 (LPC Bridge)
+ 0009 ACPI
+ 000a PCI-to-PCI bridge
+ 0016 SiS961/2 SMBus Controller
+ 0018 SiS85C503/5513 (LPC Bridge)
+ 0180 RAID bus controller 180 SATA/PATA [SiS]
+ 0181 SATA
+ 0182 182 SATA/RAID Controller
+ 0190 190 Gigabit Ethernet Adapter
+ 0191 191 Gigabit Ethernet Adapter
+ 0200 5597/5598/6326 VGA
+ 1039 0000 SiS5597 SVGA (Shared RAM)
+ 0204 82C204
+ 0205 SG86C205
+ 0300 300/305 PCI/AGP VGA Display Adapter
+ 107d 2720 Leadtek WinFast VR300
+ 0310 315H PCI/AGP VGA Display Adapter
+ 0315 315 PCI/AGP VGA Display Adapter
+ 0325 315PRO PCI/AGP VGA Display Adapter
+ 0330 330 [Xabre] PCI/AGP VGA Display Adapter
+ 0406 85C501/2
+ 0496 85C496
+ 0530 530 Host
+ 0540 540 Host
+ 0550 550 Host
+ 0597 5513C
+ 0601 85C601
+ 0620 620 Host
+ 0630 630 Host
+ 0633 633 Host
+ 0635 635 Host
+ 0645 SiS645 Host & Memory & AGP Controller
+ 0646 SiS645DX Host & Memory & AGP Controller
+ 0648 645xx
+ 0650 650/M650 Host
+ 0651 651 Host
+ 0655 655 Host
+ 0660 660 Host
+ 0661 661FX/M661FX/M661MX Host
+ 0730 730 Host
+ 0733 733 Host
+ 0735 735 Host
+ 0740 740 Host
+ 0741 741/741GX/M741 Host
+ 0745 745 Host
+ 0746 746 Host
+ 0755 755 Host
+ 0760 760/M760 Host
+ 0761 761/M761 Host
+ 0900 SiS900 PCI Fast Ethernet
+ 1019 0a14 K7S5A motherboard
+ 1039 0900 SiS900 10/100 Ethernet Adapter
+ 1043 8035 CUSI-FX motherboard
+ 0961 SiS961 [MuTIOL Media IO]
+ 0962 SiS962 [MuTIOL Media IO]
+ 0963 SiS963 [MuTIOL Media IO]
+ 0964 SiS964 [MuTIOL Media IO]
+ 0965 SiS965 [MuTIOL Media IO]
+ 3602 83C602
+ 5107 5107
+ 5300 SiS540 PCI Display Adapter
+ 5315 550 PCI/AGP VGA Display Adapter
+ 5401 486 PCI Chipset
+ 5511 5511/5512
+ 5513 5513 [IDE]
+ 1019 0970 P6STP-FL motherboard
+ 1039 5513 SiS5513 EIDE Controller (A,B step)
+ 1043 8035 CUSI-FX motherboard
+ 5517 5517
+ 5571 5571
+ 5581 5581 Pentium Chipset
+ 5582 5582
+ 5591 5591/5592 Host
+ 5596 5596 Pentium Chipset
+ 5597 5597 [SiS5582]
+ 5600 5600 Host
+ 6204 Video decoder & MPEG interface
+ 6205 VGA Controller
+ 6236 6236 3D-AGP
+ 6300 630/730 PCI/AGP VGA Display Adapter
+ 1019 0970 P6STP-FL motherboard
+ 1043 8035 CUSI-FX motherboard
+ 6306 530/620 PCI/AGP VGA Display Adapter
+ 1039 6306 SiS530,620 GUI Accelerator+3D
+ 6325 65x/M650/740 PCI/AGP VGA Display Adapter
+ 6326 86C326 5598/6326
+ 1039 6326 SiS6326 GUI Accelerator
+ 1092 0a50 SpeedStar A50
+ 1092 0a70 SpeedStar A70
+ 1092 4910 SpeedStar A70
+ 1092 4920 SpeedStar A70
+ 1569 6326 SiS6326 GUI Accelerator
+ 6330 661/741/760/761 PCI/AGP VGA Display Adapter
+ 1039 6330 [M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
+ 7001 USB 1.0 Controller
+ 1019 0a14 K7S5A motherboard
+ 1039 7000 Onboard USB Controller
+ 1462 5470 K7SOM+ 5.2C Motherboard
+ 7002 USB 2.0 Controller
+ 1509 7002 Onboard USB Controller
+ 7007 FireWire Controller
+ 7012 AC'97 Sound Controller
+ 15bd 1001 DFI 661FX motherboard
+# There are may be different modem codecs here (Intel537 compatible and incompatible)
+ 7013 AC'97 Modem Controller
+ 7016 SiS7016 PCI Fast Ethernet Adapter
+ 1039 7016 SiS7016 10/100 Ethernet Adapter
+ 7018 SiS PCI Audio Accelerator
+ 1014 01b6 SiS PCI Audio Accelerator
+ 1014 01b7 SiS PCI Audio Accelerator
+ 1019 7018 SiS PCI Audio Accelerator
+ 1025 000e SiS PCI Audio Accelerator
+ 1025 0018 SiS PCI Audio Accelerator
+ 1039 7018 SiS PCI Audio Accelerator
+ 1043 800b SiS PCI Audio Accelerator
+ 1054 7018 SiS PCI Audio Accelerator
+ 107d 5330 SiS PCI Audio Accelerator
+ 107d 5350 SiS PCI Audio Accelerator
+ 1170 3209 SiS PCI Audio Accelerator
+ 1462 400a SiS PCI Audio Accelerator
+ 14a4 2089 SiS PCI Audio Accelerator
+ 14cd 2194 SiS PCI Audio Accelerator
+ 14ff 1100 SiS PCI Audio Accelerator
+ 152d 8808 SiS PCI Audio Accelerator
+ 1558 1103 SiS PCI Audio Accelerator
+ 1558 2200 SiS PCI Audio Accelerator
+ 1563 7018 SiS PCI Audio Accelerator
+ 15c5 0111 SiS PCI Audio Accelerator
+ 270f a171 SiS PCI Audio Accelerator
+ a0a0 0022 SiS PCI Audio Accelerator
+ 7019 SiS7019 Audio Accelerator
+103a Seiko Epson Corporation
+103b Tatung Co. of America
+103c Hewlett-Packard Company
+ 002a NX9000 Notebook
+ 1005 A4977A Visualize EG
+ 1008 Visualize FX
+ 1028 Tach TL Fibre Channel Host Adapter
+ 1029 Tach XL2 Fibre Channel Host Adapter
+ 107e 000f Interphase 5560 Fibre Channel Adapter
+ 9004 9210 1Gb/2Gb Family Fibre Channel Controller
+ 9004 9211 1Gb/2Gb Family Fibre Channel Controller
+ 102a Tach TS Fibre Channel Host Adapter
+ 107e 000e Interphase 5540/5541 Fibre Channel Adapter
+ 9004 9110 1Gb/2Gb Family Fibre Channel Controller
+ 9004 9111 1Gb/2Gb Family Fibre Channel Controller
+ 1030 J2585A DeskDirect 10/100VG NIC
+ 1031 J2585B HP 10/100VG PCI LAN Adapter
+ 103c 1040 J2973A DeskDirect 10BaseT NIC
+ 103c 1041 J2585B DeskDirect 10/100VG NIC
+ 103c 1042 J2970A DeskDirect 10BaseT/2 NIC
+ 1040 J2973A DeskDirect 10BaseT NIC
+ 1041 J2585B DeskDirect 10/100 NIC
+ 1042 J2970A DeskDirect 10BaseT/2 NIC
+ 1048 Diva Serial [GSP] Multiport UART
+ 103c 1049 Tosca Console
+ 103c 104a Tosca Secondary
+ 103c 104b Maestro SP2
+ 103c 1223 Superdome Console
+ 103c 1226 Keystone SP2
+ 103c 1227 Powerbar SP2
+ 103c 1282 Everest SP2
+ 103c 1301 Diva RMP3
+ 1054 PCI Local Bus Adapter
+ 1064 79C970 PCnet Ethernet Controller
+ 108b Visualize FXe
+ 10c1 NetServer Smart IRQ Router
+ 10ed TopTools Remote Control
+ 10f0 rio System Bus Adapter
+ 10f1 rio I/O Controller
+ 1200 82557B 10/100 NIC
+ 1219 NetServer PCI Hot-Plug Controller
+ 121a NetServer SMIC Controller
+ 121b NetServer Legacy COM Port Decoder
+ 121c NetServer PCI COM Port Decoder
+ 1229 zx1 System Bus Adapter
+ 122a zx1 I/O Controller
+ 122e PCI-X Local Bus Adapter
+ 127b sx1000 System Bus Adapter
+ 127c sx1000 I/O Controller
+ 1290 Auxiliary Diva Serial Port
+ 1291 Auxiliary Diva Serial Port
+ 12b4 zx1 QuickSilver AGP8x Local Bus Adapter
+ 12eb sx2000 System Bus Adapter
+ 12ec sx2000 I/O Controller
+ 12ee PCI-X 2.0 Local Bus Adapter
+ 12f8 Broadcom BCM4306 802.11b/g Wireless LAN
+ 12fa BCM4306 802.11b/g Wireless LAN Controller
+ 2910 E2910A PCIBus Exerciser
+ 2925 E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
+ 3080 Pavilion ze2028ea
+ 3085 Realtek RTL8139/8139C/8139C+
+ 3220 Hewlett-Packard Smart Array P600
+ 3230 Hewlett-Packard Smart Array Controller
+ 4030 zx2 System Bus Adapter
+ 4031 zx2 I/O Controller
+ 4037 PCIe Local Bus Adapter
+103e Solliday Engineering
+103f Synopsys/Logic Modeling Group
+1040 Accelgraphics Inc.
+1041 Computrend
+1042 Micron
+ 1000 PC Tech RZ1000
+ 1001 PC Tech RZ1001
+ 3000 Samurai_0
+ 3010 Samurai_1
+ 3020 Samurai_IDE
+1043 ASUSTeK Computer Inc.
+ 0675 ISDNLink P-IN100-ST-D
+ 0675 1704 ISDN Adapter (PCI Bus, D, C)
+ 0675 1707 ISDN Adapter (PCI Bus, DV, W)
+ 10cf 105e ISDN Adapter (PCI Bus, DV, W)
+ 0c11 A7N8X Motherboard nForce2 IDE/USB/SMBus
+ 4015 v7100 SDRAM [GeForce2 MX]
+ 4021 v7100 Combo Deluxe [GeForce2 MX + TV tuner]
+ 4057 v8200 GeForce 3
+ 8043 v8240 PAL 128M [P4T] Motherboard
+ 807b v9280/TD [Geforce4 TI4200 8X With TV-Out and DVI]
+ 8095 A7N8X Motherboard nForce2 AC97 Audio
+ 80ac A7N8X Motherboard nForce2 AGP/Memory
+ 80bb v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out]
+ 80c5 nForce3 chipset motherboard [SK8N]
+ 80df v9520 Magic/T
+ 8187 802.11a/b/g Wireless LAN Card
+ 8188 Tiger Hybrid TV Capture Device
+1044 Adaptec (formerly DPT)
+ 1012 Domino RAID Engine
+ a400 SmartCache/Raid I-IV Controller
+ a500 PCI Bridge
+ a501 SmartRAID V Controller
+ 1044 c001 PM1554U2 Ultra2 Single Channel
+ 1044 c002 PM1654U2 Ultra2 Single Channel
+ 1044 c003 PM1564U3 Ultra3 Single Channel
+ 1044 c004 PM1564U3 Ultra3 Dual Channel
+ 1044 c005 PM1554U2 Ultra2 Single Channel (NON ACPI)
+ 1044 c00a PM2554U2 Ultra2 Single Channel
+ 1044 c00b PM2654U2 Ultra2 Single Channel
+ 1044 c00c PM2664U3 Ultra3 Single Channel
+ 1044 c00d PM2664U3 Ultra3 Dual Channel
+ 1044 c00e PM2554U2 Ultra2 Single Channel (NON ACPI)
+ 1044 c00f PM2654U2 Ultra2 Single Channel (NON ACPI)
+ 1044 c014 PM3754U2 Ultra2 Single Channel (NON ACPI)
+ 1044 c015 PM3755U2B Ultra2 Single Channel (NON ACPI)
+ 1044 c016 PM3755F Fibre Channel (NON ACPI)
+ 1044 c01e PM3757U2 Ultra2 Single Channel
+ 1044 c01f PM3757U2 Ultra2 Dual Channel
+ 1044 c020 PM3767U3 Ultra3 Dual Channel
+ 1044 c021 PM3767U3 Ultra3 Quad Channel
+ 1044 c028 PM2865U3 Ultra3 Single Channel
+ 1044 c029 PM2865U3 Ultra3 Dual Channel
+ 1044 c02a PM2865F Fibre Channel
+ 1044 c03c 2000S Ultra3 Single Channel
+ 1044 c03d 2000S Ultra3 Dual Channel
+ 1044 c03e 2000F Fibre Channel
+ 1044 c046 3000S Ultra3 Single Channel
+ 1044 c047 3000S Ultra3 Dual Channel
+ 1044 c048 3000F Fibre Channel
+ 1044 c050 5000S Ultra3 Single Channel
+ 1044 c051 5000S Ultra3 Dual Channel
+ 1044 c052 5000F Fibre Channel
+ 1044 c05a 2400A UDMA Four Channel
+ 1044 c05b 2400A UDMA Four Channel DAC
+ 1044 c064 3010S Ultra3 Dual Channel
+ 1044 c065 3410S Ultra160 Four Channel
+ 1044 c066 3010S Fibre Channel
+ a511 SmartRAID V Controller
+ 1044 c032 ASR-2005S I2O Zero Channel
+ 1044 c035 ASR-2010S I2O Zero Channel
+1045 OPTi Inc.
+ a0f8 82C750 [Vendetta] USB Controller
+ c101 92C264
+ c178 92C178
+ c556 82X556 [Viper]
+ c557 82C557 [Viper-M]
+ c558 82C558 [Viper-M ISA+IDE]
+ c567 82C750 [Vendetta], device 0
+ c568 82C750 [Vendetta], device 1
+ c569 82C579 [Viper XPress+ Chipset]
+ c621 82C621 [Viper-M/N+]
+ c700 82C700 [FireStar]
+ c701 82C701 [FireStar Plus]
+ c814 82C814 [Firebridge 1]
+ c822 82C822
+ c824 82C824
+ c825 82C825 [Firebridge 2]
+ c832 82C832
+ c861 82C861
+ c895 82C895
+ c935 EV1935 ECTIVA MachOne PCIAudio
+ d568 82C825 [Firebridge 2]
+ d721 IDE [FireStar]
+1046 IPC Corporation, Ltd.
+1047 Genoa Systems Corp
+1048 Elsa AG
+ 0c60 Gladiac MX
+ 0d22 Quadro4 900XGL [ELSA GLoria4 900XGL]
+ 1000 QuickStep 1000
+ 3000 QuickStep 3000
+ 8901 Gloria XL
+ 1048 0935 GLoria XL (Virge)
+1049 Fountain Technologies, Inc.
+# # nee SGS Thomson Microelectronics
+104a STMicroelectronics
+ 0008 STG 2000X
+ 0009 STG 1764X
+ 0010 STG4000 [3D Prophet Kyro Series]
+ 0209 STPC Consumer/Industrial North- and Southbridge
+ 020a STPC Atlas/ConsumerS/Consumer IIA Northbridge
+ 0210 STPC Atlas ISA Bridge
+ 021a STPC Consumer S Southbridge
+ 021b STPC Consumer IIA Southbridge
+ 0500 ST70137 [Unicorn] ADSL DMT Transceiver
+ 0564 STPC Client Northbridge
+ 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
+ 1746 STG 1764X
+ 2774 21x4x DEC-Tulip compatible 10/100 Ethernet
+ 3520 MPEG-II decoder card
+ 55cc STPC Client Southbridge
+104b BusLogic
+ 0140 BT-946C (old) [multimaster 01]
+ 1040 BT-946C (BA80C30) [MultiMaster 10]
+ 8130 Flashpoint LT
+104c Texas Instruments
+ 0500 100 MBit LAN Controller
+ 0508 TMS380C2X Compressor Interface
+ 1000 Eagle i/f AS
+ 104c PCI1510 PC card Cardbus Controller
+ 3d04 TVP4010 [Permedia]
+ 3d07 TVP4020 [Permedia 2]
+ 1011 4d10 Comet
+ 1040 000f AccelStar II
+ 1040 0011 AccelStar II
+ 1048 0a31 WINNER 2000
+ 1048 0a32 GLoria Synergy
+ 1048 0a34 GLoria Synergy
+ 1048 0a35 GLoria Synergy
+ 1048 0a36 GLoria Synergy
+ 1048 0a43 GLoria Synergy
+ 1048 0a44 GLoria Synergy
+ 107d 2633 WinFast 3D L2300
+ 1092 0127 FIRE GL 1000 PRO
+ 1092 0136 FIRE GL 1000 PRO
+ 1092 0141 FIRE GL 1000 PRO
+ 1092 0146 FIRE GL 1000 PRO
+ 1092 0148 FIRE GL 1000 PRO
+ 1092 0149 FIRE GL 1000 PRO
+ 1092 0152 FIRE GL 1000 PRO
+ 1092 0154 FIRE GL 1000 PRO
+ 1092 0155 FIRE GL 1000 PRO
+ 1092 0156 FIRE GL 1000 PRO
+ 1092 0157 FIRE GL 1000 PRO
+ 1097 3d01 Jeronimo Pro
+ 1102 100f Graphics Blaster Extreme
+ 3d3d 0100 Reference Permedia 2 3D
+ 8000 PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
+ e4bf 1010 CF1-1-SNARE
+ e4bf 1020 CF1-2-SNARE
+ 8009 FireWire Controller
+ 104d 8032 8032 OHCI i.LINK (IEEE 1394) Controller
+ 8017 PCI4410 FireWire Controller
+ 8019 TSB12LV23 IEEE-1394 Controller
+ 11bd 000a Studio DV500-1394
+ 11bd 000e Studio DV
+ e4bf 1010 CF2-1-CYMBAL
+ 8020 TSB12LV26 IEEE-1394 Controller (Link)
+ 11bd 000f Studio DV500-1394
+ 8021 TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
+ 104d 80df Vaio PCG-FX403
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 8022 TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link)
+ 8023 TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
+ 103c 088c NC8000 laptop
+ 1043 808b K8N4-E Mainboard
+ 8024 TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
+ 8025 TSB82AA2 IEEE-1394b Link Layer Controller
+ 1458 1000 GA-K8N Ultra-9 Mainboard
+ 8026 TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
+ 1025 003c Aspire 2001WLCi (Compaq CL50 motherboard)
+ 103c 006a NX9500
+ 1043 808d A7V333 mainboard.
+ 8027 PCI4451 IEEE-1394 Controller
+ 1028 00e6 PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
+ 8029 PCI4510 IEEE-1394 Controller
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 1071 8160 MIM2900
+ 802b PCI7410,7510,7610 OHCI-Lynx Controller
+ 1028 0139 Latitude D400
+ 1028 014e PCI7410,7510,7610 OHCI-Lynx Controller (Dell Latitude D800)
+ 802e PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
+ 8031 PCIxx21/x515 Cardbus Controller
+ 1025 0080 Aspire 5024WLMi
+ 103c 099c NX6110/NC6120
+ 103c 308b MX6125
+ 8032 OHCI Compliant IEEE 1394 Host Controller
+ 1025 0080 Aspire 5024WLMi
+ 103c 099c NX6110/NC6120
+ 103c 308b MX6125
+ 8033 PCIxx21 Integrated FlashMedia Controller
+ 1025 0080 Aspire 5024WLMi
+ 103c 099c NX6110/NC6120
+ 103c 308b MX6125
+ 8034 PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Secure Digital (SD) Controller
+ 1025 0080 Aspire 5024WLMi
+ 103c 099c NX6110/NC6120
+ 103c 308b MX6125
+ 8035 PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Smart Card Controller (SMC)
+ 103c 099c NX6110/NC6120
+ 8036 PCI6515 Cardbus Controller
+ 8038 PCI6515 SmartCard Controller
+ 8039 PCIxx12 Cardbus Controller
+ 103c 309f nx9420
+ 803a PCIxx12 OHCI Compliant IEEE 1394 Host Controller
+ 103c 309f nx9420
+ 803b 5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD)
+ 103c 309f nx9420
+# Description as Windows says it
+ 803c PCIxx12 SDA Standard Compliant SD Host Controller
+ 103c 309f nx9420
+# Description as Windows says it
+ 803d PCIxx12 GemCore based SmartCard controller
+ 103c 309f nx9420
+ 8201 PCI1620 Firmware Loading Function
+ 8204 PCI7410,7510,7610 PCI Firmware Loading Function
+ 1028 0139 Latitude D400
+ 1028 014e Latitude D800
+ 8231 XIO2000(A)/XIO2200(A) PCI Express-to-PCI Bridge
+ 8235 XIO2200(A) IEEE-1394a-2000 Controller (PHY/Link)
+ 8400 ACX 100 22Mbps Wireless Interface
+ 1186 3b00 DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
+ 1186 3b01 DWL-520+ 22Mbps PCI Wireless Adapter
+ 16ab 8501 WL-8305 IEEE802.11b+ Wireless LAN PCI Adapter
+ 8401 ACX 100 22Mbps Wireless Interface
+# OK, this info is almost useless as is, but at least it's known that it's a wireless card. More info requested from reporter.
+ 9000 Wireless Interface (of unknown type)
+ 9065 TMS320DM642
+ 9066 ACX 111 54Mbps Wireless Interface
+ 104c 9066 Trendnet TEW-421PC Wireless PCI Adapter
+ 1186 3b04 DWL-G520+ Wireless PCI Adapter
+ 1186 3b05 DWL-G650+ AirPlusG+ CardBus Wireless LAN
+ 13d1 aba0 SWLMP-54108 108Mbps Wireless mini PCI card 802.11g+
+ 1737 0033 WPC54G Ver.2 802.11G PC Card
+ a001 TDC1570
+ a100 TDC1561
+ a102 TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
+ a106 TMS320C6414 TMS320C6415 TMS320C6416
+ 175c 5000 ASI50xx Audio Adapter
+ 175c 6400 ASI6400 Cobranet series
+ 175c 8700 ASI87xx Radio Tuner card
+ ac10 PCI1050
+ ac11 PCI1053
+ ac12 PCI1130
+ ac13 PCI1031
+ ac15 PCI1131
+ ac16 PCI1250
+ 1014 0092 ThinkPad 600
+ ac17 PCI1220
+ ac18 PCI1260
+ ac19 PCI1221
+ ac1a PCI1210
+ ac1b PCI1450
+ 0e11 b113 Armada M700
+ 1014 0130 Thinkpad T20/T22/A21m
+ ac1c PCI1225
+ 0e11 b121 Armada E500
+ 1028 0088 Latitude CPi A400XT
+ ac1d PCI1251A
+ ac1e PCI1211
+ ac1f PCI1251B
+ ac20 TI 2030
+ ac21 PCI2031
+ ac22 PCI2032 PCI Docking Bridge
+ ac23 PCI2250 PCI-to-PCI Bridge
+ ac28 PCI2050 PCI-to-PCI Bridge
+ ac30 PCI1260 PC card Cardbus Controller
+ ac40 PCI4450 PC card Cardbus Controller
+ ac41 PCI4410 PC card Cardbus Controller
+ ac42 PCI4451 PC card Cardbus Controller
+ 1028 00e6 PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
+ ac44 PCI4510 PC card Cardbus Controller
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 1071 8160 MIM2000
+ ac46 PCI4520 PC card Cardbus Controller
+ ac47 PCI7510 PC card Cardbus Controller
+ 1028 0139 Latitude D400
+ 1028 013f Precision M60
+ 1028 014e Latitude D800
+ ac4a PCI7510,7610 PC card Cardbus Controller
+ 1028 0139 Latitude D400
+ 1028 014e Latitude D800
+ ac50 PCI1410 PC card Cardbus Controller
+ ac51 PCI1420
+ 0e11 004e Evo N600c
+ 1014 0148 ThinkPad A20m
+ 1014 023b ThinkPad T23 (2647-4MG)
+ 1028 00b1 Latitude C600
+ 1028 012a Latitude C640
+ 1033 80cd Versa Note VXi
+ 1095 10cf Fujitsu-Siemens LifeBook C Series
+ 10cf 1095 Lifebook S-4510/C6155
+ e4bf 1000 CP2-2-HIPHOP
+ ac52 PCI1451 PC card Cardbus Controller
+ ac53 PCI1421 PC card Cardbus Controller
+ ac54 PCI1620 PC Card Controller
+ 103c 08b0 tc1100 tablet
+ ac55 PCI1520 PC card Cardbus Controller
+ 1014 0512 ThinkPad T30/T40
+ ac56 PCI1510 PC card Cardbus Controller
+ 1014 0528 ThinkPad R40e (2684-HVG) Cardbus Controller
+ ac60 PCI2040 PCI to DSP Bridge Controller
+ 175c 5100 ASI51xx Audio Adapter
+ 175c 6100 ASI61xx Audio Adapter
+ 175c 6200 ASI62xx Audio Adapter
+ 175c 8800 ASI88xx Audio Adapter
+ ac8d PCI 7620
+ ac8e PCI7420 CardBus Controller
+ ac8f PCI7420/PCI7620 Dual Socket CardBus and Smart Card Cont. w/ 1394a-2000 OHCI Two-Port PHY/Link-Layer Cont. and SD/MS-Pro Sockets
+ fe00 FireWire Host Controller
+ fe03 12C01A FireWire Host Controller
+104d Sony Corporation
+ 8004 DTL-H2500 [Playstation development board]
+ 8009 CXD1947Q i.LINK Controller
+ 8039 CXD3222 i.LINK Controller
+ 8056 Rockwell HCF 56K modem
+ 808a Memory Stick Controller
+104e Oak Technology, Inc
+ 0017 OTI-64017
+ 0107 OTI-107 [Spitfire]
+ 0109 Video Adapter
+ 0111 OTI-64111 [Spitfire]
+ 0217 OTI-64217
+ 0317 OTI-64317
+104f Co-time Computer Ltd
+1050 Winbond Electronics Corp
+ 0000 NE2000
+ 0001 W83769F
+ 0033 W89C33D 802.11 a/b/g BB/MAC
+ 0105 W82C105
+ 0840 W89C840
+ 1050 0001 W89C840 Ethernet Adapter
+ 1050 0840 W89C840 Ethernet Adapter
+ 0940 W89C940
+ 5a5a W89C940F
+ 6692 W6692
+ 1043 1702 ISDN Adapter (PCI Bus, D, W)
+ 1043 1703 ISDN Adapter (PCI Bus, DV, W)
+ 1043 1707 ISDN Adapter (PCI Bus, DV, W)
+ 144f 1702 ISDN Adapter (PCI Bus, D, W)
+ 144f 1703 ISDN Adapter (PCI Bus, DV, W)
+ 144f 1707 ISDN Adapter (PCI Bus, DV, W)
+ 9921 W99200F MPEG-1 Video Encoder
+ 9922 W99200F/W9922PF MPEG-1/2 Video Encoder
+ 9970 W9970CF
+1051 Anigma, Inc.
+1052 ?Young Micro Systems
+1053 Young Micro Systems
+1054 Hitachi, Ltd
+1055 Efar Microsystems
+ 9130 SLC90E66 [Victory66] IDE
+ 9460 SLC90E66 [Victory66] ISA
+ 9462 SLC90E66 [Victory66] USB
+ 9463 SLC90E66 [Victory66] ACPI
+1056 ICL
+# Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
+1057 Motorola
+ 0001 MPC105 [Eagle]
+ 0002 MPC106 [Grackle]
+ 0003 MPC8240 [Kahlua]
+ 0004 MPC107
+ 0006 MPC8245 [Unity]
+ 0008 MPC8540
+ 0009 MPC8560
+ 0100 MC145575 [HFC-PCI]
+ 0431 KTI829c 100VG
+ 1801 DSP56301 Digital Signal Processor
+ 14fb 0101 Transas Radar Imitator Board [RIM]
+ 14fb 0102 Transas Radar Imitator Board [RIM-2]
+ 14fb 0202 Transas Radar Integrator Board [RIB-2]
+ 14fb 0611 1 channel CAN bus Controller [CanPci-1]
+ 14fb 0612 2 channels CAN bus Controller [CanPci-2]
+ 14fb 0613 3 channels CAN bus Controller [CanPci-3]
+ 14fb 0614 4 channels CAN bus Controller [CanPci-4]
+ 14fb 0621 1 channel CAN bus Controller [CanPci2-1]
+ 14fb 0622 2 channels CAN bus Controller [CanPci2-2]
+ 14fb 0810 Transas VTS Radar Integrator Board [RIB-4]
+ 175c 4200 ASI4215 Audio Adapter
+ 175c 4300 ASI43xx Audio Adapter
+ 175c 4400 ASI4401 Audio Adapter
+ ecc0 0010 Darla
+ ecc0 0020 Gina
+ ecc0 0030 Layla rev.0
+ ecc0 0031 Layla rev.1
+ ecc0 0040 Darla24 rev.0
+ ecc0 0041 Darla24 rev.1
+ ecc0 0050 Gina24 rev.0
+ ecc0 0051 Gina24 rev.1
+ ecc0 0070 Mona rev.0
+ ecc0 0071 Mona rev.1
+ ecc0 0072 Mona rev.2
+ 18c0 MPC8265A/8266/8272
+ 18c1 MPC8271/MPC8272
+ 3055 SM56 Data Fax Modem
+ 3410 DSP56361 Digital Signal Processor
+ ecc0 0050 Gina24 rev.0
+ ecc0 0051 Gina24 rev.1
+ ecc0 0060 Layla24
+ ecc0 0070 Mona rev.0
+ ecc0 0071 Mona rev.1
+ ecc0 0072 Mona rev.2
+ ecc0 0080 Mia rev.0
+ ecc0 0081 Mia rev.1
+ ecc0 0090 Indigo
+ ecc0 00a0 Indigo IO
+ ecc0 00b0 Indigo DJ
+ ecc0 0100 3G
+ 4801 Raven
+ 4802 Falcon
+ 4803 Hawk
+ 4806 CPX8216
+ 4d68 20268
+ 5600 SM56 PCI Modem
+ 1057 0300 SM56 PCI Speakerphone Modem
+ 1057 0301 SM56 PCI Voice Modem
+ 1057 0302 SM56 PCI Fax Modem
+ 1057 5600 SM56 PCI Voice modem
+ 13d2 0300 SM56 PCI Speakerphone Modem
+ 13d2 0301 SM56 PCI Voice modem
+ 13d2 0302 SM56 PCI Fax Modem
+ 1436 0300 SM56 PCI Speakerphone Modem
+ 1436 0301 SM56 PCI Voice modem
+ 1436 0302 SM56 PCI Fax Modem
+ 144f 100c SM56 PCI Fax Modem
+ 1494 0300 SM56 PCI Speakerphone Modem
+ 1494 0301 SM56 PCI Voice modem
+ 14c8 0300 SM56 PCI Speakerphone Modem
+ 14c8 0302 SM56 PCI Fax Modem
+ 1668 0300 SM56 PCI Speakerphone Modem
+ 1668 0302 SM56 PCI Fax Modem
+ 5608 Wildcard X100P
+ 5803 MPC5200
+ 5806 MCF54 Coldfire
+ 5808 MPC8220
+ 5809 MPC5200B
+ 6400 MPC190 Security Processor (S1 family, encryption)
+ 6405 MPC184 Security Processor (S1 family)
+1058 Electronics & Telecommunications RSH
+1059 Teknor Industrial Computers Inc
+105a Promise Technology, Inc.
+ 0d30 PDC20265 (FastTrak100 Lite/Ultra100)
+ 105a 4d33 Ultra100
+ 0d38 20263
+ 105a 4d39 Fasttrak66
+ 1275 20275
+ 3318 PDC20318 (SATA150 TX4)
+ 3319 PDC20319 (FastTrak S150 TX4)
+ 8086 3427 S875WP1-E mainboard
+ 3371 PDC20371 (FastTrak S150 TX2plus)
+ 3373 PDC20378 (FastTrak 378/SATA 378)
+ 1043 80f5 K8V Deluxe/PC-DL Deluxe motherboard
+ 1462 702e K8T NEO FIS2R motherboard
+ 3375 PDC20375 (SATA150 TX2plus)
+ 3376 PDC20376 (FastTrak 376)
+ 1043 809e A7V8X motherboard
+ 3515 PDC40719 [FastTrak TX4300/TX4310]
+ 3519 PDC40519 (FastTrak TX4200)
+ 3570 20771 (FastTrak TX2300)
+ 3571 PDC20571 (FastTrak TX2200)
+ 3574 PDC20579 SATAII 150 IDE Controller
+ 3577 PDC40779 (SATA 300 779)
+ 3d17 PDC40718 (SATA 300 TX4)
+ 3d18 PDC20518/PDC40518 (SATAII 150 TX4)
+ 3d73 PDC40775 (SATA 300 TX2plus)
+ 3d75 PDC20575 (SATAII150 TX2plus)
+ 4d30 PDC20267 (FastTrak100/Ultra100)
+ 105a 4d33 Ultra100
+ 105a 4d39 FastTrak100
+ 4d33 20246
+ 105a 4d33 20246 IDE Controller
+ 4d38 PDC20262 (FastTrak66/Ultra66)
+ 105a 4d30 Ultra Device on SuperTrak
+ 105a 4d33 Ultra66
+ 105a 4d39 FastTrak66
+ 4d68 PDC20268 (Ultra100 TX2)
+ 105a 4d68 Ultra100TX2
+ 4d69 20269
+ 105a 4d68 Ultra133TX2
+ 5275 PDC20276 (MBFastTrak133 Lite)
+ 1043 807e A7V333 motherboard.
+ 105a 0275 SuperTrak SX6000 IDE
+ 105a 1275 MBFastTrak133 Lite (tm) Controller (RAID mode)
+ 1458 b001 MBUltra 133
+ 5300 DC5300
+ 6268 PDC20270 (FastTrak100 LP/TX2/TX4)
+ 105a 4d68 FastTrak100 TX2
+ 6269 PDC20271 (FastTrak TX2000)
+ 105a 6269 FastTrak TX2/TX2000
+ 6621 PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite)
+ 6622 PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller
+ 6624 PDC20621 [FastTrak SX4100]
+ 6626 PDC20618 (Ultra 618)
+ 6629 PDC20619 (FastTrak TX4000)
+ 7275 PDC20277 (SBFastTrak133 Lite)
+ 8002 SATAII150 SX8
+105b Foxconn International, Inc.
+105c Wipro Infotech Limited
+105d Number 9 Computer Company
+ 2309 Imagine 128
+ 2339 Imagine 128-II
+ 105d 0000 Imagine 128 series 2 4Mb VRAM
+ 105d 0001 Imagine 128 series 2 4Mb VRAM
+ 105d 0002 Imagine 128 series 2 4Mb VRAM
+ 105d 0003 Imagine 128 series 2 4Mb VRAM
+ 105d 0004 Imagine 128 series 2 4Mb VRAM
+ 105d 0005 Imagine 128 series 2 4Mb VRAM
+ 105d 0006 Imagine 128 series 2 4Mb VRAM
+ 105d 0007 Imagine 128 series 2 4Mb VRAM
+ 105d 0008 Imagine 128 series 2e 4Mb DRAM
+ 105d 0009 Imagine 128 series 2e 4Mb DRAM
+ 105d 000a Imagine 128 series 2 8Mb VRAM
+ 105d 000b Imagine 128 series 2 8Mb H-VRAM
+ 11a4 000a Barco Metheus 5 Megapixel
+ 13cc 0000 Barco Metheus 5 Megapixel
+ 13cc 0004 Barco Metheus 5 Megapixel
+ 13cc 0005 Barco Metheus 5 Megapixel
+ 13cc 0006 Barco Metheus 5 Megapixel
+ 13cc 0008 Barco Metheus 5 Megapixel
+ 13cc 0009 Barco Metheus 5 Megapixel
+ 13cc 000a Barco Metheus 5 Megapixel
+ 13cc 000c Barco Metheus 5 Megapixel
+ 493d Imagine 128 T2R [Ticket to Ride]
+ 11a4 000a Barco Metheus 5 Megapixel, Dual Head
+ 11a4 000b Barco Metheus 5 Megapixel, Dual Head
+ 13cc 0002 Barco Metheus 4 Megapixel, Dual Head
+ 13cc 0003 Barco Metheus 5 Megapixel, Dual Head
+ 13cc 0007 Barco Metheus 5 Megapixel, Dual Head
+ 13cc 0008 Barco Metheus 5 Megapixel, Dual Head
+ 13cc 0009 Barco Metheus 5 Megapixel, Dual Head
+ 13cc 000a Barco Metheus 5 Megapixel, Dual Head
+ 5348 Revolution 4
+ 105d 0037 Revolution IV-FP AGP (For SGI 1600SW)
+ 11a4 0028 PVS5600M
+ 11a4 0038 PVS5600D
+105e Vtech Computers Ltd
+105f Infotronic America Inc
+1060 United Microelectronics [UMC]
+ 0001 UM82C881
+ 0002 UM82C886
+ 0101 UM8673F
+ 0881 UM8881
+ 0886 UM8886F
+ 0891 UM8891A
+ 1001 UM886A
+ 673a UM8886BF
+ 673b EIDE Master/DMA
+ 8710 UM8710
+ 886a UM8886A
+ 8881 UM8881F
+ 8886 UM8886F
+ 888a UM8886A
+ 8891 UM8891A
+ 9017 UM9017F
+ 9018 UM9018
+ 9026 UM9026
+ e881 UM8881N
+ e886 UM8886N
+ e88a UM8886N
+ e891 UM8891N
+1061 I.I.T.
+ 0001 AGX016
+ 0002 IIT3204/3501
+1062 Maspar Computer Corp
+1063 Ocean Office Automation
+1064 Alcatel
+1065 Texas Microsystems
+1066 PicoPower Technology
+ 0000 PT80C826
+ 0001 PT86C521 [Vesuvius v1] Host Bridge
+ 0002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Master
+ 0003 PT86C524 [Nile] PCI-to-PCI Bridge
+ 0004 PT86C525 [Nile-II] PCI-to-PCI Bridge
+ 0005 National PC87550 System Controller
+ 8002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave
+1067 Mitsubishi Electric
+ 0301 AccelGraphics AccelECLIPSE
+ 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
+ 0308 Tornado 3000 [OEM Evans & Sutherland]
+ 1002 VG500 [VolumePro Volume Rendering Accelerator]
+1068 Diversified Technology
+1069 Mylex Corporation
+ 0001 DAC960P
+ 0002 DAC960PD
+ 0010 DAC960PG
+ 0020 DAC960LA
+ 0050 AcceleRAID 352/170/160 support Device
+ 1069 0050 AcceleRAID 352 support Device
+ 1069 0052 AcceleRAID 170 support Device
+ 1069 0054 AcceleRAID 160 support Device
+ b166 AcceleRAID 600/500/400/Sapphire support Device
+ 1014 0242 iSeries 2872 DASD IOA
+ 1014 0266 Dual Channel PCI-X U320 SCSI Adapter
+ 1014 0278 Dual Channel PCI-X U320 SCSI RAID Adapter
+ 1014 02d3 Dual Channel PCI-X U320 SCSI Adapter
+ 1014 02d4 Dual Channel PCI-X U320 SCSI RAID Adapter
+ 1069 0200 AcceleRAID 400, Single Channel, PCI-X, U320, SCSI RAID
+ 1069 0202 AcceleRAID Sapphire, Dual Channel, PCI-X, U320, SCSI RAID
+ 1069 0204 AcceleRAID 500, Dual Channel, Low-Profile, PCI-X, U320, SCSI RAID
+ 1069 0206 AcceleRAID 600, Dual Channel, PCI-X, U320, SCSI RAID
+ ba55 eXtremeRAID 1100 support Device
+ ba56 eXtremeRAID 2000/3000 support Device
+ 1069 0030 eXtremeRAID 3000 support Device
+ 1069 0040 eXtremeRAID 2000 support Device
+ ba57 eXtremeRAID 4000/5000 support Device
+ 1069 0072 eXtremeRAID 5000 support Device
+106a Aten Research Inc
+106b Apple Computer Inc.
+ 0001 Bandit PowerPC host bridge
+ 0002 Grand Central I/O
+ 0003 Control Video
+ 0004 PlanB Video-In
+ 0007 O'Hare I/O
+ 000c DOS on Mac
+ 000e Hydra Mac I/O
+ 0010 Heathrow Mac I/O
+ 0017 Paddington Mac I/O
+ 0018 UniNorth FireWire
+ 0019 KeyLargo USB
+ 001e UniNorth Internal PCI
+ 001f UniNorth PCI
+ 0020 UniNorth AGP
+ 0021 UniNorth GMAC (Sun GEM)
+ 0022 KeyLargo Mac I/O
+ 0024 UniNorth/Pangea GMAC (Sun GEM)
+ 0025 KeyLargo/Pangea Mac I/O
+ 0026 KeyLargo/Pangea USB
+ 0027 UniNorth/Pangea AGP
+ 0028 UniNorth/Pangea PCI
+ 0029 UniNorth/Pangea Internal PCI
+ 002d UniNorth 1.5 AGP
+ 002e UniNorth 1.5 PCI
+ 002f UniNorth 1.5 Internal PCI
+ 0030 UniNorth/Pangea FireWire
+ 0031 UniNorth 2 FireWire
+ 106b 5811 iBook G4 2004
+ 0032 UniNorth 2 GMAC (Sun GEM)
+ 0033 UniNorth 2 ATA/100
+ 0034 UniNorth 2 AGP
+ 0035 UniNorth 2 PCI
+ 0036 UniNorth 2 Internal PCI
+ 003b UniNorth/Intrepid ATA/100
+ 003e KeyLargo/Intrepid Mac I/O
+ 003f KeyLargo/Intrepid USB
+ 0040 K2 KeyLargo USB
+ 0041 K2 KeyLargo Mac/IO
+ 0042 K2 FireWire
+ 0043 K2 ATA/100
+ 0045 K2 HT-PCI Bridge
+ 0046 K2 HT-PCI Bridge
+ 0047 K2 HT-PCI Bridge
+ 0048 K2 HT-PCI Bridge
+ 0049 K2 HT-PCI Bridge
+ 004b U3 AGP
+ 004c K2 GMAC (Sun GEM)
+ 004f Shasta Mac I/O
+ 0050 Shasta IDE
+ 0051 Shasta (Sun GEM)
+ 0052 Shasta Firewire
+ 0053 Shasta PCI Bridge
+ 0054 Shasta PCI Bridge
+ 0055 Shasta PCI Bridge
+ 0058 U3L AGP Bridge
+ 0059 U3H AGP Bridge
+ 0066 Intrepid2 AGP Bridge
+ 0067 Intrepid2 PCI Bridge
+ 0068 Intrepid2 PCI Bridge
+ 0069 Intrepid2 ATA/100
+ 006a Intrepid2 Firewire
+ 006b Intrepid2 GMAC (Sun GEM)
+ 1645 Tigon3 Gigabit Ethernet NIC (BCM5701)
+106c Hynix Semiconductor
+ 8801 Dual Pentium ISA/PCI Motherboard
+ 8802 PowerPC ISA/PCI Motherboard
+ 8803 Dual Window Graphics Accelerator
+ 8804 LAN Controller
+ 8805 100-BaseT LAN
+106d Sequent Computer Systems
+106e DFI, Inc
+106f City Gate Development Ltd
+1070 Daewoo Telecom Ltd
+1071 Mitac
+ 8160 Mitac 8060B Mobile Platform
+1072 GIT Co Ltd
+1073 Yamaha Corporation
+ 0001 3D GUI Accelerator
+ 0002 YGV615 [RPA3 3D-Graphics Controller]
+ 0003 YMF-740
+ 0004 YMF-724
+ 1073 0004 YMF724-Based PCI Audio Adapter
+ 0005 DS1 Audio
+ 1073 0005 DS-XG PCI Audio CODEC
+ 0006 DS1 Audio
+ 0008 DS1 Audio
+ 1073 0008 DS-XG PCI Audio CODEC
+ 000a DS1L Audio
+ 1073 0004 DS-XG PCI Audio CODEC
+ 1073 000a DS-XG PCI Audio CODEC
+ 000c YMF-740C [DS-1L Audio Controller]
+ 107a 000c DS-XG PCI Audio CODEC
+ 000d YMF-724F [DS-1 Audio Controller]
+ 1073 000d DS-XG PCI Audio CODEC
+ 0010 YMF-744B [DS-1S Audio Controller]
+ 1073 0006 DS-XG PCI Audio CODEC
+ 1073 0010 DS-XG PCI Audio CODEC
+ 0012 YMF-754 [DS-1E Audio Controller]
+ 1073 0012 DS-XG PCI Audio Codec
+ 0020 DS-1 Audio
+ 2000 DS2416 Digital Mixing Card
+ 1073 2000 DS2416 Digital Mixing Card
+1074 NexGen Microsystems
+ 4e78 82c500/1
+1075 Advanced Integrations Research
+1076 Chaintech Computer Co. Ltd
+1077 QLogic Corp.
+ 1016 ISP10160 Single Channel Ultra3 SCSI Processor
+ 1020 ISP1020 Fast-wide SCSI
+ 1022 ISP1022 Fast-wide SCSI
+ 1080 ISP1080 SCSI Host Adapter
+ 1216 ISP12160 Dual Channel Ultra3 SCSI Processor
+ 101e 8471 QLA12160 on AMI MegaRAID
+ 101e 8493 QLA12160 on AMI MegaRAID
+ 1240 ISP1240 SCSI Host Adapter
+ 1280 ISP1280 SCSI Host Adapter
+ 2020 ISP2020A Fast!SCSI Basic Adapter
+ 2100 QLA2100 64-bit Fibre Channel Adapter
+ 1077 0001 QLA2100 64-bit Fibre Channel Adapter
+ 2200 QLA2200 64-bit Fibre Channel Adapter
+ 1077 0002 QLA2200
+ 2300 QLA2300 64-bit Fibre Channel Adapter
+ 2312 QLA2312 Fibre Channel Adapter
+ 2322 QLA2322 Fibre Channel Adapter
+ 2422 QLA2422 Fibre Channel Adapter
+ 2432 QLA2432 Fibre Channel Adapter
+ 3010 QLA3010 Network Adapter
+ 3022 QLA3022 Network Adapter
+ 4010 QLA4010 iSCSI TOE Adapter
+ 4022 QLA4022 iSCSI TOE Adapter
+ 6312 QLA6312 Fibre Channel Adapter
+ 6322 QLA6322 Fibre Channel Adapter
+1078 Cyrix Corporation
+ 0000 5510 [Grappa]
+ 0001 PCI Master
+ 0002 5520 [Cognac]
+ 0100 5530 Legacy [Kahlua]
+ 0101 5530 SMI [Kahlua]
+ 0102 5530 IDE [Kahlua]
+ 0103 5530 Audio [Kahlua]
+ 0104 5530 Video [Kahlua]
+ 0400 ZFMicro PCI Bridge
+ 0401 ZFMicro Chipset SMI
+ 0402 ZFMicro Chipset IDE
+ 0403 ZFMicro Expansion Bus
+1079 I-Bus
+107a NetWorth
+107b Gateway 2000
+107c LG Electronics [Lucky Goldstar Co. Ltd]
+107d LeadTek Research Inc.
+ 0000 P86C850
+ 204d [GeForce 7800 GTX] Winfast PX7800 GTX TDH
+ 2134 WinFast 3D S320 II
+ 2971 [GeForce FX 5900] WinFast A350 TDH MyViVo
+107e Interphase Corporation
+ 0001 5515 ATM Adapter [Flipper]
+ 0002 100 VG AnyLan Controller
+ 0004 5526 Fibre Channel Host Adapter
+ 0005 x526 Fibre Channel Host Adapter
+ 0008 5525/5575 ATM Adapter (155 Mbit) [Atlantic]
+ 9003 5535-4P-BRI-ST
+ 9007 5535-4P-BRI-U
+ 9008 5535-1P-SR
+ 900c 5535-1P-SR-ST
+ 900e 5535-1P-SR-U
+ 9011 5535-1P-PRI
+ 9013 5535-2P-PRI
+ 9023 5536-4P-BRI-ST
+ 9027 5536-4P-BRI-U
+ 9031 5536-1P-PRI
+ 9033 5536-2P-PRI
+107f Data Technology Corporation
+ 0802 SL82C105
+1080 Contaq Microsystems
+ 0600 82C599
+ c691 Cypress CY82C691
+ c693 82c693
+1081 Supermac Technology
+ 0d47 Radius PCI to NuBUS Bridge
+1082 EFA Corporation of America
+1083 Forex Computer Corporation
+ 0001 FR710
+1084 Parador
+1085 Tulip Computers Int.B.V.
+1086 J. Bond Computer Systems
+1087 Cache Computer
+1088 Microcomputer Systems (M) Son
+1089 Data General Corporation
+# Formerly Bit3 Computer Corp.
+108a SBS Technologies
+ 0001 VME Bridge Model 617
+ 0010 VME Bridge Model 618
+ 0040 dataBLIZZARD
+ 3000 VME Bridge Model 2706
+108c Oakleigh Systems Inc.
+108d Olicom
+ 0001 Token-Ring 16/4 PCI Adapter (3136/3137)
+ 0002 16/4 Token Ring
+ 0004 RapidFire 3139 Token-Ring 16/4 PCI Adapter
+ 108d 0004 OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
+ 0005 GoCard 3250 Token-Ring 16/4 CardBus PC Card
+ 0006 OC-3530 RapidFire Token-Ring 100
+ 0007 RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
+ 108d 0007 OC-3141 RapidFire Token-Ring 16/4 Adapter
+ 0008 RapidFire 3540 HSTR 100/16/4 PCI Adapter
+ 108d 0008 OC-3540 RapidFire HSTR 100/16/4 Adapter
+ 0011 OC-2315
+ 0012 OC-2325
+ 0013 OC-2183/2185
+ 0014 OC-2326
+ 0019 OC-2327/2250 10/100 Ethernet Adapter
+ 108d 0016 OC-2327 Rapidfire 10/100 Ethernet Adapter
+ 108d 0017 OC-2250 GoCard 10/100 Ethernet Adapter
+ 0021 OC-6151/6152 [RapidFire ATM 155]
+ 0022 ATM Adapter
+108e Sun Microsystems Computer Corp.
+ 0001 EBUS
+ 1000 EBUS
+ 1001 Happy Meal
+ 1100 RIO EBUS
+ 1101 RIO GEM
+ 1102 RIO 1394
+ 1103 RIO USB
+ 1648 [bge] Gigabit Ethernet
+ 2bad GEM
+ 5000 Simba Advanced PCI Bridge
+ 5043 SunPCI Co-processor
+ 8000 Psycho PCI Bus Module
+ 8001 Schizo PCI Bus Module
+ 8002 Schizo+ PCI Bus Module
+ a000 Ultra IIi
+ a001 Ultra IIe
+ a801 Tomatillo PCI Bus Module
+ abba Cassini 10/100/1000
+108f Systemsoft
+1090 Compro Computer Services, Inc.
+1091 Intergraph Corporation
+ 0020 3D graphics processor
+ 0021 3D graphics processor w/Texturing
+ 0040 3D graphics frame buffer
+ 0041 3D graphics frame buffer
+ 0060 Proprietary bus bridge
+ 00e4 Powerstorm 4D50T
+ 0720 Motion JPEG codec
+ 07a0 Sun Expert3D-Lite Graphics Accelerator
+ 1091 Sun Expert3D Graphics Accelerator
+1092 Diamond Multimedia Systems
+ 00a0 Speedstar Pro SE
+ 00a8 Speedstar 64
+ 0550 Viper V550
+ 08d4 Supra 2260 Modem
+ 094c SupraExpress 56i Pro
+ 1092 Viper V330
+ 6120 Maximum DVD
+ 8810 Stealth SE
+ 8811 Stealth 64/SE
+ 8880 Stealth
+ 8881 Stealth
+ 88b0 Stealth 64
+ 88b1 Stealth 64
+ 88c0 Stealth 64
+ 88c1 Stealth 64
+ 88d0 Stealth 64
+ 88d1 Stealth 64
+ 88f0 Stealth 64
+ 88f1 Stealth 64
+ 9999 DMD-I0928-1 "Monster sound" sound chip
+1093 National Instruments
+ 0160 PCI-DIO-96
+ 0162 PCI-MIO-16XE-50
+ 1150 PCI-DIO-32HS High Speed Digital I/O Board
+ 1170 PCI-MIO-16XE-10
+ 1180 PCI-MIO-16E-1
+ 1190 PCI-MIO-16E-4
+ 1310 PCI-6602
+ 1330 PCI-6031E
+ 1350 PCI-6071E
+ 14e0 PCI-6110
+ 14f0 PCI-6111
+ 17d0 PCI-6503
+ 1870 PCI-6713
+ 1880 PCI-6711
+ 18b0 PCI-6052E
+ 2410 PCI-6733
+ 2890 PCI-6036E
+ 2a60 PCI-6023E
+ 2a70 PCI-6024E
+ 2a80 PCI-6025E
+ 2c80 PCI-6035E
+ 2ca0 PCI-6034E
+ 70a9 PCI-6528 (Digital I/O at 60V)
+ 70b8 PCI-6251 [M Series - High Speed Multifunction DAQ]
+ b001 IMAQ-PCI-1408
+ b011 IMAQ-PXI-1408
+ b021 IMAQ-PCI-1424
+ b031 IMAQ-PCI-1413
+ b041 IMAQ-PCI-1407
+ b051 IMAQ-PXI-1407
+ b061 IMAQ-PCI-1411
+ b071 IMAQ-PCI-1422
+ b081 IMAQ-PXI-1422
+ b091 IMAQ-PXI-1411
+ c801 PCI-GPIB
+ c831 PCI-GPIB bridge
+1094 First International Computers [FIC]
+# nee CMD Technology Inc
+1095 Silicon Image, Inc.
+ 0240 Adaptec AAR-1210SA SATA HostRAID Controller
+ 0640 PCI0640
+ 0643 PCI0643
+ 0646 PCI0646
+ 0647 PCI0647
+ 0648 PCI0648
+ 1043 8025 CUBX motherboard
+ 0649 SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
+ 0e11 005d Integrated Ultra ATA-100 Dual Channel Controller
+ 0e11 007e Integrated Ultra ATA-100 IDE RAID Controller
+ 101e 0649 AMI MegaRAID IDE 100 Controller
+ 0650 PBC0650A
+ 0670 USB0670
+ 1095 0670 USB0670
+ 0673 USB0673
+ 0680 PCI0680 Ultra ATA-133 Host Controller
+ 1095 3680 Winic W-680 (Silicon Image 680 based)
+ 3112 SiI 3112 [SATALink/SATARaid] Serial ATA Controller
+ 1095 3112 SiI 3112 SATALink Controller
+ 1095 6112 SiI 3112 SATARaid Controller
+ 9005 0250 SATAConnect 1205SA Host Controller
+ 3114 SiI 3114 [SATALink/SATARaid] Serial ATA Controller
+ 1095 3114 SiI 3114 SATALink Controller
+ 1095 6114 SiI 3114 SATARaid Controller
+ 3124 SiI 3124 PCI-X Serial ATA Controller
+ 1095 3124 SiI 3124 PCI-X Serial ATA Controller
+ 3132 SiI 3132 Serial ATA Raid II Controller
+ 3512 SiI 3512 [SATALink/SATARaid] Serial ATA Controller
+ 1095 3512 SiI 3512 SATALink Controller
+ 1095 6512 SiI 3512 SATARaid Controller
+1096 Alacron
+1097 Appian Technology
+1098 Quantum Designs (H.K.) Ltd
+ 0001 QD-8500
+ 0002 QD-8580
+1099 Samsung Electronics Co., Ltd
+109a Packard Bell
+109b Gemlight Computer Ltd.
+109c Megachips Corporation
+109d Zida Technologies Ltd.
+109e Brooktree Corporation
+ 032e Bt878 Video Capture
+ 0350 Bt848 Video Capture
+ 0351 Bt849A Video capture
+ 0369 Bt878 Video Capture
+ 1002 0001 TV-Wonder
+ 1002 0003 TV-Wonder/VE
+ 036c Bt879(??) Video Capture
+ 13e9 0070 Win/TV (Video Section)
+ 036e Bt878 Video Capture
+ 0070 13eb WinTV Series
+ 0070 ff01 Viewcast Osprey 200
+ 0071 0101 DigiTV PCI
+ 107d 6606 WinFast TV 2000
+ 11bd 0012 PCTV pro (TV + FM stereo receiver)
+ 11bd 001c PCTV Sat (DBC receiver)
+ 127a 0001 Bt878 Mediastream Controller NTSC
+ 127a 0002 Bt878 Mediastream Controller PAL BG
+ 127a 0003 Bt878a Mediastream Controller PAL BG
+ 127a 0048 Bt878/832 Mediastream Controller
+ 144f 3000 MagicTView CPH060 - Video
+ 1461 0002 TV98 Series (TV/No FM/Remote)
+ 1461 0003 AverMedia UltraTV PCI 350
+ 1461 0004 AVerTV WDM Video Capture
+ 1461 0761 AverTV DVB-T
+ 1461 0771 AverMedia AVerTV DVB-T 771
+ 14f1 0001 Bt878 Mediastream Controller NTSC
+ 14f1 0002 Bt878 Mediastream Controller PAL BG
+ 14f1 0003 Bt878a Mediastream Controller PAL BG
+ 14f1 0048 Bt878/832 Mediastream Controller
+ 1822 0001 VisionPlus DVB card
+ 1851 1850 FlyVideo'98 - Video
+ 1851 1851 FlyVideo II
+ 1852 1852 FlyVideo'98 - Video (with FM Tuner)
+ 18ac d500 DViCO FusionHDTV5 Lite
+ 270f fc00 Digitop DTT-1000
+ bd11 1200 PCTV pro (TV + FM stereo receiver)
+ 036f Bt879 Video Capture
+ 127a 0044 Bt879 Video Capture NTSC
+ 127a 0122 Bt879 Video Capture PAL I
+ 127a 0144 Bt879 Video Capture NTSC
+ 127a 0222 Bt879 Video Capture PAL BG
+ 127a 0244 Bt879a Video Capture NTSC
+ 127a 0322 Bt879 Video Capture NTSC
+ 127a 0422 Bt879 Video Capture NTSC
+ 127a 1122 Bt879 Video Capture PAL I
+ 127a 1222 Bt879 Video Capture PAL BG
+ 127a 1322 Bt879 Video Capture NTSC
+ 127a 1522 Bt879a Video Capture PAL I
+ 127a 1622 Bt879a Video Capture PAL BG
+ 127a 1722 Bt879a Video Capture NTSC
+ 14f1 0044 Bt879 Video Capture NTSC
+ 14f1 0122 Bt879 Video Capture PAL I
+ 14f1 0144 Bt879 Video Capture NTSC
+ 14f1 0222 Bt879 Video Capture PAL BG
+ 14f1 0244 Bt879a Video Capture NTSC
+ 14f1 0322 Bt879 Video Capture NTSC
+ 14f1 0422 Bt879 Video Capture NTSC
+ 14f1 1122 Bt879 Video Capture PAL I
+ 14f1 1222 Bt879 Video Capture PAL BG
+ 14f1 1322 Bt879 Video Capture NTSC
+ 14f1 1522 Bt879a Video Capture PAL I
+ 14f1 1622 Bt879a Video Capture PAL BG
+ 14f1 1722 Bt879a Video Capture NTSC
+ 1851 1850 FlyVideo'98 - Video
+ 1851 1851 FlyVideo II
+ 1852 1852 FlyVideo'98 - Video (with FM Tuner)
+ 0370 Bt880 Video Capture
+ 1851 1850 FlyVideo'98
+ 1851 1851 FlyVideo'98 EZ - video
+ 1852 1852 FlyVideo'98 (with FM Tuner)
+ 0878 Bt878 Audio Capture
+ 0070 13eb WinTV Series
+ 0070 ff01 Viewcast Osprey 200
+ 0071 0101 DigiTV PCI
+ 1002 0001 TV-Wonder
+ 1002 0003 TV-Wonder/VE
+ 11bd 0012 PCTV pro (TV + FM stereo receiver, audio section)
+ 11bd 001c PCTV Sat (DBC receiver)
+ 127a 0001 Bt878 Video Capture (Audio Section)
+ 127a 0002 Bt878 Video Capture (Audio Section)
+ 127a 0003 Bt878 Video Capture (Audio Section)
+ 127a 0048 Bt878 Video Capture (Audio Section)
+ 13e9 0070 Win/TV (Audio Section)
+ 144f 3000 MagicTView CPH060 - Audio
+ 1461 0002 Avermedia PCTV98 Audio Capture
+ 1461 0004 AVerTV WDM Audio Capture
+ 1461 0761 AVerTV DVB-T
+ 1461 0771 AverMedia AVerTV DVB-T 771
+ 14f1 0001 Bt878 Video Capture (Audio Section)
+ 14f1 0002 Bt878 Video Capture (Audio Section)
+ 14f1 0003 Bt878 Video Capture (Audio Section)
+ 14f1 0048 Bt878 Video Capture (Audio Section)
+ 1822 0001 VisionPlus DVB Card
+ 18ac d500 DViCO FusionHDTV5 Lite
+ 270f fc00 Digitop DTT-1000
+ bd11 1200 PCTV pro (TV + FM stereo receiver, audio section)
+ 0879 Bt879 Audio Capture
+ 127a 0044 Bt879 Video Capture (Audio Section)
+ 127a 0122 Bt879 Video Capture (Audio Section)
+ 127a 0144 Bt879 Video Capture (Audio Section)
+ 127a 0222 Bt879 Video Capture (Audio Section)
+ 127a 0244 Bt879 Video Capture (Audio Section)
+ 127a 0322 Bt879 Video Capture (Audio Section)
+ 127a 0422 Bt879 Video Capture (Audio Section)
+ 127a 1122 Bt879 Video Capture (Audio Section)
+ 127a 1222 Bt879 Video Capture (Audio Section)
+ 127a 1322 Bt879 Video Capture (Audio Section)
+ 127a 1522 Bt879 Video Capture (Audio Section)
+ 127a 1622 Bt879 Video Capture (Audio Section)
+ 127a 1722 Bt879 Video Capture (Audio Section)
+ 14f1 0044 Bt879 Video Capture (Audio Section)
+ 14f1 0122 Bt879 Video Capture (Audio Section)
+ 14f1 0144 Bt879 Video Capture (Audio Section)
+ 14f1 0222 Bt879 Video Capture (Audio Section)
+ 14f1 0244 Bt879 Video Capture (Audio Section)
+ 14f1 0322 Bt879 Video Capture (Audio Section)
+ 14f1 0422 Bt879 Video Capture (Audio Section)
+ 14f1 1122 Bt879 Video Capture (Audio Section)
+ 14f1 1222 Bt879 Video Capture (Audio Section)
+ 14f1 1322 Bt879 Video Capture (Audio Section)
+ 14f1 1522 Bt879 Video Capture (Audio Section)
+ 14f1 1622 Bt879 Video Capture (Audio Section)
+ 14f1 1722 Bt879 Video Capture (Audio Section)
+ 0880 Bt880 Audio Capture
+ 2115 BtV 2115 Mediastream controller
+ 2125 BtV 2125 Mediastream controller
+ 2164 BtV 2164
+ 2165 BtV 2165
+ 8230 Bt8230 ATM Segment/Reassembly Ctrlr (SRC)
+ 8472 Bt8472
+ 8474 Bt8474
+109f Trigem Computer Inc.
+10a0 Meidensha Corporation
+10a1 Juko Electronics Ind. Co. Ltd
+10a2 Quantum Corporation
+10a3 Everex Systems Inc
+10a4 Globe Manufacturing Sales
+10a5 Smart Link Ltd.
+ 3052 SmartPCI562 56K Modem
+ 5449 SmartPCI561 modem
+10a6 Informtech Industrial Ltd.
+10a7 Benchmarq Microelectronics
+10a8 Sierra Semiconductor
+ 0000 STB Horizon 64
+10a9 Silicon Graphics, Inc.
+ 0001 Crosstalk to PCI Bridge
+ 0002 Linc I/O controller
+ 0003 IOC3 I/O controller
+ 0004 O2 MACE
+ 0005 RAD Audio
+ 0006 HPCEX
+ 0007 RPCEX
+ 0008 DiVO VIP
+ 0009 AceNIC Gigabit Ethernet
+ 10a9 8002 AceNIC Gigabit Ethernet
+ 0010 AMP Video I/O
+ 0011 GRIP
+ 0012 SGH PSHAC GSN
+ 1001 Magic Carpet
+ 1002 Lithium
+ 1003 Dual JPEG 1
+ 1004 Dual JPEG 2
+ 1005 Dual JPEG 3
+ 1006 Dual JPEG 4
+ 1007 Dual JPEG 5
+ 1008 Cesium
+ 100a IOC4 I/O controller
+ 2001 Fibre Channel
+ 2002 ASDE
+ 4001 TIO-CE PCI Express Bridge
+ 4002 TIO-CE PCI Express Port
+ 8001 O2 1394
+ 8002 G-net NT
+10aa ACC Microelectronics
+ 0000 ACCM 2188
+10ab Digicom
+10ac Honeywell IAC
+10ad Symphony Labs
+ 0001 W83769F
+ 0003 SL82C103
+ 0005 SL82C105
+ 0103 SL82c103
+ 0105 SL82c105
+ 0565 W83C553
+10ae Cornerstone Technology
+10af Micro Computer Systems Inc
+10b0 CardExpert Technology
+10b1 Cabletron Systems Inc
+10b2 Raytheon Company
+10b3 Databook Inc
+ 3106 DB87144
+ b106 DB87144
+10b4 STB Systems Inc
+ 1b1d Velocity 128 3D
+ 10b4 237e Velocity 4400
+10b5 PLX Technology, Inc.
+ 0001 i960 PCI bus interface
+ 1042 Brandywine / jxi2, Inc. - PMC-SyncClock32, IRIG A & B, Nasa 36
+ 1076 VScom 800 8 port serial adaptor
+ 1077 VScom 400 4 port serial adaptor
+ 1078 VScom 210 2 port serial and 1 port parallel adaptor
+ 1103 VScom 200 2 port serial adaptor
+ 1146 VScom 010 1 port parallel adaptor
+ 1147 VScom 020 2 port parallel adaptor
+ 2540 IXXAT CAN-Interface PC-I 04/PCI
+ 2724 Thales PCSM Security Card
+ 6540 PCI6540/6466 PCI-PCI bridge (transparent mode)
+ 4c53 10e0 PSL09 PrPMC
+ 6541 PCI6540/6466 PCI-PCI bridge (non-transparent mode, primary side)
+ 4c53 10e0 PSL09 PrPMC
+ 6542 PCI6540/6466 PCI-PCI bridge (non-transparent mode, secondary side)
+ 4c53 10e0 PSL09 PrPMC
+ 8111 PEX 8111 PCI Express-to-PCI Bridge
+ 8114 PEX 8114 PCI Express-to-PCI/PCI-X Bridge
+ 8516 PEX 8516 Versatile PCI Express Switch
+ 8532 PEX 8532 Versatile PCI Express Switch
+ 9030 PCI <-> IOBus Bridge Hot Swap
+ 10b5 2862 Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
+ 10b5 2906 Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
+ 10b5 2940 Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
+ 10b5 2977 IXXAT iPC-I XC16/PCI CAN Board
+ 10b5 2978 SH ARC-PCIu SOHARD ARCNET card
+ 10b5 3025 Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
+ 10b5 3068 Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
+ 1397 3136 4xS0-ISDN PCI Adapter
+ 1397 3137 S2M-E1-ISDN PCI Adapter
+ 1518 0200 Kontron ThinkIO-C
+ 15ed 1002 MCCS 8-port Serial Hot Swap
+ 15ed 1003 MCCS 16-port Serial Hot Swap
+ 9036 9036
+ 9050 PCI <-> IOBus Bridge
+ 10b5 1067 IXXAT CAN i165
+ 10b5 1172 IK220 (Heidenhain)
+ 10b5 2036 SatPak GPS
+ 10b5 2221 Alpermann+Velte PCL PCI LV: Timecode Reader Board
+ 10b5 2273 SH ARC-PCI SOHARD ARCNET card
+ 10b5 2431 Alpermann+Velte PCL PCI D: Timecode Reader Board
+ 10b5 2905 Alpermann+Velte PCI TS: Time Synchronisation Board
+ 10b5 9050 MP9050
+ 1498 0362 TPMC866 8 Channel Serial Card
+ 1522 0001 RockForce 4 Port V.90 Data/Fax/Voice Modem
+ 1522 0002 RockForce 2 Port V.90 Data/Fax/Voice Modem
+ 1522 0003 RockForce 6 Port V.90 Data/Fax/Voice Modem
+ 1522 0004 RockForce 8 Port V.90 Data/Fax/Voice Modem
+ 1522 0010 RockForce2000 4 Port V.90 Data/Fax/Voice Modem
+ 1522 0020 RockForce2000 2 Port V.90 Data/Fax/Voice Modem
+ 15ed 1000 Macrolink MCCS 8-port Serial
+ 15ed 1001 Macrolink MCCS 16-port Serial
+ 15ed 1002 Macrolink MCCS 8-port Serial Hot Swap
+ 15ed 1003 Macrolink MCCS 16-port Serial Hot Swap
+ 5654 2036 OpenSwitch 6 Telephony card
+ 5654 3132 OpenSwitch 12 Telephony card
+ 5654 5634 OpenLine4 Telephony Card
+ d531 c002 PCIntelliCAN 2xSJA1000 CAN bus
+ d84d 4006 EX-4006 1P
+ d84d 4008 EX-4008 1P EPP/ECP
+ d84d 4014 EX-4014 2P
+ d84d 4018 EX-4018 3P EPP/ECP
+ d84d 4025 EX-4025 1S(16C550) RS-232
+ d84d 4027 EX-4027 1S(16C650) RS-232
+ d84d 4028 EX-4028 1S(16C850) RS-232
+ d84d 4036 EX-4036 2S(16C650) RS-232
+ d84d 4037 EX-4037 2S(16C650) RS-232
+ d84d 4038 EX-4038 2S(16C850) RS-232
+ d84d 4052 EX-4052 1S(16C550) RS-422/485
+ d84d 4053 EX-4053 2S(16C550) RS-422/485
+ d84d 4055 EX-4055 4S(16C550) RS-232
+ d84d 4058 EX-4055 4S(16C650) RS-232
+ d84d 4065 EX-4065 8S(16C550) RS-232
+ d84d 4068 EX-4068 8S(16C650) RS-232
+ d84d 4078 EX-4078 2S(16C552) RS-232+1P
+ 9054 PCI <-> IOBus Bridge
+ 10b5 2455 Wessex Techology PHIL-PCI
+ 10b5 2696 Innes Corp AM Radcap card
+ 10b5 2717 Innes Corp Auricon card
+ 10b5 2844 Innes Corp TVS Encoder card
+ 12c7 4001 Intel Dialogic DM/V960-4T1 PCI
+ 12d9 0002 PCI Prosody Card rev 1.5
+ 16df 0011 PIKA PrimeNet MM PCI
+ 16df 0012 PIKA PrimeNet MM cPCI 8
+ 16df 0013 PIKA PrimeNet MM cPCI 8 (without CAS Signaling)
+ 16df 0014 PIKA PrimeNet MM cPCI 4
+ 16df 0015 PIKA Daytona MM
+ 16df 0016 PIKA InLine MM
+ 9056 Francois
+ 10b5 2979 CellinkBlade 11 - CPCI board VoATM AAL1
+ 9060 9060
+ 906d 9060SD
+ 125c 0640 Aries 16000P
+ 906e 9060ES
+ 9080 9080
+ 103c 10eb (Agilent) E2777B 83K Series Optical Communication Interface
+ 103c 10ec (Agilent) E6978-66442 PCI CIC
+ 10b5 9080 9080 [real subsystem ID not set]
+ 129d 0002 Aculab PCI Prosidy card
+ 12d9 0002 PCI Prosody Card
+ 12df 4422 4422PCI ["Do-All" Telemetry Data Aquisition System]
+ 1517 000b ECSG-1R3ADC-PMC Clock synthesizer
+ 9656 PCI <-> IOBus Bridge
+ 1517 000f ECDR-GC314-PMC Receiver
+ 1885 0700 Tsunami FPGA PMC with Altera Stratix S40
+ 1885 0701 Tsunami FPGA PMC with Altera Stratix S30
+ bb04 B&B 3PCIOSD1A Isolated PCI Serial
+10b6 Madge Networks
+ 0001 Smart 16/4 PCI Ringnode
+ 0002 Smart 16/4 PCI Ringnode Mk2
+ 10b6 0002 Smart 16/4 PCI Ringnode Mk2
+ 10b6 0006 16/4 CardBus Adapter
+ 0003 Smart 16/4 PCI Ringnode Mk3
+ 0e11 b0fd Compaq NC4621 PCI, 4/16, WOL
+ 10b6 0003 Smart 16/4 PCI Ringnode Mk3
+ 10b6 0007 Presto PCI Plus Adapter
+ 0004 Smart 16/4 PCI Ringnode Mk1
+ 0006 16/4 Cardbus Adapter
+ 10b6 0006 16/4 CardBus Adapter
+ 0007 Presto PCI Adapter
+ 10b6 0007 Presto PCI
+ 0009 Smart 100/16/4 PCI-HS Ringnode
+ 10b6 0009 Smart 100/16/4 PCI-HS Ringnode
+ 000a Smart 100/16/4 PCI Ringnode
+ 10b6 000a Smart 100/16/4 PCI Ringnode
+ 000b 16/4 CardBus Adapter Mk2
+ 10b6 0008 16/4 CardBus Adapter Mk2
+ 10b6 000b 16/4 Cardbus Adapter Mk2
+ 000c RapidFire 3140V2 16/4 TR Adapter
+ 10b6 000c RapidFire 3140V2 16/4 TR Adapter
+ 1000 Collage 25/155 ATM Client Adapter
+ 1001 Collage 155 ATM Server Adapter
+10b7 3Com Corporation
+ 0001 3c985 1000BaseSX (SX/TX)
+ 0013 AR5212 802.11abg NIC (3CRDAG675)
+ 10b7 2031 3CRDAG675 11a/b/g Wireless PCI Adapter
+ 0910 3C910-A01
+ 1006 MINI PCI type 3B Data Fax Modem
+ 1007 Mini PCI 56k Winmodem
+ 10b7 615c Mini PCI 56K Modem
+ 1201 3c982-TXM 10/100baseTX Dual Port A [Hydra]
+ 1202 3c982-TXM 10/100baseTX Dual Port B [Hydra]
+ 1700 3c940 10/100/1000Base-T [Marvell]
+ 1043 80eb A7V600/P4P800/K8V motherboard
+ 10b7 0010 3C940 Gigabit LOM Ethernet Adapter
+ 10b7 0020 3C941 Gigabit LOM Ethernet Adapter
+ 147b 1407 KV8-MAX3 motherboard
+ 3390 3c339 TokenLink Velocity
+ 3590 3c359 TokenLink Velocity XL
+ 10b7 3590 TokenLink Velocity XL Adapter (3C359/359B)
+ 4500 3c450 HomePNA [Tornado]
+ 5055 3c555 Laptop Hurricane
+ 5057 3c575 Megahertz 10/100 LAN CardBus [Boomerang]
+ 10b7 5a57 3C575 Megahertz 10/100 LAN Cardbus PC Card
+ 5157 3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
+ 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
+ 5257 3cCFE575CT CardBus [Cyclone]
+ 10b7 5c57 FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
+ 5900 3c590 10BaseT [Vortex]
+ 5920 3c592 EISA 10mbps Demon/Vortex
+ 5950 3c595 100BaseTX [Vortex]
+ 5951 3c595 100BaseT4 [Vortex]
+ 5952 3c595 100Base-MII [Vortex]
+ 5970 3c597 EISA Fast Demon/Vortex
+ 5b57 3c595 Megahertz 10/100 LAN CardBus [Boomerang]
+ 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
+ 6000 3CRSHPW796 [OfficeConnect Wireless CardBus]
+ 6001 3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]
+ 6055 3c556 Hurricane CardBus [Cyclone]
+ 6056 3c556B CardBus [Tornado]
+ 10b7 6556 10/100 Mini PCI Ethernet Adapter
+ 6560 3cCFE656 CardBus [Cyclone]
+ 10b7 656a 3CCFEM656 10/100 LAN+56K Modem CardBus
+ 6561 3cCFEM656 10/100 LAN+56K Modem CardBus
+ 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
+ 6562 3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
+ 10b7 656b 3CCFEM656B 10/100 LAN+56K Modem CardBus
+ 6563 3cCFEM656B 10/100 LAN+56K Modem CardBus
+ 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
+ 6564 3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
+ 7646 3cSOHO100-TX Hurricane
+ 7770 3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect]
+ 7940 3c803 FDDILink UTP Controller
+ 7980 3c804 FDDILink SAS Controller
+ 7990 3c805 FDDILink DAS Controller
+ 80eb 3c940B 10/100/1000Base-T
+ 8811 Token ring
+ 9000 3c900 10BaseT [Boomerang]
+ 9001 3c900 10Mbps Combo [Boomerang]
+ 9004 3c900B-TPO Etherlink XL [Cyclone]
+ 10b7 9004 3C900B-TPO Etherlink XL TPO 10Mb
+ 9005 3c900B-Combo Etherlink XL [Cyclone]
+ 10b7 9005 3C900B-Combo Etherlink XL Combo
+ 9006 3c900B-TPC Etherlink XL [Cyclone]
+ 900a 3c900B-FL 10base-FL [Cyclone]
+ 9050 3c905 100BaseTX [Boomerang]
+ 9051 3c905 100BaseT4 [Boomerang]
+ 9054 3C905B-TX Fast Etherlink XL PCI
+ 10b7 9054 3C905B-TX Fast Etherlink XL PCI
+ 9055 3c905B 100BaseTX [Cyclone]
+ 1028 0080 3C905B Fast Etherlink XL 10/100
+ 1028 0081 3C905B Fast Etherlink XL 10/100
+ 1028 0082 3C905B Fast Etherlink XL 10/100
+ 1028 0083 3C905B Fast Etherlink XL 10/100
+ 1028 0084 3C905B Fast Etherlink XL 10/100
+ 1028 0085 3C905B Fast Etherlink XL 10/100
+ 1028 0086 3C905B Fast Etherlink XL 10/100
+ 1028 0087 3C905B Fast Etherlink XL 10/100
+ 1028 0088 3C905B Fast Etherlink XL 10/100
+ 1028 0089 3C905B Fast Etherlink XL 10/100
+ 1028 0090 3C905B Fast Etherlink XL 10/100
+ 1028 0091 3C905B Fast Etherlink XL 10/100
+ 1028 0092 3C905B Fast Etherlink XL 10/100
+ 1028 0093 3C905B Fast Etherlink XL 10/100
+ 1028 0094 3C905B Fast Etherlink XL 10/100
+ 1028 0095 3C905B Fast Etherlink XL 10/100
+ 1028 0096 3C905B Fast Etherlink XL 10/100
+ 1028 0097 3C905B Fast Etherlink XL 10/100
+ 1028 0098 3C905B Fast Etherlink XL 10/100
+ 1028 0099 3C905B Fast Etherlink XL 10/100
+ 10b7 9055 3C905B Fast Etherlink XL 10/100
+ 9056 3c905B-T4 Fast EtherLink XL [Cyclone]
+ 9058 3c905B Deluxe Etherlink 10/100/BNC [Cyclone]
+ 905a 3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]
+ 9200 3c905C-TX/TX-M [Tornado]
+ 1028 0095 3C920 Integrated Fast Ethernet Controller
+ 1028 0097 3C920 Integrated Fast Ethernet Controller
+ 1028 00fe Optiplex GX240
+ 1028 012a 3C920 Integrated Fast Ethernet Controller [Latitude C640]
+ 10b7 1000 3C905C-TX Fast Etherlink for PC Management NIC
+ 10b7 7000 10/100 Mini PCI Ethernet Adapter
+ 10f1 2466 Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
+ 9201 3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
+ 1043 80ab A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
+ 9202 3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
+ 9210 3C920B-EMB-WNM Integrated Fast Ethernet Controller
+ 9300 3CSOHO100B-TX 910-A01 [tulip]
+ 9800 3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
+ 10b7 9800 3c980-TX Fast Etherlink XL Server Adapter
+ 9805 3c980-C 10/100baseTX NIC [Python-T]
+ 10b7 1201 EtherLink Server 10/100 Dual Port A
+ 10b7 1202 EtherLink Server 10/100 Dual Port B
+ 10b7 9805 3c980 10/100baseTX NIC [Python-T]
+ 10f1 2462 Thunder K7 S2462
+ 9900 3C990-TX [Typhoon]
+ 9902 3CR990-TX-95 [Typhoon 56-bit]
+ 9903 3CR990-TX-97 [Typhoon 168-bit]
+ 9904 3C990B-TX-M/3C990BSVR [Typhoon2]
+ 10b7 1000 3CR990B-TX-M [Typhoon2]
+ 10b7 2000 3CR990BSVR [Typhoon2 Server]
+ 9905 3CR990-FX-95/97/95 [Typhon Fiber]
+ 10b7 1101 3CR990-FX-95 [Typhoon Fiber 56-bit]
+ 10b7 1102 3CR990-FX-97 [Typhoon Fiber 168-bit]
+ 10b7 2101 3CR990-FX-95 Server [Typhoon Fiber 56-bit]
+ 10b7 2102 3CR990-FX-97 Server [Typhoon Fiber 168-bit]
+ 9908 3CR990SVR95 [Typhoon Server 56-bit]
+ 9909 3CR990SVR97 [Typhoon Server 168-bit]
+ 990a 3C990SVR [Typhoon Server]
+ 990b 3C990SVR [Typhoon Server]
+10b8 Standard Microsystems Corp [SMC]
+ 0005 83c170 EPIC/100 Fast Ethernet Adapter
+ 1055 e000 LANEPIC 10/100 [EVB171Q-PCI]
+ 1055 e002 LANEPIC 10/100 [EVB171G-PCI]
+ 10b8 a011 EtherPower II 10/100
+ 10b8 a014 EtherPower II 10/100
+ 10b8 a015 EtherPower II 10/100
+ 10b8 a016 EtherPower II 10/100
+ 10b8 a017 EtherPower II 10/100
+ 0006 83c175 EPIC/100 Fast Ethernet Adapter
+ 1055 e100 LANEPIC Cardbus Fast Ethernet Adapter
+ 1055 e102 LANEPIC Cardbus Fast Ethernet Adapter
+ 1055 e300 LANEPIC Cardbus Fast Ethernet Adapter
+ 1055 e302 LANEPIC Cardbus Fast Ethernet Adapter
+ 10b8 a012 LANEPIC Cardbus Fast Ethernet Adapter
+ 13a2 8002 LANEPIC Cardbus Fast Ethernet Adapter
+ 13a2 8006 LANEPIC Cardbus Fast Ethernet Adapter
+ 1000 FDC 37c665
+ 1001 FDC 37C922
+ 2802 SMC2802W [EZ Connect g]
+ a011 83C170QF
+ b106 SMC34C90
+10b9 ALi Corporation
+ 0101 CMI8338/C3DX PCI Audio Device
+ 0111 C-Media CMI8738/C3DX Audio Device (OEM)
+ 10b9 0111 C-Media CMI8738/C3DX Audio Device (OEM)
+ 0780 Multi-IO Card
+ 0782 Multi-IO Card
+ 1435 M1435
+ 1445 M1445
+ 1449 M1449
+ 1451 M1451
+ 1461 M1461
+ 1489 M1489
+ 1511 M1511 [Aladdin]
+ 1512 M1512 [Aladdin]
+ 1513 M1513 [Aladdin]
+ 1521 M1521 [Aladdin III]
+ 10b9 1521 ALI M1521 Aladdin III CPU Bridge
+ 1523 M1523
+ 10b9 1523 ALI M1523 ISA Bridge
+ 1531 M1531 [Aladdin IV]
+ 1533 M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+]
+ 1014 053b ThinkPad R40e (2684-HVG) PCI to ISA Bridge
+ 10b9 1533 ALi M1533 Aladdin IV/V ISA Bridge
+ 1541 M1541
+ 10b9 1541 ALI M1541 Aladdin V/V+ AGP System Controller
+ 1543 M1543
+ 1563 M1563 HyperTransport South Bridge
+ 1573 PCI to LPC Controller
+ 1621 M1621
+ 1631 ALI M1631 PCI North Bridge Aladdin Pro III
+ 1632 M1632M Northbridge+Trident
+ 1641 ALI M1641 PCI North Bridge Aladdin Pro IV
+ 1644 M1644/M1644T Northbridge+Trident
+ 1646 M1646 Northbridge+Trident
+ 1647 M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
+ 1651 M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
+ 1671 M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
+ 1672 M1672 Northbridge [CyberALADDiN-P4]
+ 1681 M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
+ 1687 M1687 K8 Northbridge [AGP8X and HyperTransport]
+ 1689 M1689 K8 Northbridge [Super K8 Single Chip]
+ 1695 M1695 K8 Northbridge [PCI Express and HyperTransport]
+ 1697 M1697 HTT Host Bridge
+ 3141 M3141
+ 3143 M3143
+ 3145 M3145
+ 3147 M3147
+ 3149 M3149
+ 3151 M3151
+ 3307 M3307
+ 3309 M3309
+ 3323 M3325 Video/Audio Decoder
+ 5212 M4803
+ 5215 MS4803
+ 5217 M5217H
+ 5219 M5219
+ 5225 M5225
+ 5228 M5228 ALi ATA/RAID Controller
+ 5229 M5229 IDE
+ 1014 050f ThinkPad R30
+ 1014 053d ThinkPad R40e (2684-HVG) builtin IDE
+ 103c 0024 Pavilion ze4400 builtin IDE
+ 1043 8053 A7A266 Motherboard IDE
+ 5235 M5225
+ 5237 USB 1.1 Controller
+ 1014 0540 ThinkPad R40e (2684-HVG) builtin USB
+ 103c 0024 Pavilion ze4400 builtin USB
+ 104d 810f VAIO PCG-U1 USB/OHCI Revision 1.0
+ 5239 USB 2.0 Controller
+ 5243 M1541 PCI to AGP Controller
+ 5246 AGP8X Controller
+ 5247 PCI to AGP Controller
+ 5249 M5249 HTT to PCI Bridge
+ 524b PCI Express Root Port
+ 524c PCI Express Root Port
+ 524d PCI Express Root Port
+ 524e PCI Express Root Port
+ 5251 M5251 P1394 OHCI 1.0 Controller
+ 5253 M5253 P1394 OHCI 1.1 Controller
+ 5261 M5261 Ethernet Controller
+ 5263 ULi 1689,1573 integrated ethernet.
+ 5281 ALi M5281 Serial ATA / RAID Host Controller
+ 5287 ULi 5287 SATA
+ 5288 ULi M5288 SATA
+ 5289 ULi 5289 SATA
+ 5450 Lucent Technologies Soft Modem AMR
+ 5451 M5451 PCI AC-Link Controller Audio Device
+ 1014 0506 ThinkPad R30
+ 1014 053e ThinkPad R40e (2684-HVG) builtin Audio
+ 103c 0024 Pavilion ze4400 builtin Audio
+ 10b9 5451 HP Compaq nc4010 (DY885AA#ABN)
+ 5453 M5453 PCI AC-Link Controller Modem Device
+ 5455 M5455 PCI AC-Link Controller Audio Device
+ 5457 M5457 AC'97 Modem Controller
+ 1014 0535 ThinkPad R40e (2684-HVG) builtin modem
+ 103c 0024 Pavilion ze4400 builtin Modem Device
+ 5459 SmartLink SmartPCI561 56K Modem
+ 545a SmartLink SmartPCI563 56K Modem
+ 5461 High Definition Audio/AC'97 Host Controller
+ 5471 M5471 Memory Stick Controller
+ 5473 M5473 SD-MMC Controller
+ 7101 M7101 Power Management Controller [PMU]
+ 1014 0510 ThinkPad R30
+ 1014 053c ThinkPad R40e (2684-HVG) Power Management Controller
+ 103c 0024 Pavilion ze4400
+10ba Mitsubishi Electric Corp.
+ 0301 AccelGraphics AccelECLIPSE
+ 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
+ 0308 Tornado 3000 [OEM Evans & Sutherland]
+ 1002 VG500 [VolumePro Volume Rendering Accelerator]
+10bb Dapha Electronics Corporation
+10bc Advanced Logic Research
+10bd Surecom Technology
+ 0e34 NE-34
+10be Tseng Labs International Co.
+10bf Most Inc
+10c0 Boca Research Inc.
+10c1 ICM Co., Ltd.
+10c2 Auspex Systems Inc.
+10c3 Samsung Semiconductors, Inc.
+ 1100 Smartether100 SC1100 LAN Adapter (i82557B)
+10c4 Award Software International Inc.
+10c5 Xerox Corporation
+10c6 Rambus Inc.
+10c7 Media Vision
+10c8 Neomagic Corporation
+ 0001 NM2070 [MagicGraph 128]
+ 0002 NM2090 [MagicGraph 128V]
+ 0003 NM2093 [MagicGraph 128ZV]
+ 0004 NM2160 [MagicGraph 128XD]
+ 1014 00ba MagicGraph 128XD
+ 1025 1007 MagicGraph 128XD
+ 1028 0074 MagicGraph 128XD
+ 1028 0075 MagicGraph 128XD
+ 1028 007d MagicGraph 128XD
+ 1028 007e MagicGraph 128XD
+ 1033 802f MagicGraph 128XD
+ 104d 801b MagicGraph 128XD
+ 104d 802f MagicGraph 128XD
+ 104d 830b MagicGraph 128XD
+ 10ba 0e00 MagicGraph 128XD
+ 10c8 0004 MagicGraph 128XD
+ 10cf 1029 MagicGraph 128XD
+ 10f7 8308 MagicGraph 128XD
+ 10f7 8309 MagicGraph 128XD
+ 10f7 830b MagicGraph 128XD
+ 10f7 830d MagicGraph 128XD
+ 10f7 8312 MagicGraph 128XD
+ 0005 NM2200 [MagicGraph 256AV]
+ 1014 00dd ThinkPad 570
+ 1028 0088 Latitude CPi A
+ 0006 NM2360 [MagicMedia 256ZX]
+ 0016 NM2380 [MagicMedia 256XL+]
+ 10c8 0016 MagicMedia 256XL+
+ 0025 NM2230 [MagicGraph 256AV+]
+ 0083 NM2093 [MagicGraph 128ZV+]
+ 8005 NM2200 [MagicMedia 256AV Audio]
+ 0e11 b0d1 MagicMedia 256AV Audio Device on Discovery
+ 0e11 b126 MagicMedia 256AV Audio Device on Durango
+ 1014 00dd MagicMedia 256AV Audio Device on BlackTip Thinkpad
+ 1025 1003 MagicMedia 256AV Audio Device on TravelMate 720
+ 1028 0088 Latitude CPi A
+ 1028 008f MagicMedia 256AV Audio Device on Colorado Inspiron
+ 103c 0007 MagicMedia 256AV Audio Device on Voyager II
+ 103c 0008 MagicMedia 256AV Audio Device on Voyager III
+ 103c 000d MagicMedia 256AV Audio Device on Omnibook 900
+ 10c8 8005 MagicMedia 256AV Audio Device on FireAnt
+ 110a 8005 MagicMedia 256AV Audio Device
+ 14c0 0004 MagicMedia 256AV Audio Device
+ 8006 NM2360 [MagicMedia 256ZX Audio]
+ 8016 NM2380 [MagicMedia 256XL+ Audio]
+10c9 Dataexpert Corporation
+10ca Fujitsu Microelectr., Inc.
+10cb Omron Corporation
+# nee Mentor ARC Inc
+10cc Mai Logic Incorporated
+ 0660 Articia S Host Bridge
+ 0661 Articia S PCI Bridge
+10cd Advanced System Products, Inc
+ 1100 ASC1100
+ 1200 ASC1200 [(abp940) Fast SCSI-II]
+ 1300 ABP940-U / ABP960-U
+ 10cd 1310 ASC1300 SCSI Adapter
+ 1195 1320 Ultra-SCSI CardBus PC Card REX CB31
+ 2300 ABP940-UW
+ 2500 ABP940-U2W
+10ce Radius
+# nee Citicorp TTI
+10cf Fujitsu Limited.
+ 2001 mb86605
+10d1 FuturePlus Systems Corp.
+10d2 Molex Incorporated
+10d3 Jabil Circuit Inc
+10d4 Hualon Microelectronics
+10d5 Autologic Inc.
+10d6 Cetia
+10d7 BCM Advanced Research
+10d8 Advanced Peripherals Labs
+10d9 Macronix, Inc. [MXIC]
+ 0431 MX98715
+ 0512 MX98713
+ 0531 MX987x5
+ 1186 1200 DFE-540TX ProFAST 10/100 Adapter
+ 8625 MX86250
+ 8626 Macronix MX86251 + 3Dfx Voodoo Rush
+ 8888 MX86200
+10da Compaq IPG-Austin
+ 0508 TC4048 Token Ring 4/16
+ 3390 Tl3c3x9
+10db Rohm LSI Systems, Inc.
+10dc CERN/ECP/EDU
+ 0001 STAR/RD24 SCI-PCI (PMC)
+ 0002 TAR/RD24 SCI-PCI (PMC)
+ 0021 HIPPI destination
+ 0022 HIPPI source
+ 10dc ATT2C15-3 FPGA
+10dd Evans & Sutherland
+ 0100 Lightning 1200
+10de nVidia Corporation
+ 0008 NV1 [EDGE 3D]
+ 0009 NV1 [EDGE 3D]
+ 0010 NV2 [Mutara V08]
+ 0020 NV4 [RIVA TNT]
+ 1043 0200 V3400 TNT
+ 1048 0c18 Erazor II SGRAM
+ 1048 0c19 Erazor II
+ 1048 0c1b Erazor II
+ 1048 0c1c Erazor II
+ 1092 0550 Viper V550
+ 1092 0552 Viper V550
+ 1092 4804 Viper V550
+ 1092 4808 Viper V550
+ 1092 4810 Viper V550
+ 1092 4812 Viper V550
+ 1092 4815 Viper V550
+ 1092 4820 Viper V550 with TV out
+ 1092 4822 Viper V550
+ 1092 4904 Viper V550
+ 1092 4914 Viper V550
+ 1092 8225 Viper V550
+ 10b4 273d Velocity 4400
+ 10b4 273e Velocity 4400
+ 10b4 2740 Velocity 4400
+ 10de 0020 Riva TNT
+ 1102 1015 Graphics Blaster CT6710
+ 1102 1016 Graphics Blaster RIVA TNT
+ 0028 NV5 [RIVA TNT2/TNT2 Pro]
+ 1043 0200 AGP-V3800 SGRAM
+ 1043 0201 AGP-V3800 SDRAM
+ 1043 0205 PCI-V3800
+ 1043 4000 AGP-V3800PRO
+ 1048 0c21 Synergy II
+ 1048 0c28 Erazor III
+ 1048 0c29 Erazor III
+ 1048 0c2a Erazor III
+ 1048 0c2b Erazor III
+ 1048 0c31 Erazor III Pro
+ 1048 0c32 Erazor III Pro
+ 1048 0c33 Erazor III Pro
+ 1048 0c34 Erazor III Pro
+ 107d 2134 WinFast 3D S320 II + TV-Out
+ 1092 4804 Viper V770
+ 1092 4a00 Viper V770
+ 1092 4a02 Viper V770 Ultra
+ 1092 5a00 RIVA TNT2/TNT2 Pro
+ 1092 6a02 Viper V770 Ultra
+ 1092 7a02 Viper V770 Ultra
+ 10de 0005 RIVA TNT2 Pro
+ 10de 000f Compaq NVIDIA TNT2 Pro
+ 1102 1020 3D Blaster RIVA TNT2
+ 1102 1026 3D Blaster RIVA TNT2 Digital
+ 14af 5810 Maxi Gamer Xentor
+ 0029 NV5 [RIVA TNT2 Ultra]
+ 1043 0200 AGP-V3800 Deluxe
+ 1043 0201 AGP-V3800 Ultra SDRAM
+ 1043 0205 PCI-V3800 Ultra
+ 1048 0c2e Erazor III Ultra
+ 1048 0c2f Erazor III Ultra
+ 1048 0c30 Erazor III Ultra
+ 1102 1021 3D Blaster RIVA TNT2 Ultra
+ 1102 1029 3D Blaster RIVA TNT2 Ultra
+ 1102 102f 3D Blaster RIVA TNT2 Ultra
+ 14af 5820 Maxi Gamer Xentor 32
+ 002a NV5 [Riva TnT2]
+ 002b NV5 [Riva TnT2]
+ 002c NV6 [Vanta/Vanta LT]
+ 1043 0200 AGP-V3800 Combat SDRAM
+ 1043 0201 AGP-V3800 Combat
+ 1048 0c20 TNT2 Vanta
+ 1048 0c21 TNT2 Vanta
+ 1092 6820 Viper V730
+ 1102 1031 CT6938 VANTA 8MB
+ 1102 1034 CT6894 VANTA 16MB
+ 14af 5008 Maxi Gamer Phoenix 2
+ 002d NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
+ 1043 0200 AGP-V3800M
+ 1043 0201 AGP-V3800M
+ 1048 0c3a Erazor III LT
+ 1048 0c3b Erazor III LT
+ 10de 001e M64 AGP4x
+ 1102 1023 CT6892 RIVA TNT2 Value
+ 1102 1024 CT6932 RIVA TNT2 Value 32Mb
+ 1102 102c CT6931 RIVA TNT2 Value [Jumper]
+ 1462 8808 MSI-8808
+ 1554 1041 Pixelview RIVA TNT2 M64
+ 1569 002d Palit Microsystems Daytona TNT2 M64
+ 002e NV6 [Vanta]
+ 002f NV6 [Vanta]
+ 0034 MCP04 SMBus
+ 0035 MCP04 IDE
+ 0036 MCP04 Serial ATA Controller
+ 0037 MCP04 Ethernet Controller
+ 0038 MCP04 Ethernet Controller
+ 003a MCP04 AC'97 Audio Controller
+ 003b MCP04 USB Controller
+ 003c MCP04 USB Controller
+ 003d MCP04 PCI Bridge
+ 003e MCP04 Serial ATA Controller
+ 0040 NV40 [GeForce 6800 Ultra]
+ 0041 NV40 [GeForce 6800]
+ 1043 817b V9999 Gamer Edition
+ 0042 NV40.2 [GeForce 6800 LE]
+ 0043 NV40.3
+ 0044 NV40 [GeForce 6800 XT]
+ 0045 NV40 [GeForce 6800 GT]
+ 0047 NV40 [GeForce 6800 GS]
+ 1682 2109 GeForce 6800 GS
+ 0049 NV40GL
+ 004e NV40GL [Quadro FX 4000]
+ 0050 CK804 ISA Bridge
+ 1043 815a K8N4-E Mainboard
+ 1458 0c11 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 0051 CK804 ISA Bridge
+ 0052 CK804 SMBus
+ 1043 815a K8N4-E Mainboard
+ 1458 0c11 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 0053 CK804 IDE
+ 1043 815a K8N4-E Mainboard
+ 1458 5002 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 0054 CK804 Serial ATA Controller
+ 1458 b003 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 0055 CK804 Serial ATA Controller
+ 1043 815a K8N4-E Mainboard
+ 1458 b003 GA-K8N Ultra-9 Mainboard
+ 147b 1c1a KN8-Ultra Mainboard
+ 0056 CK804 Ethernet Controller
+ 0057 CK804 Ethernet Controller
+ 1043 8141 K8N4-E Mainboard
+ 1458 e000 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 0058 CK804 AC'97 Modem
+ 0059 CK804 AC'97 Audio Controller
+ 1043 812a K8N4-E Mainboard
+ 147b 1c1a KN8-Ultra Mainboard
+ 005a CK804 USB Controller
+ 1043 815a K8N4-E Mainboard
+ 1458 5004 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 005b CK804 USB Controller
+ 1043 815a K8N4-E Mainboard
+ 1458 5004 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 005c CK804 PCI Bridge
+ 005d CK804 PCIE Bridge
+ 005e CK804 Memory Controller
+ 10f1 2891 Thunder K8SRE Mainboard
+ 1458 5000 GA-K8N Ultra-9 Mainboard
+ 1462 7100 MSI K8N Diamond
+ 147b 1c1a KN8-Ultra Mainboard
+ 005f CK804 Memory Controller
+ 0060 nForce2 ISA Bridge
+ 1043 80ad A7N8X Mainboard
+ a0a0 03ba UK79G-1394 motherboard
+ 0064 nForce2 SMBus (MCP)
+ a0a0 03bb UK79G-1394 motherboard
+ 0065 nForce2 IDE
+ a0a0 03b2 UK79G-1394 motherboard
+ 0066 nForce2 Ethernet Controller
+ 1043 80a7 A7N8X Mainboard onboard nForce2 Ethernet
+ 0067 nForce2 USB Controller
+ 1043 0c11 A7N8X Mainboard
+ 0068 nForce2 USB Controller
+ 1043 0c11 A7N8X Mainboard
+ a0a0 03b4 UK79G-1394 motherboard
+ 006a nForce2 AC97 Audio Controler (MCP)
+ 1043 8095 nForce2 AC97 Audio Controler (MCP)
+ a0a0 0304 UK79G-1394 motherboard
+ 006b nForce Audio Processing Unit
+ 10de 006b nForce2 MCP Audio Processing Unit
+ 006c nForce2 External PCI Bridge
+ 006d nForce2 PCI Bridge
+ 006e nForce2 FireWire (IEEE 1394) Controller
+ a0a0 0306 UK79G-1394 motherboard
+ 0080 MCP2A ISA bridge
+ 147b 1c09 NV7 Motherboard
+ 0084 MCP2A SMBus
+ 147b 1c09 NV7 Motherboard
+ 0085 MCP2A IDE
+ 147b 1c09 NV7 Motherboard
+ 0086 MCP2A Ethernet Controller
+ 0087 MCP2A USB Controller
+ 147b 1c09 NV7 Motherboard
+ 0088 MCP2A USB Controller
+ 147b 1c09 NV7 Motherboard
+ 008a MCP2S AC'97 Audio Controller
+ 147b 1c09 NV7 Motherboard
+ 008b MCP2A PCI Bridge
+ 008c MCP2A Ethernet Controller
+ 008e nForce2 Serial ATA Controller
+ 0090 G70 [GeForce 7800 GTX]
+ 0091 G70 [GeForce 7800 GTX]
+ 0092 G70 [GeForce 7800 GT]
+ 0093 G70 [GeForce 7800 GS]
+ 0098 GeForce Go 7800
+ 0099 GE Force Go 7800 GTX
+ 009d G70GL [Quadro FX4500]
+ 00a0 NV5 [Aladdin TNT2]
+ 14af 5810 Maxi Gamer Xentor
+ 00c0 NV41 [GeForce 6800 GS]
+ 00c1 NV41.1 [GeForce 6800]
+ 00c2 NV41.2 [GeForce 6800 LE]
+ 00c3 NV42 [Geforce 6800 XT]
+ 00c8 NV41.8 [GeForce Go 6800]
+ 00c9 NV41.9 [GeForce Go 6800 Ultra]
+ 00cc NV41 [Quadro FX Go1400]
+ 00cd NV41 [Quadro FX 3450/4000 SDI]
+ 10de 029b wx4300 Workstation
+ 00ce NV41GL [Quadro FX 1400]
+ 00d0 nForce3 LPC Bridge
+ 00d1 nForce3 Host Bridge
+ 00d2 nForce3 AGP Bridge
+ 00d3 CK804 Memory Controller
+ 00d4 nForce3 SMBus
+ 00d5 nForce3 IDE
+ 00d6 nForce3 Ethernet
+ 00d7 nForce3 USB 1.1
+ 00d8 nForce3 USB 2.0
+ 00d9 nForce3 Audio
+ 00da nForce3 Audio
+ 00dd nForce3 PCI Bridge
+ 00df CK8S Ethernet Controller
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00e0 nForce3 250Gb LPC Bridge
+ 10de 0c11 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00e1 nForce3 250Gb Host Bridge
+ 147b 1c0b NF8 Mainboard
+ 00e2 nForce3 250Gb AGP Host to PCI Bridge
+ 00e3 CK8S Serial ATA Controller (v2.5)
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00e4 nForce 250Gb PCI System Management
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00e5 CK8S Parallel ATA Controller (v2.5)
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00e6 CK8S Ethernet Controller
+ 00e7 CK8S USB Controller
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00e8 nForce3 EHCI USB 2.0 Controller
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00ea nForce3 250Gb AC'97 Audio Controller
+ 105b 0c43 Winfast NF3250K8AA
+ 147b 1c0b NF8 Mainboard
+ 00ed nForce3 250Gb PCI-to-PCI Bridge
+ 00ee CK8S Serial ATA Controller (v2.5)
+ 00f0 NV40 [GeForce 6800/GeForce 6800 Ultra]
+ 00f1 NV43 [GeForce 6600/GeForce 6600 GT]
+ 1043 81a6 N6600GT TD 128M AGP
+ 1682 2119 GeForce 6600 GT AGP 128MB DDR3 DUAL DVI TV
+ 00f2 NV43 [GeForce 6600/GeForce 6600 GT]
+ 1682 211c GeForce 6600 256MB DDR DUAL DVI TV
+ 00f3 NV43 [GeForce 6200]
+ 00f4 NV43 [GeForce 6600 LE]
+ 00f5 G70 [GeForce 7800 GS]
+ 00f6 NV43 [GeForce 6600 GS]
+ 00f8 NV45GL [Quadro FX 3400/4400]
+ 00f9 NV40 [GeForce 6800 Ultra/GeForce 6800 GT]
+ 1682 2120 GEFORCE 6800 GT PCI-E
+ 00fa NV36 [GeForce PCX 5750]
+ 00fb NV35 [GeForce PCX 5900]
+ 00fc NV37GL [Quadro FX 330/GeForce PCX 5300]
+ 00fd NV37GL [Quadro FX 330/Quadro NVS280]
+ 00fe NV38GL [Quadro FX 1300]
+ 00ff NV18 [GeForce PCX 4300]
+ 0100 NV10 [GeForce 256 SDR]
+ 1043 0200 AGP-V6600 SGRAM
+ 1043 0201 AGP-V6600 SDRAM
+ 1043 4008 AGP-V6600 SGRAM
+ 1043 4009 AGP-V6600 SDRAM
+ 1048 0c41 Erazor X
+ 1048 0c43 ERAZOR X PCI
+ 1048 0c48 Synergy Force
+ 1102 102d CT6941 GeForce 256
+ 14af 5022 3D Prophet SE
+ 0101 NV10DDR [GeForce 256 DDR]
+ 1043 0202 AGP-V6800 DDR
+ 1043 400a AGP-V6800 DDR SGRAM
+ 1043 400b AGP-V6800 DDR SDRAM
+ 1048 0c42 Erazor X
+ 107d 2822 WinFast GeForce 256
+ 1102 102e CT6971 GeForce 256 DDR
+ 14af 5021 3D Prophet DDR-DVI
+ 0103 NV10GL [Quadro]
+ 1048 0c40 GLoria II-64
+ 1048 0c44 GLoria II
+ 1048 0c45 GLoria II
+ 1048 0c4a GLoria II-64 Pro
+ 1048 0c4b GLoria II-64 Pro DVII
+ 0110 NV11 [GeForce2 MX/MX 400]
+ 1043 4015 AGP-V7100 Pro
+ 1043 4031 V7100 Pro with TV output
+ 1048 0c60 Gladiac MX
+ 1048 0c61 Gladiac 511PCI
+ 1048 0c63 Gladiac 511TV-OUT 32MB
+ 1048 0c64 Gladiac 511TV-OUT 64MB
+ 1048 0c65 Gladiac 511TWIN
+ 1048 0c66 Gladiac 311
+ 10de 0091 Dell OEM GeForce 2 MX 400
+ 10de 00a1 Apple OEM GeForce2 MX
+ 1462 8817 MSI GeForce2 MX400 Pro32S [MS-8817]
+ 14af 7102 3D Prophet II MX
+ 14af 7103 3D Prophet II MX Dual-Display
+ 0111 NV11DDR [GeForce2 MX 100 DDR/200 DDR]
+ 0112 NV11 [GeForce2 Go]
+ 0113 NV11GL [Quadro2 MXR/EX/Go]
+ 0140 NV43 [GeForce 6600 GT]
+ 0141 NV43 [GeForce 6600]
+ 1458 3124 GV-NX66128DP Turbo Force Edition
+ 0142 NV43 [GeForce 6600 PCIe]
+ 0144 NV43 [GeForce Go 6600]
+ 0145 NV43 [GeForce 6610 XL]
+ 0146 NV43 [Geforce Go 6600TE/6200TE]
+ 0148 NV43 [GeForce Go 6600]
+ 0149 NV43 [GeForce Go 6600 GT]
+ 014a Quadro NVS 440
+ 014c Quadro FX 550
+ 014e NV43GL [Quadro FX 540]
+ 014f NV43 [GeForce 6200]
+ 0150 NV15 [GeForce2 GTS/Pro]
+ 1043 4016 V7700 AGP Video Card
+ 1048 0c50 Gladiac
+ 1048 0c52 Gladiac-64
+ 107d 2840 WinFast GeForce2 GTS with TV output
+ 107d 2842 WinFast GeForce 2 Pro
+ 10de 002e GeForce2 GTS
+ 1462 8831 Creative GeForce2 Pro
+ 0151 NV15DDR [GeForce2 Ti]
+ 1043 405f V7700Ti
+ 1462 5506 Creative 3D Blaster Geforce2 Titanium
+ 0152 NV15BR [GeForce2 Ultra, Bladerunner]
+ 1048 0c56 GLADIAC Ultra
+ 0153 NV15GL [Quadro2 Pro]
+ 0161 NV44 [GeForce 6200 TurboCache(TM)]
+ 0162 NV44 [GeForce 6200 SE TurboCache (TM)]
+ 0163 NV44 [GeForce 6200 LE]
+ 0164 NV44 [GeForce Go 6200]
+ 0165 NV44 [Quadro NVS 285]
+ 0166 NV43 [GeForce Go 6400]
+ 0167 GeForce Go 6200 TurboCache
+ 0168 NV43 [GeForce Go 6200 TurboCache]
+ 0170 NV17 [GeForce4 MX 460]
+ 0171 NV17 [GeForce4 MX 440]
+ 10b0 0002 Gainward Pro/600 TV
+ 10de 0008 Apple OEM GeForce4 MX 440
+ 1462 8661 G4MX440-VTP
+ 1462 8730 MX440SES-T (MS-8873)
+ 1462 8852 GeForce4 MX440 PCI
+ 147b 8f00 Abit Siluro GeForce4MX440
+ 0172 NV17 [GeForce4 MX 420]
+ 0173 NV17 [GeForce4 MX 440-SE]
+ 0174 NV17 [GeForce4 440 Go]
+ 0175 NV17 [GeForce4 420 Go]
+ 0176 NV17 [GeForce4 420 Go 32M]
+ 103c 08b0 tc1100 tablet
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 0177 NV17 [GeForce4 460 Go]
+ 0178 NV17GL [Quadro4 550 XGL]
+ 0179 NV17 [GeForce4 420 Go 32M]
+ 10de 0179 GeForce4 MX (Mac)
+ 017a NV17GL [Quadro4 200/400 NVS]
+ 017b NV17GL [Quadro4 550 XGL]
+ 017c NV17GL [Quadro4 500 GoGL]
+ 017d NV17 [GeForce4 410 Go 16M]
+ 0181 NV18 [GeForce4 MX 440 AGP 8x]
+ 1043 806f V9180 Magic
+ 1462 8880 MS-StarForce GeForce4 MX 440 with AGP8X
+ 1462 8900 MS-8890 GeForce 4 MX440 AGP8X
+ 1462 9350 MSI Geforce4 MX T8X with AGP8X
+ 147b 8f0d Siluro GF4 MX-8X
+ 0182 NV18 [GeForce4 MX 440SE AGP 8x]
+ 0183 NV18 [GeForce4 MX 420 AGP 8x]
+ 0185 NV18 [GeForce4 MX 4000 AGP 8x]
+ 0186 NV18M [GeForce4 448 Go]
+ 0187 NV18M [GeForce4 488 Go]
+ 0188 NV18GL [Quadro4 580 XGL]
+ 018a NV18GL [Quadro4 NVS AGP 8x]
+ 018b NV18GL [Quadro4 380 XGL]
+ 018c Quadro NVS 50 PCI
+ 018d NV18M [GeForce4 448 Go]
+ 01a0 NVCrush11 [GeForce2 MX Integrated Graphics]
+ 01a4 nForce CPU bridge
+ 01ab nForce 420 Memory Controller (DDR)
+ 01ac nForce 220/420 Memory Controller
+ 01ad nForce 220/420 Memory Controller
+ 01b0 nForce Audio
+ 01b1 nForce Audio
+ 01b2 nForce ISA Bridge
+ 01b4 nForce PCI System Management
+ 01b7 nForce AGP to PCI Bridge
+ 01b8 nForce PCI-to-PCI bridge
+ 01bc nForce IDE
+ 01c1 nForce AC'97 Modem Controller
+ 01c2 nForce USB Controller
+ 01c3 nForce Ethernet Controller
+ 01d1 GeForce 7300 LE
+# MSI 7300LE PCI Express Graphics Adapter
+ 1462 0345 John Ennew
+ 01d7 Quadro NVS 110M / GeForce Go 7300
+ 01d8 GeForce Go 7400
+ 01da Quadro NVS 110M
+ 01de Quadro FX 350
+ 10de 01dc Quadro FX Go350M
+ 01df GeForce 7300 GS
+ 01e0 nForce2 AGP (different version?)
+ 147b 1c09 NV7 Motherboard
+ 01e8 nForce2 AGP
+ 01ea nForce2 Memory Controller 0
+ a0a0 03b9 UK79G-1394 motherboard
+ 01eb nForce2 Memory Controller 1
+ a0a0 03b9 UK79G-1394 motherboard
+ 01ec nForce2 Memory Controller 2
+ a0a0 03b9 UK79G-1394 motherboard
+ 01ed nForce2 Memory Controller 3
+ a0a0 03b9 UK79G-1394 motherboard
+ 01ee nForce2 Memory Controller 4
+ a0a0 03b9 UK79G-1394 motherboard
+ 01ef nForce2 Memory Controller 5
+ a0a0 03b9 UK79G-1394 motherboard
+ 01f0 NV18 [GeForce4 MX - nForce GPU]
+ a0a0 03b5 UK79G-1394 motherboard
+ 0200 NV20 [GeForce3]
+ 1043 402f AGP-V8200 DDR
+ 1048 0c70 GLADIAC 920
+ 0201 NV20 [GeForce3 Ti 200]
+ 0202 NV20 [GeForce3 Ti 500]
+ 1043 405b V8200 T5
+ 1545 002f Xtasy 6964
+ 0203 NV20DCC [Quadro DCC]
+ 0211 NV40 [GeForce 6800]
+ 0212 NV40 [GeForce 6800 LE]
+ 0215 NV40 [GeForce 6800 GT]
+ 0218 NV40 [GeForce 6800 XT]
+ 0221 NV43 [GeForce 6200]
+ 0240 C51PV [GeForce 6150]
+ 1462 7207 K8NGM2 series
+ 0241 C51 PCI Express Bridge
+ 0242 C51G [GeForce 6100]
+ 0243 C51 PCI Express Bridge
+ 0244 C51 PCI Express Bridge
+ 0245 C51 PCI Express Bridge
+ 0246 C51 PCI Express Bridge
+ 0247 C51 PCI Express Bridge
+ 0248 C51 PCI Express Bridge
+ 0249 C51 PCI Express Bridge
+ 024a C51 PCI Express Bridge
+ 024b C51 PCI Express Bridge
+ 024c C51 PCI Express Bridge
+ 024d C51 PCI Express Bridge
+ 024e C51 PCI Express Bridge
+ 024f C51 PCI Express Bridge
+ 0250 NV25 [GeForce4 Ti 4600]
+ 0251 NV25 [GeForce4 Ti 4400]
+ 1043 8023 v8440 GeForce 4 Ti4400
+ 0252 NV25 [GeForce4 Ti]
+ 0253 NV25 [GeForce4 Ti 4200]
+ 107d 2896 WinFast A250 LE TD (Dual VGA/TV-out/DVI)
+ 147b 8f09 Siluro (Dual VGA/TV-out/DVI)
+ 0258 NV25GL [Quadro4 900 XGL]
+ 0259 NV25GL [Quadro4 750 XGL]
+ 025b NV25GL [Quadro4 700 XGL]
+ 0260 MCP51 LPC Bridge
+ 1462 7207 K8NGM2 series
+ 0261 MCP51 LPC Bridge
+ 0262 MCP51 LPC Bridge
+ 0263 MCP51 LPC Bridge
+ 0264 MCP51 SMBus
+ 1462 7207 K8NGM2 series
+ 0265 MCP51 IDE
+ 1462 7207 K8NGM2 series
+ 0266 MCP51 Serial ATA Controller
+ 1462 7207 K8NGM2 series
+ 0267 MCP51 Serial ATA Controller
+ 1462 7207 K8NGM2 series
+ 0268 MCP51 Ethernet Controller
+ 0269 MCP51 Ethernet Controller
+ 1462 7207 K8NGM2 series
+ 026a MCP51 MCI
+ 026b MCP51 AC97 Audio Controller
+ 026c MCP51 High Definition Audio
+ 1462 7207 K8NGM2 series
+ 026d MCP51 USB Controller
+ 1462 7207 K8NGM2 series
+ 026e MCP51 USB Controller
+ 1462 7207 K8NGM2 series
+ 026f MCP51 PCI Bridge
+ 0270 MCP51 Host Bridge
+ 1462 7207 K8NGM2 series
+ 0271 MCP51 PMU
+ 0272 MCP51 Memory Controller 0
+ 027e C51 Memory Controller 2
+ 1462 7207 K8NGM2 series
+ 027f C51 Memory Controller 3
+ 1462 7207 K8NGM2 series
+ 0280 NV28 [GeForce4 Ti 4800]
+ 0281 NV28 [GeForce4 Ti 4200 AGP 8x]
+ 0282 NV28 [GeForce4 Ti 4800 SE]
+ 0286 NV28 [GeForce4 Ti 4200 Go AGP 8x]
+ 0288 NV28GL [Quadro4 980 XGL]
+ 0289 NV28GL [Quadro4 780 XGL]
+ 028c NV28GLM [Quadro4 700 GoGL]
+ 0290 GeForce 7900 GTX
+ 0291 GeForce 7900 GT
+ 029a G71 [Quadro FX 2500M]
+ 029b G71 [Quadro FX 1500M]
+ 029c Quadro FX 5500
+ 029d Quadro FX 3500
+ 029e Quadro FX 1500
+ 029f Quadro FX 4500 X2
+# Xbox Graphics Processing Unit (Integrated). GeForce3 derivative (NV20 < NV2A < NV25).
+ 02a0 NV2A [XGPU]
+ 02e1 GeForce 7600 GS
+ 02f0 C51 Host Bridge
+ 1462 7207 K8NGM2 series
+ 02f1 C51 Host Bridge
+ 02f2 C51 Host Bridge
+ 02f3 C51 Host Bridge
+ 02f4 C51 Host Bridge
+ 02f5 C51 Host Bridge
+ 02f6 C51 Host Bridge
+ 02f7 C51 Host Bridge
+ 02f8 C51 Memory Controller 5
+ 1462 7207 K8NGM2 series
+ 02f9 C51 Memory Controller 4
+ 1462 7207 K8NGM2 series
+ 02fa C51 Memory Controller 0
+ 1462 7207 K8NGM2 series
+ 02fb C51 PCI Express Bridge
+ 02fc C51 PCI Express Bridge
+ 02fd C51 PCI Express Bridge
+ 02fe C51 Memory Controller 1
+ 1462 7207 K8NGM2 series
+ 02ff C51 Host Bridge
+ 1462 7207 K8NGM2 series
+ 0300 NV30 [GeForce FX]
+ 0301 NV30 [GeForce FX 5800 Ultra]
+ 0302 NV30 [GeForce FX 5800]
+ 0308 NV30GL [Quadro FX 2000]
+ 0309 NV30GL [Quadro FX 1000]
+ 0311 NV31 [GeForce FX 5600 Ultra]
+ 0312 NV31 [GeForce FX 5600]
+ 0313 NV31
+ 0314 NV31 [GeForce FX 5600XT]
+ 1043 814a V9560XT/TD
+ 0316 NV31M
+ 0317 NV31M Pro
+ 031a NV31M [GeForce FX Go5600]
+ 031b NV31M [GeForce FX Go5650]
+ 031c NVIDIA Quadro FX Go700
+ 031d NV31GLM
+ 031e NV31GLM Pro
+ 031f NV31GLM Pro
+ 0320 NV34 [GeForce FX 5200]
+ 0321 NV34 [GeForce FX 5200 Ultra]
+ 0322 NV34 [GeForce FX 5200]
+ 1462 9171 MS-8917 (FX5200-T128)
+ 1462 9360 MS-8936 (FX5200-T128)
+ 0323 NV34 [GeForce FX 5200LE]
+ 0324 NV34M [GeForce FX Go5200]
+ 1028 0196 Inspiron 5160
+ 1071 8160 MIM2000
+ 0325 NV34M [GeForce FX Go5250]
+ 0326 NV34 [GeForce FX 5500]
+ 0327 NV34 [GeForce FX 5100]
+ 0328 NV34M [GeForce FX Go5200 32M/64M]
+ 0329 NV34M [GeForce FX Go5200]
+ 032a NV34GL [Quadro NVS 280 PCI]
+ 032b NV34GL [Quadro FX 500/600 PCI]
+ 032c NV34GLM [GeForce FX Go 5300]
+ 032d NV34 [GeForce FX Go5100]
+ 032f NV34GL
+ 0330 NV35 [GeForce FX 5900 Ultra]
+ 0331 NV35 [GeForce FX 5900]
+ 1043 8145 V9950GE
+ 0332 NV35 [GeForce FX 5900XT]
+ 0333 NV38 [GeForce FX 5950 Ultra]
+ 0334 NV35 [GeForce FX 5900ZT]
+ 0338 NV35GL [Quadro FX 3000]
+ 033f NV35GL [Quadro FX 700]
+ 0341 NV36.1 [GeForce FX 5700 Ultra]
+ 0342 NV36.2 [GeForce FX 5700]
+ 0343 NV36 [GeForce FX 5700LE]
+ 0344 NV36.4 [GeForce FX 5700VE]
+ 0345 NV36.5
+ 0347 NV36 [GeForce FX Go5700]
+ 103c 006a NX9500
+ 0348 NV36 [GeForce FX Go5700]
+ 0349 NV36M Pro
+ 034b NV36MAP
+ 034c NV36 [Quadro FX Go1000]
+ 034e NV36GL [Quadro FX 1100]
+ 034f NV36GL
+ 0360 MCP55 LPC Bridge
+ 0361 MCP55 LPC Bridge
+ 0362 MCP55 LPC Bridge
+ 0363 MCP55 LPC Bridge
+ 0364 MCP55 LPC Bridge
+ 0365 MCP55 LPC Bridge
+ 0366 MCP55 LPC Bridge
+ 0367 MCP55 LPC Bridge
+ 0368 MCP55 SMBus
+ 0369 MCP55 Memory Controller
+ 036a MCP55 Memory Controller
+ 036b MCP55 SMU
+ 036c MCP55 USB Controller
+ 036d MCP55 USB Controller
+ 036e MCP55 IDE
+ 0370 MCP55 PCI bridge
+ 0371 MCP55 High Definition Audio
+ 0372 MCP55 Ethernet
+ 0373 MCP55 Ethernet
+ 0374 MCP55 PCI Express bridge
+ 0375 MCP55 PCI Express bridge
+ 0376 MCP55 PCI Express bridge
+ 0377 MCP55 PCI Express bridge
+ 0378 MCP55 PCI Express bridge
+ 037a MCP55 Memory Controller
+ 037e MCP55 SATA Controller
+ 037f MCP55 SATA Controller
+ 0391 G70 [GeForce 7600 GT]
+ 0392 G70 [GeForce 7600 GS]
+ 1462 0622 NX7600GS-T2D256EH
+ 0398 G70 [GeForce Go 7600]
+ 039e Quadro FX 560
+ 03a0 C55 Host Bridge
+ 03a1 C55 Host Bridge
+ 03a2 C55 Host Bridge
+ 03a3 C55 Host Bridge
+ 03a4 C55 Host Bridge
+ 03a5 C55 Host Bridge
+ 03a6 C55 Host Bridge
+ 03a7 C55 Host Bridge
+ 03a8 C55 Memory Controller
+ 03a9 C55 Memory Controller
+ 03aa C55 Memory Controller
+ 03ab C55 Memory Controller
+ 03ac C55 Memory Controller
+ 03ad C55 Memory Controller
+ 03ae C55 Memory Controller
+ 03af C55 Memory Controller
+ 03b0 C55 Memory Controller
+ 03b1 C55 Memory Controller
+ 03b2 C55 Memory Controller
+ 03b3 C55 Memory Controller
+ 03b4 C55 Memory Controller
+ 03b5 C55 Memory Controller
+ 03b6 C55 Memory Controller
+ 03b7 C55 PCI Express bridge
+ 03b8 C55 PCI Express bridge
+ 03b9 C55 PCI Express bridge
+ 03ba C55 Memory Controller
+ 03bb C55 PCI Express bridge
+ 03e0 MCP61 LPC Bridge
+ 03e1 MCP61 LPC Bridge
+ 03e2 MCP61 LPC Bridge
+ 03e3 MCP61 LPC Bridge
+ 03e4 MCP61 High Definition Audio
+ 03e5 MCP61 Ethernet
+ 03e6 MCP61 Ethernet
+ 03e7 MCP61 SATA Controller
+ 03e8 MCP61 PCI Express bridge
+ 03e9 MCP61 PCI Express bridge
+ 03ea MCP61 Memory Controller
+ 03eb MCP61 SMBus
+ 03ec MCP61 IDE
+ 03ee MCP61 Ethernet
+ 03ef MCP61 Ethernet
+ 03f0 MCP61 High Definition Audio
+ 03f1 MCP61 USB Controller
+ 03f2 MCP61 USB Controller
+ 03f3 MCP61 PCI bridge
+ 03f4 MCP61 SMU
+ 03f5 MCP61 Memory Controller
+ 03f6 MCP61 SATA Controller
+ 03f7 MCP61 SATA Controller
+ 0440 MCP65 LPC Bridge
+ 0441 MCP65 LPC Bridge
+ 0442 MCP65 LPC Bridge
+ 0443 MCP65 LPC Bridge
+ 0444 MCP65 Memory Controller
+ 0445 MCP65 Memory Controller
+ 0446 MCP65 SMBus
+ 0447 MCP65 SMU
+ 0448 MCP65 IDE
+ 0449 MCP65 PCI bridge
+ 044a MCP65 High Definition Audio
+ 044b MCP65 High Definition Audio
+ 044c MCP65 AHCI Controller
+ 044d MCP65 AHCI Controller
+ 044e MCP65 AHCI Controller
+ 044f MCP65 AHCI Controller
+ 0450 MCP65 Ethernet
+ 0451 MCP65 Ethernet
+ 0452 MCP65 Ethernet
+ 0453 MCP65 Ethernet
+ 0454 MCP65 USB Controller
+ 0455 MCP65 USB Controller
+ 0456 MCP65 USB Controller
+ 0457 MCP65 USB Controller
+ 0458 MCP65 PCI Express bridge
+ 0459 MCP65 PCI Express bridge
+ 045a MCP65 PCI Express bridge
+ 045c MCP65 SATA Controller
+ 045d MCP65 SATA Controller
+ 045e MCP65 SATA Controller
+ 045f MCP65 SATA Controller
+10df Emulex Corporation
+ 1ae5 LP6000 Fibre Channel Host Adapter
+ f085 LP850 Fibre Channel Host Adapter
+ f095 LP952 Fibre Channel Host Adapter
+ f098 LP982 Fibre Channel Host Adapter
+ f0a1 Thor LightPulse Fibre Channel Host Adapter
+ f0a5 Thor LightPulse Fibre Channel Host Adapter
+ f0b5 Viper LightPulse Fibre Channel Host Adapter
+ f0d1 Helios LightPulse Fibre Channel Host Adapter
+ f0d5 Helios LightPulse Fibre Channel Host Adapter
+ f0e1 Zephyr LightPulse Fibre Channel Host Adapter
+ f0e5 Zephyr LightPulse Fibre Channel Host Adapter
+ f0f5 Neptune LightPulse Fibre Channel Host Adapter
+ f700 LP7000 Fibre Channel Host Adapter
+ f701 LP7000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
+ f800 LP8000 Fibre Channel Host Adapter
+ f801 LP8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
+ f900 LP9000 Fibre Channel Host Adapter
+ f901 LP9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
+ f980 LP9802 Fibre Channel Host Adapter
+ f981 LP9802 Fibre Channel Host Adapter Alternate ID
+ f982 LP9802 Fibre Channel Host Adapter Alternate ID
+ fa00 Thor-X LightPulse Fibre Channel Host Adapter
+ fb00 Viper LightPulse Fibre Channel Host Adapter
+ fc00 Thor-X LightPulse Fibre Channel Host Adapter
+ fc10 Helios-X LightPulse Fibre Channel Host Adapter
+ fc20 Zephyr-X LightPulse Fibre Channel Host Adapter
+ fd00 Helios-X LightPulse Fibre Channel Host Adapter
+ fe00 Zephyr-X LightPulse Fibre Channel Host Adapter
+ ff00 Neptune LightPulse Fibre Channel Host Adapter
+10e0 Integrated Micro Solutions Inc.
+ 5026 IMS5026/27/28
+ 5027 IMS5027
+ 5028 IMS5028
+ 8849 IMS8849
+ 8853 IMS8853
+ 9128 IMS9128 [Twin turbo 128]
+10e1 Tekram Technology Co.,Ltd.
+ 0391 TRM-S1040
+ 10e1 0391 DC-315U SCSI-3 Host Adapter
+ 690c DC-690c
+ dc29 DC-290
+10e2 Aptix Corporation
+10e3 Tundra Semiconductor Corp.
+ 0000 CA91C042 [Universe]
+ 0108 Tsi108 Host Bridge for Single PowerPC
+ 0148 Tsi148 [Tempe]
+ 0860 CA91C860 [QSpan]
+ 25d8 0110 HuSCI PMC reflective memory
+ 0862 CA91C862A [QSpan-II]
+ 25d8 0110 HuSCI PMC reflective memory
+ 8260 CA91L8200B [Dual PCI PowerSpan II]
+ 8261 CA91L8260B [Single PCI PowerSpan II]
+ a108 Tsi109 Host Bridge for Dual PowerPC
+10e4 Tandem Computers
+ 8029 Realtek 8029 Network Card
+10e5 Micro Industries Corporation
+10e6 Gainbery Computer Products Inc.
+10e7 Vadem
+10e8 Applied Micro Circuits Corp.
+ 1072 INES GPIB-PCI (AMCC5920 based)
+ 2011 Q-Motion Video Capture/Edit board
+ 4750 S5930 [Matchmaker]
+ 5920 S5920
+ 8043 LANai4.x [Myrinet LANai interface chip]
+ 8062 S5933_PARASTATION
+ 807d S5933 [Matchmaker]
+ 8088 Kongsberg Spacetec Format Synchronizer
+ 8089 Kongsberg Spacetec Serial Output Board
+ 809c S5933_HEPC3
+ 80d7 PCI-9112
+ 80d9 PCI-9118
+ 80da PCI-9812
+ 811a PCI-IEEE1355-DS-DE Interface
+ 814c Fastcom ESCC-PCI (Commtech, Inc.)
+ 8170 S5933 [Matchmaker] (Chipset Development Tool)
+# sold with Roper Scientifc(Photometrics) CoolSnap HQ camera
+ 81e6 Multimedia video controller
+ 8291 Fastcom 232/8-PCI (Commtech, Inc.)
+ 82c4 Fastcom 422/4-PCI (Commtech, Inc.)
+ 82c5 Fastcom 422/2-PCI (Commtech, Inc.)
+ 82c6 Fastcom IG422/1-PCI (Commtech, Inc.)
+ 82c7 Fastcom IG232/2-PCI (Commtech, Inc.)
+ 82ca Fastcom 232/4-PCI (Commtech, Inc.)
+ 82db AJA HDNTV HD SDI Framestore
+ 82e2 Fastcom DIO24H-PCI (Commtech, Inc.)
+ 8851 S5933 on Innes Corp FM Radio Capture card
+10e9 Alps Electric Co., Ltd.
+10ea Intergraphics Systems
+ 1680 IGA-1680
+ 1682 IGA-1682
+ 1683 IGA-1683
+ 2000 CyberPro 2000
+ 2010 CyberPro 2000A
+ 5000 CyberPro 5000
+ 5050 CyberPro 5050
+ 5202 CyberPro 5202
+# CyberPro5202 Audio Function
+ 5252 CyberPro5252
+10eb Artists Graphics
+ 0101 3GA
+ 8111 Twist3 Frame Grabber
+10ec Realtek Semiconductor Co., Ltd.
+ 0139 Zonet Zen3200
+ 1025 1605 TravelMate 5600 series
+ 8029 RTL-8029(AS)
+ 10b8 2011 EZ-Card (SMC1208)
+ 10ec 8029 RTL-8029(AS)
+ 1113 1208 EN1208
+ 1186 0300 DE-528
+ 1259 2400 AT-2400
+ 8129 RTL-8129
+ 10ec 8129 RT8129 Fast Ethernet Adapter
+ 8136 RTL8101E PCI Express Fast Ethernet controller
+ 8138 RT8139 (B/C) Cardbus Fast Ethernet Adapter
+ 10ec 8138 RT8139 (B/C) Fast Ethernet Adapter
+ 8139 RTL-8139/8139C/8139C+
+ 0357 000a TTP-Monitoring Card V2.0
+ 1025 005a TravelMate 290
+ 1025 8920 ALN-325
+ 1025 8921 ALN-325
+ 103c 006a NX9500
+ 1043 8109 P5P800-MX Mainboard
+ 1071 8160 MIM2000
+ 10bd 0320 EP-320X-R
+ 10ec 8139 RT8139
+ 1113 ec01 FNC-0107TX
+ 1186 1300 DFE-538TX
+ 1186 1320 SN5200
+ 1186 8139 DRN-32TX
+ 11f6 8139 FN22-3(A) LinxPRO Ethernet Adapter
+ 1259 2500 AT-2500TX
+ 1259 2503 AT-2500TX/ACPI
+ 1429 d010 ND010
+ 1432 9130 EN-9130TX
+ 1436 8139 RT8139
+ 1458 e000 GA-7VM400M/7VT600 Motherboard
+ 1462 788c 865PE Neo2-V Mainboard
+ 146c 1439 FE-1439TX
+ 1489 6001 GF100TXRII
+ 1489 6002 GF100TXRA
+ 149c 139a LFE-8139ATX
+ 149c 8139 LFE-8139TX
+ 14cb 0200 LNR-100 Family 10/100 Base-TX Ethernet
+ 1695 9001 Onboard RTL8101L 10/100 MBit
+ 1799 5000 F5D5000 PCI Card/Desktop Network PCI Card
+ 1904 8139 RTL8139D Fast Ethernet Adapter
+ 2646 0001 EtheRx
+ 8e2e 7000 KF-230TX
+ 8e2e 7100 KF-230TX/2
+ a0a0 0007 ALN-325C
+ 8167 RTL-8169SC Gigabit Ethernet
+ 8168 RTL8111/8168B PCI Express Gigabit Ethernet controller
+ 8169 RTL-8169 Gigabit Ethernet
+ 1025 0079 Aspire 5024WLMi
+ 1259 c107 CG-LAPCIGT
+ 1371 434e ProG-2000L
+ 1458 e000 GA-8I915ME-G Mainboard
+ 1462 702c K8T NEO 2 motherboard
+ 8180 RTL8180L 802.11b MAC
+ 8185 RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller
+ 8197 SmartLAN56 56K Modem
+10ed Ascii Corporation
+ 7310 V7310
+10ee Xilinx Corporation
+ 0205 Wildcard TE205P
+ 0210 Wildcard TE210P
+ 0314 Wildcard TE405P/TE410P (1st Gen)
+ 0405 Wildcard TE405P (2nd Gen)
+ 0410 Wildcard TE410P (2nd Gen)
+ 3fc0 RME Digi96
+ 3fc1 RME Digi96/8
+ 3fc2 RME Digi96/8 Pro
+ 3fc3 RME Digi96/8 Pad
+ 3fc4 RME Digi9652 (Hammerfall)
+ 3fc5 RME Hammerfall DSP
+ 3fc6 RME Hammerfall DSP MADI
+ 8381 Ellips Santos Frame Grabber
+ d154 Copley Controls CAN card (PCI-CAN-02)
+10ef Racore Computer Products, Inc.
+ 8154 M815x Token Ring Adapter
+10f0 Peritek Corporation
+10f1 Tyan Computer
+ 2865 Tyan Thunder K8E S2865
+10f2 Achme Computer, Inc.
+10f3 Alaris, Inc.
+10f4 S-MOS Systems, Inc.
+10f5 NKK Corporation
+ a001 NDR4000 [NR4600 Bridge]
+10f6 Creative Electronic Systems SA
+10f7 Matsushita Electric Industrial Co., Ltd.
+10f8 Altos India Ltd
+10f9 PC Direct
+10fa Truevision
+ 000c TARGA 1000
+10fb Thesys Gesellschaft fuer Mikroelektronik mbH
+ 186f TH 6255
+10fc I-O Data Device, Inc.
+# What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
+ 0003 Cardbus IDE Controller
+ 0005 Cardbus SCSI CBSC II
+10fd Soyo Computer, Inc
+10fe Fast Multimedia AG
+10ff NCube
+1100 Jazz Multimedia
+1101 Initio Corporation
+ 1060 INI-A100U2W
+ 1622 INI-1623 PCI SATA-II Controller
+ 9100 INI-9100/9100W
+ 9400 INI-940
+ 9401 INI-950
+ 9500 360P
+ 9502 Initio INI-9100UW Ultra Wide SCSI Controller INIC-950P chip
+1102 Creative Labs
+ 0002 SB Live! EMU10k1
+ 1102 0020 CT4850 SBLive! Value
+ 1102 0021 CT4620 SBLive!
+ 1102 002f SBLive! mainboard implementation
+ 1102 100a SB Live! 5.1 Digital OEM [SB0220]
+ 1102 4001 E-mu APS
+ 1102 8022 CT4780 SBLive! Value
+ 1102 8023 CT4790 SoundBlaster PCI512
+ 1102 8024 CT4760 SBLive!
+ 1102 8025 SBLive! Mainboard Implementation
+ 1102 8026 CT4830 SBLive! Value
+ 1102 8027 CT4832 SBLive! Value
+ 1102 8028 CT4760 SBLive! OEM version
+ 1102 8031 CT4831 SBLive! Value
+ 1102 8040 CT4760 SBLive!
+ 1102 8051 CT4850 SBLive! Value
+ 1102 8061 SBLive! Player 5.1
+ 1102 8064 SBLive! 5.1 Model SB0100
+ 1102 8065 SBLive! 5.1 Digital Model SB0220
+ 1102 8067 SBLive! 5.1 eMicro 28028
+ 0004 SB Audigy
+ 1102 0051 SB0090 Audigy Player
+ 1102 0053 SB0090 Audigy Player/OEM
+ 1102 0058 SB0090 Audigy Player/OEM
+ 1102 1007 SB0240 Audigy 2 Platinum 6.1
+ 1102 2002 SB Audigy 2 ZS (SB0350)
+ 0005 SB X-Fi
+ 1102 0021 X-Fi Platinum
+ 1102 1003 X-Fi XtremeMusic
+ 0006 [SB Live! Value] EMU10k1X
+ 0007 SB Audigy LS
+ 1102 0007 SBLive! 24bit
+ 1102 1001 SB0310 Audigy LS
+ 1102 1002 SB0312 Audigy LS
+ 1102 1006 SB0410 SBLive! 24-bit
+ 1462 1009 K8N Diamond
+ 0008 SB0400 Audigy2 Value
+ 1102 0008 EMU0404 Digital Audio System
+ 4001 SB Audigy FireWire Port
+ 1102 0010 SB Audigy FireWire Port
+ 7002 SB Live! Game Port
+ 1102 0020 Gameport Joystick
+ 7003 SB Audigy Game Port
+ 1102 0040 SB Audigy MIDI/Game Port
+ 7004 [SB Live! Value] Input device controller
+ 7005 SB Audigy LS Game Port
+ 1102 1001 SB0310 Audigy LS MIDI/Game port
+ 1102 1002 SB0312 Audigy LS MIDI/Game port
+ 8064 SB0100 [SBLive! 5.1 OEM]
+ 8938 Ectiva EV1938
+ 1033 80e5 SlimTower-Jim (NEC)
+ 1071 7150 Mitac 7150
+ 110a 5938 Siemens Scenic Mobile 510PIII
+ 13bd 100c Ceres-C (Sharp, Intel BX)
+ 13bd 100d Sharp, Intel Banister
+ 13bd 100e TwinHead P09S/P09S3 (Sharp)
+ 13bd f6f1 Marlin (Sharp)
+ 14ff 0e70 P88TE (TWINHEAD INTERNATIONAL Corp)
+ 14ff c401 Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
+ 156d b400 G400 - Geo (AlphaTop (Taiwan))
+ 156d b550 G560 (AlphaTop (Taiwan))
+ 156d b560 G560 (AlphaTop (Taiwan))
+ 156d b700 G700/U700 (AlphaTop (Taiwan))
+ 156d b795 G795 (AlphaTop (Taiwan))
+ 156d b797 G797 (AlphaTop (Taiwan))
+1103 Triones Technologies, Inc.
+ 0003 HPT343/345/346/363
+ 0004 HPT366/368/370/370A/372/372N
+ 1103 0001 HPT370A
+ 1103 0004 HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
+ 1103 0005 HPT370 UDMA100
+ 0005 HPT372A/372N
+ 0006 HPT302/302N
+ 0007 HPT371/371N
+ 0008 HPT374
+ 0009 HPT372N
+1104 RasterOps Corp.
+1105 Sigma Designs, Inc.
+ 1105 REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
+ 8300 REALmagic Hollywood Plus DVD Decoder
+ 8400 EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
+ 8401 EM8401 REALmagic DVD/MPEG-2 A/V Decoder
+ 8470 EM8470 REALmagic DVD/MPEG-4 A/V Decoder
+ 8471 EM8471 REALmagic DVD/MPEG-4 A/V Decoder
+ 8475 EM8475 REALmagic DVD/MPEG-4 A/V Decoder
+ 1105 0001 REALmagic X-Card
+ 8476 EM8476 REALmagic DVD/MPEG-4 A/V Decoder
+ 127d 0000 CineView II
+ 8485 EM8485 REALmagic DVD/MPEG-4 A/V Decoder
+ 8486 EM8486 REALmagic DVD/MPEG-4 A/V Decoder
+1106 VIA Technologies, Inc.
+ 0102 Embedded VIA Ethernet Controller
+ 0130 VT6305 1394.A Controller
+# Wrong ID found on Jetway K8M8MS
+ 0204 K8M800 Host Bridge
+ 0208 PT890 Host Bridge
+ 0238 K8T890 Host Bridge
+ 0258 PT880 Host Bridge
+ 0259 CN400/PM880 Host Bridge
+ 0269 KT880 Host Bridge
+ 0282 K8T800Pro Host Bridge
+ 1043 80a3 A8V Deluxe
+ 0290 K8M890 Host Bridge
+ 0293 PM896 Host Bridge
+ 0296 P4M800 Host Bridge
+ 0305 VT8363/8365 [KT133/KM133]
+ 1019 0987 K7VZA Mainboard
+ 1043 8033 A7V Mainboard
+ 1043 803e A7V-E Mainboard
+ 1043 8042 A7V133/A7V133-C Mainboard
+ 147b a401 KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
+ 0308 PT894 Host Bridge
+ 0314 CN700/VN800/P4M800CE/Pro Host Bridge
+ 0324 CX700 Host Bridge
+ 0327 P4M890 Host Bridge
+ 0336 K8M890CE Host Bridge
+ 0340 PT900 Host Bridge
+ 0351 VT3351 Host Bridge
+ 0364 P4M900 Host Bridge
+ 0391 VT8371 [KX133]
+ 0501 VT8501 [Apollo MVP4]
+ 0505 VT82C505
+# Shares chip with :0576. The VT82C576M has :1571 instead of :0561.
+ 0561 VT82C576MV
+ 0571 VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
+ 1019 0985 P6VXA Motherboard
+ 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
+ 1043 8052 VT8233A Bus Master ATA100/66/33 IDE
+ 1043 808c A7V8X / A7V333 motherboard
+ 1043 80a1 A7V8X-X motherboard rev. 1.01
+ 1043 80ed A7V600/K8V-X/A8V Deluxe motherboard
+ 1106 0571 VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
+ 1179 0001 Magnia Z310
+ 1297 f641 FX41 motherboard
+ 1458 5002 GA-7VAX Mainboard
+ 1462 7020 K8T NEO 2 motherboard
+ 147b 1407 KV8-MAX3 motherboard
+ 1849 0571 K7VT2/K7VT6 motherboard
+ 0576 VT82C576 3V [Apollo Master]
+ 0585 VT82C585VP [Apollo VP1/VPX]
+ 0586 VT82C586/A/B PCI-to-ISA [Apollo VP]
+ 1106 0000 MVP3 ISA Bridge
+ 0591 VT8237A SATA 2-Port Controller
+ 0595 VT82C595 [Apollo VP2]
+ 0596 VT82C596 ISA [Mobile South]
+ 1106 0000 VT82C596/A/B PCI to ISA Bridge
+ 1458 0596 VT82C596/A/B PCI to ISA Bridge
+ 0597 VT82C597 [Apollo VP3]
+ 0598 VT82C598 [Apollo MVP3]
+ 0601 VT8601 [Apollo ProMedia]
+ 0605 VT8605 [ProSavage PM133]
+ 1043 802c CUV4X mainboard
+ 0680 VT82C680 [Apollo P6]
+ 0686 VT82C686 [Apollo Super South]
+ 1019 0985 P6VXA Motherboard
+ 1043 802c CUV4X mainboard
+ 1043 8033 A7V Mainboard
+ 1043 803e A7V-E Mainboard
+ 1043 8040 A7M266 Mainboard
+ 1043 8042 A7V133/A7V133-C Mainboard
+ 1106 0000 VT82C686/A PCI to ISA Bridge
+ 1106 0686 VT82C686/A PCI to ISA Bridge
+ 1179 0001 Magnia Z310
+ 147b a702 KG7-Lite Mainboard
+ 0691 VT82C693A/694x [Apollo PRO133x]
+ 1019 0985 P6VXA Motherboard
+ 1179 0001 Magnia Z310
+ 1458 0691 VT82C691 Apollo Pro System Controller
+ 0693 VT82C693 [Apollo Pro Plus]
+ 0698 VT82C693A [Apollo Pro133 AGP]
+ 0926 VT82C926 [Amazon]
+ 1000 VT82C570MV
+ 1106 VT82C570MV
+ 1204 K8M800 Host Bridge
+ 1208 PT890 Host Bridge
+ 1238 K8T890 Host Bridge
+ 1258 PT880 Host Bridge
+ 1259 CN400/PM880 Host Bridge
+ 1269 KT880 Host Bridge
+ 1282 K8T800Pro Host Bridge
+ 1290 K8M890 Host Bridge
+ 1293 PM896 Host Bridge
+ 1296 P4M800 Host Bridge
+ 1308 PT894 Host Bridge
+ 1314 CN700/VN800/P4M800CE/Pro Host Bridge
+ 1324 CX700 Host Bridge
+ 1327 P4M890 Host Bridge
+ 1336 K8M890CE Host Bridge
+ 1340 PT900 Host Bridge
+ 1351 VT3351 Host Bridge
+ 1364 P4M900 Host Bridge
+ 1571 VT82C576M/VT82C586
+ 1595 VT82C595/97 [Apollo VP2/97]
+ 2204 K8M800 Host Bridge
+ 2208 PT890 Host Bridge
+ 2238 K8T890 Host Bridge
+ 2258 PT880 Host Bridge
+ 2259 CN400/PM880 Host Bridge
+ 2269 KT880 Host Bridge
+ 2282 K8T800Pro Host Bridge
+ 2290 K8M890 Host Bridge
+ 2293 PM896 Host Bridge
+ 2296 P4M800 Host Bridge
+ 2308 PT894 Host Bridge
+ 2314 CN700/VN800/P4M800CE/Pro Host Bridge
+ 2324 CX700 Host Bridge
+ 2327 P4M890 Host Bridge
+ 2336 K8M890CE Host Bridge
+ 2340 PT900 Host Bridge
+ 2351 VT3351 Host Bridge
+ 2364 P4M900 Host Bridge
+ 287a VT8251 PCI to PCI Bridge
+ 287b VT8251 Host Bridge
+ 287c VT8251 PCIE Root Port
+ 287d VT8251 PCIE Root Port
+ 287e VT8251 Ultra VLINK Controller
+ 3022 CLE266
+ 3038 VT82xxxxx UHCI USB 1.1 Controller
+ 0925 1234 USB Controller
+ 1019 0985 P6VXA Motherboard
+ 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
+ 1043 8080 A7V333 motherboard
+ 1043 808c VT6202 USB2.0 4 port controller
+ 1043 80a1 A7V8X-X motherboard
+ 1043 80ed A7V600/K8V-X/A8V Deluxe motherboard
+ 1179 0001 Magnia Z310
+ 1458 5004 GA-7VAX Mainboard
+ 1462 7020 K8T NEO 2 motherboard
+ 147b 1407 KV8-MAX3 motherboard
+ 182d 201d CN-029 USB2.0 4 port PCI Card
+ 1849 3038 K7VT6
+ 3040 VT82C586B ACPI
+ 3043 VT86C100A [Rhine]
+ 10bd 0000 VT86C100A Fast Ethernet Adapter
+ 1106 0100 VT86C100A Fast Ethernet Adapter
+ 1186 1400 DFE-530TX rev A
+ 3044 IEEE 1394 Host Controller
+ 1025 005a TravelMate 290
+ 1043 808a A8V Deluxe
+ 1458 1000 GA-7VT600-1394 Motherboard
+ 1462 207d K8NGM2 series motherboard
+ 1462 702d K8T NEO 2 motherboard
+ 1462 971d MS-6917
+ 3050 VT82C596 Power Management
+ 3051 VT82C596 Power Management
+ 3053 VT6105M [Rhine-III]
+ 3057 VT82C686 [Apollo Super ACPI]
+ 1019 0985 P6VXA Motherboard
+ 1019 0987 K7VZA Motherboard
+ 1043 8033 A7V Mainboard
+ 1043 803e A7V-E Mainboard
+ 1043 8040 A7M266 Mainboard
+ 1043 8042 A7V133/A7V133-C Mainboard
+ 1179 0001 Magnia Z310
+ 3058 VT82C686 AC97 Audio Controller
+ 0e11 0097 SoundMax Digital Integrated Audio
+ 0e11 b194 Soundmax integrated digital audio
+ 1019 0985 P6VXA Motherboard
+ 1019 0987 K7VZA Motherboard
+ 1043 1106 A7V133/A7V133-C Mainboard
+ 1106 4511 Onboard Audio on EP7KXA
+ 1458 7600 Onboard Audio
+ 1462 3091 MS-6309 Onboard Audio
+ 1462 3300 MS-6330 Onboard Audio
+ 15dd 7609 Onboard Audio
+ 3059 VT8233/A/8235/8237 AC97 Audio Controller
+ 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
+ 1043 8095 A7V8X Motherboard (Realtek ALC650 codec)
+ 1043 80a1 A7V8X-X Motherboard
+ 1043 80b0 A7V600/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
+ 1043 812a A8V Deluxe motherboard (Realtek ALC850 codec)
+ 1106 3059 L7VMM2 Motherboard
+ 1106 4161 K7VT2 motherboard
+ 1106 4170 PCPartner P4M800-8237R Motherboard
+ 1106 4552 Soyo KT-600 Dragon Plus (Realtek ALC 650)
+ 1297 c160 FX41 motherboard (Realtek ALC650 codec)
+ 1458 a002 GA-7VAX Onboard Audio (Realtek ALC650)
+ 1462 0080 K8T NEO 2 motherboard
+ 1462 3800 KT266 onboard audio
+ 147b 1407 KV8-MAX3 motherboard
+ 1849 9761 K7VT6 motherboard
+ 4005 4710 MSI K7T266 Pro2-RU (MSI-6380 v2) onboard audio (Realtek/ALC 200/200P)
+ a0a0 01b6 AK77-8XN onboard audio
+ 3065 VT6102 [Rhine-II]
+ 1043 80a1 A7V8X-X Motherboard
+ 1106 0102 VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
+ 1186 1400 DFE-530TX rev A
+ 1186 1401 DFE-530TX rev B
+ 13b9 1421 LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
+ 147b 1c09 NV7 Motherboard
+ 1695 3005 VT6103
+ 1695 300c Realtek ALC655 sound chip
+ 1849 3065 K7VT6 motherboard
+# This hosts more than just the Intel 537 codec, it also hosts PCtel (SIL33) and SmartLink (SIL34) codecs
+ 3068 AC'97 Modem Controller
+ 1462 309e MS-6309 Saturn Motherboard
+ 3074 VT8233 PCI to ISA Bridge
+ 1043 8052 VT8233A
+ 3091 VT8633 [Apollo Pro266]
+ 3099 VT8366/A/7 [Apollo KT266/A/333]
+ 1043 8064 A7V266-E Mainboard
+ 1043 807f A7V333 Mainboard
+ 1849 3099 K7VT2 motherboard
+ 3101 VT8653 Host Bridge
+ 3102 VT8662 Host Bridge
+ 3103 VT8615 Host Bridge
+ 3104 USB 2.0
+ 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
+ 1043 808c A7V8X motherboard
+ 1043 80a1 A7V8X-X motherboard rev 1.01
+ 1043 80ed A7V600/K8V-X/A8V Deluxe motherboard
+ 1297 f641 FX41 motherboard
+ 1458 5004 GA-7VAX Mainboard
+ 1462 7020 K8T NEO 2 motherboard
+ 147b 1407 KV8-MAX3 motherboard
+ 182d 201d CN-029 USB 2.0 4 port PCI Card
+ 1849 3104 K7VT6 motherboard
+ 3106 VT6105 [Rhine-III]
+ 1186 1403 DFE-530TX rev C
+ 3108 S3 Unichrome Pro VGA Adapter
+ 3109 VT8233C PCI to ISA Bridge
+ 3112 VT8361 [KLE133] Host Bridge
+ 3113 VPX/VPX2 PCI to PCI Bridge Controller
+ 3116 VT8375 [KM266/KL266] Host Bridge
+ 1297 f641 FX41 motherboard
+ 3118 S3 Unichrome Pro VGA Adapter
+ 3119 VT6120/VT6121/VT6122 Gigabit Ethernet Adapter
+ 3122 VT8623 [Apollo CLE266] integrated CastleRock graphics
+ 3123 VT8623 [Apollo CLE266]
+ 3128 VT8753 [P4X266 AGP]
+ 3133 VT3133 Host Bridge
+ 3147 VT8233A ISA Bridge
+ 1043 808c A7V333 motherboard
+ 3148 P4M266 Host Bridge
+ 3149 VIA VT6420 SATA RAID Controller
+ 1043 80ed A7V600/K8V Deluxe/K8V-X/A8V Deluxe motherboard
+ 1458 b003 GA-7VM400AM(F) Motherboard
+ 1462 7020 K8T Neo 2 Motherboard
+ 147b 1407 KV8-MAX3 motherboard
+ 147b 1408 KV7
+ 1849 3149 K7VT6 motherboard
+ 3156 P/KN266 Host Bridge
+ 3164 VT6410 ATA133 RAID controller
+ 1043 80f4 P4P800 Mainboard Deluxe ATX
+ 1462 7028 915P/G Neo2
+ 3168 VT8374 P4X400 Host Controller/AGP Bridge
+ 3177 VT8235 ISA Bridge
+ 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
+ 1043 808c A7V8X motherboard
+ 1043 80a1 A7V8X-X motherboard
+ 1297 f641 FX41 motherboard
+ 1458 5001 GA-7VAX Mainboard
+ 1849 3177 K7VT2 motherboard
+ 3178 ProSavageDDR P4N333 Host Bridge
+ 3188 VT8385 [K8T800 AGP] Host Bridge
+ 1043 80a3 K8V Deluxe/K8V-X motherboard
+ 147b 1407 KV8-MAX3 motherboard
+ 3189 VT8377 [KT400/KT600 AGP] Host Bridge
+ 1043 807f A7V8X motherboard
+ 1458 5000 GA-7VAX Mainboard
+ 1849 3189 K7VT6 motherboard
+ 3204 K8M800 Host Bridge
+ 3205 VT8378 [KM400/A] Chipset Host Bridge
+ 1458 5000 GA-7VM400M Motherboard
+ 3208 PT890 Host Bridge
+ 3213 VPX/VPX2 PCI to PCI Bridge Controller
+ 3218 K8T800M Host Bridge
+ 3227 VT8237 ISA bridge [KT600/K8T800/K8T890 South]
+ 1043 80ed A7V600/K8V-X/A8V Deluxe motherboard
+ 1106 3227 DFI KT600-AL Motherboard
+ 1458 5001 GA-7VT600 Motherboard
+ 147b 1407 KV8-MAX3 motherboard
+ 1849 3227 K7VT4 motherboard
+ 3238 K8T890 Host Bridge
+ 3249 VT6421 IDE RAID Controller
+ 324a CX700 PCI to PCI Bridge
+ 324b CX700 Host Bridge
+ 324e CX700 Internal Module Bus
+ 3258 PT880 Host Bridge
+ 3259 CN400/PM880 Host Bridge
+ 3269 KT880 Host Bridge
+ 3282 K8T800Pro Host Bridge
+ 3287 VT8251 PCI to ISA Bridge
+ 3288 VIA High Definition Audio Controller
+ 3290 K8M890 Host Bridge
+ 3296 P4M800 Host Bridge
+ 3324 CX700 Host Bridge
+ 3327 P4M890 Host Bridge
+ 3336 K8M890CE Host Bridge
+ 3337 VT8237A PCI to ISA Bridge
+ 3340 PT900 Host Bridge
+ 3344 UniChrome Pro IGP
+ 3349 VT8251 AHCI/SATA 4-Port Controller
+ 3351 VT3351 Host Bridge
+ 3364 P4M900 Host Bridge
+ 337a VT8237A PCI to PCI Bridge
+ 337b VT8237A Host Bridge
+ 4149 VIA VT6420 (ATA133) Controller
+ 4204 K8M800 Host Bridge
+ 4208 PT890 Host Bridge
+ 4238 K8T890 Host Bridge
+ 4258 PT880 Host Bridge
+ 4259 CN400/PM880 Host Bridge
+ 4269 KT880 Host Bridge
+ 4282 K8T800Pro Host Bridge
+ 4290 K8M890 Host Bridge
+ 4293 PM896 Host Bridge
+ 4296 P4M800 Host Bridge
+ 4308 PT894 Host Bridge
+ 4314 CN700/VN800/P4M800CE/Pro Host Bridge
+ 4324 CX700 Host Bridge
+ 4327 P4M890 Host Bridge
+ 4336 K8M890CE Host Bridge
+ 4340 PT900 Host Bridge
+ 4351 VT3351 Host Bridge
+ 4364 P4M900 Host Bridge
+ 5030 VT82C596 ACPI [Apollo PRO]
+ 5208 PT890 I/O APIC Interrupt Controller
+ 5238 K8T890 I/O APIC Interrupt Controller
+ 5290 K8M890 I/O APIC Interrupt Controller
+ 5308 PT894 I/O APIC Interrupt Controller
+ 5327 P4M890 I/O APIC Interrupt Controller
+ 5336 K8M890CE I/O APIC Interrupt Controller
+ 5340 PT900 I/O APIC Interrupt Controller
+ 5351 VT3351 I/O APIC Interrupt Controller
+ 5364 P4M900 I/O APIC Interrupt Controller
+ 6100 VT85C100A [Rhine II]
+ 6327 P4M890 Security Device
+ 7204 K8M800 Host Bridge
+ 7205 VT8378 [S3 UniChrome] Integrated Video
+ 1458 d000 Gigabyte GA-7VM400(A)M(F) Motherboard
+ 7208 PT890 Host Bridge
+ 7238 K8T890 Host Bridge
+ 7258 PT880 Host Bridge
+ 7259 CN400/PM880 Host Bridge
+ 7269 KT880 Host Bridge
+ 7282 K8T800Pro Host Bridge
+ 7290 K8M890 Host Bridge
+ 7293 PM896 Host Bridge
+ 7296 P4M800 Host Bridge
+ 7308 PT894 Host Bridge
+ 7314 CN700/VN800/P4M800CE/Pro Host Bridge
+ 7324 CX700 Host Bridge
+ 7327 P4M890 Host Bridge
+ 7336 K8M890CE Host Bridge
+ 7340 PT900 Host Bridge
+ 7351 VT3351 Host Bridge
+ 7364 P4M900 Host Bridge
+ 8231 VT8231 [PCI-to-ISA Bridge]
+ 8235 VT8235 ACPI
+ 8305 VT8363/8365 [KT133/KM133 AGP]
+ 8324 CX700 PCI to ISA Bridge
+ 8391 VT8371 [KX133 AGP]
+ 8501 VT8501 [Apollo MVP4 AGP]
+ 8596 VT82C596 [Apollo PRO AGP]
+ 8597 VT82C597 [Apollo VP3 AGP]
+ 8598 VT82C598/694x [Apollo MVP3/Pro133x AGP]
+ 1019 0985 P6VXA Motherboard
+ 8601 VT8601 [Apollo ProMedia AGP]
+ 8605 VT8605 [PM133 AGP]
+ 8691 VT82C691 [Apollo Pro]
+ 8693 VT82C693 [Apollo Pro Plus] PCI Bridge
+ a208 PT890 PCI to PCI Bridge Controller
+ a238 K8T890 PCI to PCI Bridge Controller
+ a327 P4M890 PCI to PCI Bridge Controller
+ a364 P4M900 PCI to PCI Bridge Controller
+ b091 VT8633 [Apollo Pro266 AGP]
+ b099 VT8366/A/7 [Apollo KT266/A/333 AGP]
+ b101 VT8653 AGP Bridge
+ b102 VT8362 AGP Bridge
+ b103 VT8615 AGP Bridge
+ b112 VT8361 [KLE133] AGP Bridge
+ b113 VPX/VPX2 I/O APIC Interrupt Controller
+ b115 VT8363/8365 [KT133/KM133] PCI Bridge
+ b168 VT8235 PCI Bridge
+ b188 VT8237 PCI bridge [K8T800/K8T890 South]
+ 147b 1407 KV8-MAX3 motherboard
+ b198 VT8237 PCI Bridge
+ b213 VPX/VPX2 I/O APIC Interrupt Controller
+ b999 [K8T890 North / VT8237 South] PCI Bridge
+ c208 PT890 PCI to PCI Bridge Controller
+ c238 K8T890 PCI to PCI Bridge Controller
+ c327 P4M890 PCI to PCI Bridge Controller
+ c340 PT900 PCI to PCI Bridge Controller
+ c364 P4M900 PCI to PCI Bridge Controller
+ d104 VT8237 Integrated Fast Ethernet Controller
+ d208 PT890 PCI to PCI Bridge Controller
+ d213 VPX/VPX2 PCI to PCI Bridge Controller
+ d238 K8T890 PCI to PCI Bridge Controller
+ d340 PT900 PCI to PCI Bridge Controller
+ e208 PT890 PCI to PCI Bridge Controller
+ e238 K8T890 PCI to PCI Bridge Controller
+ e340 PT900 PCI to PCI Bridge Controller
+ f208 PT890 PCI to PCI Bridge Controller
+ f238 K8T890 PCI to PCI Bridge Controller
+ f340 PT900 PCI to PCI Bridge Controller
+1107 Stratus Computers
+ 0576 VIA VT82C570MV [Apollo] (Wrong vendor ID!)
+1108 Proteon, Inc.
+ 0100 p1690plus_AA
+ 0101 p1690plus_AB
+ 0105 P1690Plus
+ 0108 P1690Plus
+ 0138 P1690Plus
+ 0139 P1690Plus
+ 013c P1690Plus
+ 013d P1690Plus
+1109 Cogent Data Technologies, Inc.
+ 1400 EM110TX [EX110TX]
+110a Siemens Nixdorf AG
+ 0002 Pirahna 2-port
+ 0005 Tulip controller, power management, switch extender
+ 0006 FSC PINC (I/O-APIC)
+ 0015 FSC Multiprocessor Interrupt Controller
+ 001d FSC Copernicus Management Controller
+ 007b FSC Remote Service Controller, mailbox device
+ 007c FSC Remote Service Controller, shared memory device
+ 007d FSC Remote Service Controller, SMIC device
+ 2101 HST SAPHIR V Primary PCI (ISDN/PMx)
+# Superfastcom-PCI (Commtech, Inc.) or DSCC4 WAN Adapter
+ 2102 DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels
+ 2104 Eicon Diva 2.02 compatible passive ISDN card
+ 3142 SIMATIC NET CP 5613A1 (Profibus Adapter)
+ 4021 SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
+ 4029 SIMATIC NET CP 5613A2 (Profibus Adapter)
+ 4942 FPGA I-Bus Tracer for MBD
+ 6120 SZB6120
+110b Chromatic Research Inc.
+ 0001 Mpact Media Processor
+ 0004 Mpact 2
+110c Mini-Max Technology, Inc.
+110d Znyx Advanced Systems
+110e CPU Technology
+110f Ross Technology
+1110 Powerhouse Systems
+ 6037 Firepower Powerized SMP I/O ASIC
+ 6073 Firepower Powerized SMP I/O ASIC
+1111 Santa Cruz Operation
+# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom
+1112 Osicom Technologies Inc
+ 2200 FDDI Adapter
+ 2300 Fast Ethernet Adapter
+ 2340 4 Port Fast Ethernet Adapter
+ 2400 ATM Adapter
+1113 Accton Technology Corporation
+ 1211 SMC2-1211TX
+ 103c 1207 EN-1207D Fast Ethernet Adapter
+ 1113 1211 EN-1207D Fast Ethernet Adapter
+ 1216 EN-1216 Ethernet Adapter
+ 1113 2242 EN2242 10/100 Ethernet Mini-PCI Card
+ 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
+ 1217 EN-1217 Ethernet Adapter
+ 5105 10Mbps Network card
+ 9211 EN-1207D Fast Ethernet Adapter
+ 1113 9211 EN-1207D Fast Ethernet Adapter
+ 9511 21x4x DEC-Tulip compatible Fast Ethernet
+ d301 CPWNA100 (Philips wireless PCMCIA)
+ ec02 SMC 1244TX v3
+1114 Atmel Corporation
+ 0506 at76c506 802.11b Wireless Network Adaptor
+1115 3D Labs
+1116 Data Translation
+ 0022 DT3001
+ 0023 DT3002
+ 0024 DT3003
+ 0025 DT3004
+ 0026 DT3005
+ 0027 DT3001-PGL
+ 0028 DT3003-PGL
+1117 Datacube, Inc
+ 9500 Max-1C SVGA card
+ 9501 Max-1C image processing
+1118 Berg Electronics
+1119 ICP Vortex Computersysteme GmbH
+ 0000 GDT 6000/6020/6050
+ 0001 GDT 6000B/6010
+ 0002 GDT 6110/6510
+ 0003 GDT 6120/6520
+ 0004 GDT 6530
+ 0005 GDT 6550
+ 0006 GDT 6117/6517
+ 0007 GDT 6127/6527
+ 0008 GDT 6537
+ 0009 GDT 6557/6557-ECC
+ 000a GDT 6115/6515
+ 000b GDT 6125/6525
+ 000c GDT 6535
+ 000d GDT 6555
+ 0010 GDT 6115/6515
+ 0011 GDT 6125/6525
+ 0012 GDT 6535
+ 0013 GDT 6555/6555-ECC
+ 0100 GDT 6117RP/6517RP
+ 0101 GDT 6127RP/6527RP
+ 0102 GDT 6537RP
+ 0103 GDT 6557RP
+ 0104 GDT 6111RP/6511RP
+ 0105 GDT 6121RP/6521RP
+ 0110 GDT 6117RD/6517RD
+ 0111 GDT 6127RD/6527RD
+ 0112 GDT 6537RD
+ 0113 GDT 6557RD
+ 0114 GDT 6111RD/6511RD
+ 0115 GDT 6121RD/6521RD
+ 0118 GDT 6118RD/6518RD/6618RD
+ 0119 GDT 6128RD/6528RD/6628RD
+ 011a GDT 6538RD/6638RD
+ 011b GDT 6558RD/6658RD
+ 0120 GDT 6117RP2/6517RP2
+ 0121 GDT 6127RP2/6527RP2
+ 0122 GDT 6537RP2
+ 0123 GDT 6557RP2
+ 0124 GDT 6111RP2/6511RP2
+ 0125 GDT 6121RP2/6521RP2
+ 0136 GDT 6113RS/6513RS
+ 0137 GDT 6123RS/6523RS
+ 0138 GDT 6118RS/6518RS/6618RS
+ 0139 GDT 6128RS/6528RS/6628RS
+ 013a GDT 6538RS/6638RS
+ 013b GDT 6558RS/6658RS
+ 013c GDT 6533RS/6633RS
+ 013d GDT 6543RS/6643RS
+ 013e GDT 6553RS/6653RS
+ 013f GDT 6563RS/6663RS
+ 0166 GDT 7113RN/7513RN/7613RN
+ 0167 GDT 7123RN/7523RN/7623RN
+ 0168 GDT 7118RN/7518RN/7518RN
+ 0169 GDT 7128RN/7528RN/7628RN
+ 016a GDT 7538RN/7638RN
+ 016b GDT 7558RN/7658RN
+ 016c GDT 7533RN/7633RN
+ 016d GDT 7543RN/7643RN
+ 016e GDT 7553RN/7653RN
+ 016f GDT 7563RN/7663RN
+ 01d6 GDT 4x13RZ
+ 01d7 GDT 4x23RZ
+ 01f6 GDT 8x13RZ
+ 01f7 GDT 8x23RZ
+ 01fc GDT 8x33RZ
+ 01fd GDT 8x43RZ
+ 01fe GDT 8x53RZ
+ 01ff GDT 8x63RZ
+ 0210 GDT 6519RD/6619RD
+ 0211 GDT 6529RD/6629RD
+ 0260 GDT 7519RN/7619RN
+ 0261 GDT 7529RN/7629RN
+ 02ff GDT MAXRP
+ 0300 GDT NEWRX
+111a Efficient Networks, Inc
+ 0000 155P-MF1 (FPGA)
+ 0002 155P-MF1 (ASIC)
+ 0003 ENI-25P ATM
+ 111a 0000 ENI-25p Miniport ATM Adapter
+ 0005 SpeedStream (LANAI)
+ 111a 0001 ENI-3010 ATM
+ 111a 0009 ENI-3060 ADSL (VPI=0)
+ 111a 0101 ENI-3010 ATM
+ 111a 0109 ENI-3060CO ADSL (VPI=0)
+ 111a 0809 ENI-3060 ADSL (VPI=0 or 8)
+ 111a 0909 ENI-3060CO ADSL (VPI=0 or 8)
+ 111a 0a09 ENI-3060 ADSL (VPI=<0..15>)
+ 0007 SpeedStream ADSL
+ 111a 1001 ENI-3061 ADSL [ASIC]
+ 1203 SpeedStream 1023 Wireless PCI Adapter
+111b Teledyne Electronic Systems
+111c Tricord Systems Inc.
+ 0001 Powerbis Bridge
+111d Integrated Device Technology, Inc.
+ 0001 IDT77201/77211 155Mbps ATM SAR Controller [NICStAR]
+ 0003 IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller
+ 0004 IDT77V252 155Mbps ATM MICRO ABR SAR Controller
+ 0005 IDT77V222 155Mbps ATM MICRO ABR SAR Controller
+111e Eldec
+111f Precision Digital Images
+ 4a47 Precision MX Video engine interface
+ 5243 Frame capture bus interface
+1120 EMC Corporation
+1121 Zilog
+1122 Multi-tech Systems, Inc.
+1123 Excellent Design, Inc.
+1124 Leutron Vision AG
+ 2581 Picport Monochrome
+1125 Eurocore
+1126 Vigra
+1127 FORE Systems Inc
+ 0200 ForeRunner PCA-200 ATM
+ 0210 PCA-200PC
+ 0250 ATM
+ 0300 ForeRunner PCA-200EPC ATM
+ 0310 ATM
+ 0400 ForeRunnerHE ATM Adapter
+ 1127 0400 ForeRunnerHE ATM
+1129 Firmworks
+112a Hermes Electronics Company, Ltd.
+112b Linotype - Hell AG
+112c Zenith Data Systems
+112d Ravicad
+112e Infomedia Microelectronics Inc.
+112f Imaging Technology Inc
+ 0000 MVC IC-PCI
+ 0001 MVC IM-PCI Video frame grabber/processor
+ 0008 PC-CamLink PCI framegrabber
+1130 Computervision
+1131 Philips Semiconductors
+ 1561 USB 1.1 Host Controller
+ 1562 USB 2.0 Host Controller
+ 3400 SmartPCI56(UCB1500) 56K Modem
+ 5400 TriMedia TM1000/1100
+ 5402 TriMedia TM-1300
+ 1244 0f00 Fritz!Card DSL
+ 5405 TriMedia TM1500
+ 5406 TriMedia TM1700
+ 7130 SAA7130 Video Broadcast Decoder
+ 102b 48d0 Matrox CronosPlus
+ 1048 226b ELSA EX-VISION 300TV
+ 1131 2001 10MOONS PCI TV CAPTURE CARD
+ 1131 2005 Techcom (India) TV Tuner Card (SSD-TV-670)
+ 1461 050c Nagase Sangyo TransGear 3000TV
+ 1461 10ff AVerMedia DVD EZMaker
+ 1461 2108 AverMedia AverTV/305
+ 1461 2115 AverMedia AverTV Studio 305
+ 153b 1152 Terratec Cinergy 200 TV
+ 185b c100 Compro VideoMate TV PVR/FM
+ 185b c901 Videomate DVB-T200
+ 5168 0138 LifeView FlyVIDEO2000
+ 7133 SAA7133/SAA7135 Video Broadcast Decoder
+ 0000 4091 Beholder BeholdTV 409 FM
+ 1019 4cb5 Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)
+ 1043 0210 FlyTV mini Asus Digimatrix
+ 1043 4843 ASUS TV-FM 7133
+ 1043 4845 TV-FM 7135
+ 1043 4862 P7131 Dual
+ 1131 2001 Proteus Pro [philips reference design]
+ 1131 2018 Tiger reference design
+ 1131 4ee9 MonsterTV Mobile
+ 11bd 002b PCTV Stereo
+ 11bd 002e PCTV 110i (saa7133)
+ 12ab 0800 PURPLE TV
+ 1421 0335 Instant TV DVB-T Cardbus
+ 1421 1370 Instant TV (saa7135)
+ 1435 7330 VFG7330
+ 1435 7350 VFG7350
+ 1461 1044 AVerTVHD MCE A180
+ 1461 f31f Avermedia AVerTV GO 007 FM
+ 1462 6231 TV@Anywhere plus
+ 1489 0214 LifeView FlyTV Platinum FM
+ 14c0 1212 LifeView FlyTV Platinum Mini2
+ 153b 1160 Cinergy 250 PCI TV
+ 153b 1162 Terratec Cinergy 400 mobile
+ 185b c100 VideoMate TV
+ 5168 0306 LifeView FlyDVB-T DUO
+ 5168 0319 LifeView FlyDVB Trio
+ 7134 SAA7134/SAA7135HL Video Broadcast Decoder
+ 1019 4cb4 Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)
+ 1043 0210 Digimatrix TV
+ 1043 4840 ASUS TV-FM 7134
+ 1131 2004 EUROPA V3 reference design
+ 1131 4e85 SKNet Monster TV
+ 1131 6752 EMPRESS
+ 11bd 002b PCTV Stereo
+ 11bd 002d PCTV 300i DVB-T + PAL
+ 1461 2c00 AverTV Hybrid+FM PCI
+ 1461 9715 AVerTV Studio 307
+ 1461 a70a Avermedia AVerTV 307
+ 1461 a70b AverMedia M156 / Medion 2819
+ 1461 d6ee Cardbus TV/Radio (E500)
+ 1471 b7e9 AVerTV Cardbus plus
+ 153b 1142 Terratec Cinergy 400 TV
+ 153b 1143 Terratec Cinergy 600 TV
+ 153b 1158 Terratec Cinergy 600 TV MK3
+ 1540 9524 ProVideo PV952
+ 16be 0003 Medion 7134
+ 185b c200 Compro VideoMate Gold+ Pal
+ 185b c900 Videomate DVB-T300
+ 1894 a006 KNC One TV-Station DVR
+ 1894 fe01 KNC One TV-Station RDS / Typhoon TV Tuner RDS
+ 7145 SAA7145
+ 7146 SAA7146
+ 110a 0000 Fujitsu/Siemens DVB-C card rev1.5
+ 110a ffff Fujitsu/Siemens DVB-C card rev1.5
+ 1131 4f56 KNC1 DVB-S Budget
+ 1131 4f60 Fujitsu-Siemens Activy DVB-S Budget Rev AL
+ 1131 4f61 Activy DVB-S Budget Rev GR
+# It has an LSI companion chip.
+ 1131 5f61 Activy DVB-T Budget
+ 114b 2003 DVRaptor Video Edit/Capture Card
+ 11bd 0006 DV500 Overlay
+ 11bd 000a DV500 Overlay
+ 11bd 000f DV500 Overlay
+ 13c2 0000 Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
+ 13c2 0001 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
+ 13c2 0002 Technotrend/Hauppauge DVB card rev2.1
+ 13c2 0003 Technotrend/Hauppauge DVB card rev2.1
+ 13c2 0004 Technotrend/Hauppauge DVB card rev2.1
+ 13c2 0006 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
+ 13c2 0008 Technotrend/Hauppauge DVB-T
+ 13c2 000a Octal/Technotrend DVB-C for iTV
+ 13c2 1003 Technotrend-Budget/Hauppauge WinTV-NOVA-S DVB card
+ 13c2 1004 Technotrend-Budget/Hauppauge WinTV-NOVA-C DVB card
+ 13c2 1005 Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card
+ 13c2 100c Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card
+ 13c2 100f Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card
+ 13c2 1011 Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card
+ 13c2 1013 SATELCO Multimedia DVB
+ 13c2 1016 WinTV-NOVA-SE DVB card
+ 13c2 1102 Technotrend/Hauppauge DVB card rev2.1
+ 153b 1156 Terratec Cynergy 1200C
+ 9730 SAA9730 Integrated Multimedia and Peripheral Controller
+1132 Mitel Corp.
+1133 Eicon Networks Corporation
+ 7901 EiconCard S90
+ 7902 EiconCard S90
+ 7911 EiconCard S91
+ 7912 EiconCard S91
+ 7941 EiconCard S94
+ 7942 EiconCard S94
+ 7943 EiconCard S94
+ 7944 EiconCard S94
+ b921 EiconCard P92
+ b922 EiconCard P92
+ b923 EiconCard P92
+ e001 Diva Pro 2.0 S/T
+ e002 Diva 2.0 S/T PCI
+ e003 Diva Pro 2.0 U
+ e004 Diva 2.0 U PCI
+ e005 Diva 2.01 S/T PCI
+ e006 Diva CT S/T PCI
+ e007 Diva CT U PCI
+ e008 Diva CT Lite S/T PCI
+ e009 Diva CT Lite U PCI
+ e00a Diva ISDN+V.90 PCI
+ e00b Diva 2.02 PCI S/T
+ e00c Diva 2.02 PCI U
+ e00d Diva ISDN Pro 3.0 PCI
+ e00e Diva ISDN+CT S/T PCI Rev 2
+ e010 Diva Server BRI-2M PCI
+ 110a 0021 Fujitsu Siemens ISDN S0
+ e011 Diva Server BRI S/T Rev 2
+ e012 Diva Server 4BRI-8M PCI
+ e013 Diva Server 4BRI Rev 2
+ 1133 1300 Diva Server V-4BRI-8
+ 1133 e013 Diva Server 4BRI-8M 2.0 PCI
+ e014 Diva Server PRI-30M PCI
+ e015 DIVA Server PRI Rev 2
+ 1133 e015 Diva Server PRI 2.0 PCI
+ e016 Diva Server Voice 4BRI PCI
+ e017 Diva Server Voice 4BRI Rev 2
+ 1133 e017 Diva Server Voice 4BRI-8M 2.0 PCI
+ e018 Diva Server BRI-2M 2.0 PCI
+ 1133 1800 Diva Server V-BRI-2
+ 1133 e018 Diva Server BRI-2M 2.0 PCI
+ e019 Diva Server Voice PRI Rev 2
+ 1133 e019 Diva Server Voice PRI 2.0 PCI
+ e01a Diva Server 2FX
+ e01b Diva Server Voice BRI-2M 2.0 PCI
+ 1133 e01b Diva Server Voice BRI-2M 2.0 PCI
+ e01c Diva Server PRI Rev 3
+ 1133 1c01 Diva Server PRI/E1/T1-8
+ 1133 1c02 Diva Server PRI/T1-24
+ 1133 1c03 Diva Server PRI/E1-30
+ 1133 1c04 Diva Server PRI/E1/T1
+ 1133 1c05 Diva Server V-PRI/T1-24
+ 1133 1c06 Diva Server V-PRI/E1-30
+ 1133 1c07 Diva Server PRI/E1/T1-8 Cornet NQ
+ 1133 1c08 Diva Server PRI/T1-24 Cornet NQ
+ 1133 1c09 Diva Server PRI/E1-30 Cornet NQ
+ 1133 1c0a Diva Server PRI/E1/T1 Cornet NQ
+ 1133 1c0b Diva Server V-PRI/T1-24 Cornet NQ
+ 1133 1c0c Diva Server V-PRI/E1-30 Cornet NQ
+ e01e Diva Server 2PRI
+ e020 Diva Server 4PRI
+ e022 Diva Server Analog-2P
+ e024 Diva Server Analog-4P
+ 1133 2400 Diva Server V-Analog-4P
+ 1133 e024 Diva Server Analog-4P
+ e028 Diva Server Analog-8P
+ 1133 2800 Diva Server V-Analog-8P
+ 1133 e028 Diva Server Analog-8P
+ e02a Diva Server IPM-300
+ e02c Diva Server IPM-600
+1134 Mercury Computer Systems
+ 0001 Raceway Bridge
+ 0002 Dual PCI to RapidIO Bridge
+1135 Fuji Xerox Co Ltd
+ 0001 Printer controller
+1136 Momentum Data Systems
+1137 Cisco Systems Inc
+1138 Ziatech Corporation
+ 8905 8905 [STD 32 Bridge]
+1139 Dynamic Pictures, Inc
+ 0001 VGA Compatable 3D Graphics
+113a FWB Inc
+113b Network Computing Devices
+113c Cyclone Microsystems, Inc.
+ 0000 PCI-9060 i960 Bridge
+ 0001 PCI-SDK [PCI i960 Evaluation Platform]
+ 0911 PCI-911 [i960Jx-based Intelligent I/O Controller]
+ 0912 PCI-912 [i960CF-based Intelligent I/O Controller]
+ 0913 PCI-913
+ 0914 PCI-914 [I/O Controller w/ secondary PCI bus]
+113d Leading Edge Products Inc
+113e Sanyo Electric Co - Computer Engineering Dept
+113f Equinox Systems, Inc.
+ 0808 SST-64P Adapter
+ 1010 SST-128P Adapter
+ 80c0 SST-16P DB Adapter
+ 80c4 SST-16P RJ Adapter
+ 80c8 SST-16P Adapter
+ 8888 SST-4P Adapter
+ 9090 SST-8P Adapter
+1140 Intervoice Inc
+1141 Crest Microsystem Inc
+1142 Alliance Semiconductor Corporation
+ 3210 AP6410
+ 6422 ProVideo 6422
+ 6424 ProVideo 6424
+ 6425 ProMotion AT25
+ 643d ProMotion AT3D
+1143 NetPower, Inc
+1144 Cincinnati Milacron
+ 0001 Noservo controller
+1145 Workbit Corporation
+ 8007 NinjaSCSI-32 Workbit
+ f007 NinjaSCSI-32 KME
+ f010 NinjaSCSI-32 Workbit
+ f012 NinjaSCSI-32 Logitec
+ f013 NinjaSCSI-32 Logitec
+ f015 NinjaSCSI-32 Melco
+ f020 NinjaSCSI-32 Sony PCGA-DVD51
+1146 Force Computers
+1147 Interface Corp
+# Nee Schneider & Koch
+1148 SysKonnect
+ 4000 FDDI Adapter
+ 0e11 b03b Netelligent 100 FDDI DAS Fibre SC
+ 0e11 b03c Netelligent 100 FDDI SAS Fibre SC
+ 0e11 b03d Netelligent 100 FDDI DAS UTP
+ 0e11 b03e Netelligent 100 FDDI SAS UTP
+ 0e11 b03f Netelligent 100 FDDI SAS Fibre MIC
+ 1148 5521 FDDI SK-5521 (SK-NET FDDI-UP)
+ 1148 5522 FDDI SK-5522 (SK-NET FDDI-UP DAS)
+ 1148 5541 FDDI SK-5541 (SK-NET FDDI-FP)
+ 1148 5543 FDDI SK-5543 (SK-NET FDDI-LP)
+ 1148 5544 FDDI SK-5544 (SK-NET FDDI-LP DAS)
+ 1148 5821 FDDI SK-5821 (SK-NET FDDI-UP64)
+ 1148 5822 FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
+ 1148 5841 FDDI SK-5841 (SK-NET FDDI-FP64)
+ 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64)
+ 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
+ 4200 Token Ring adapter
+ 4300 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
+ 1148 9821 SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
+ 1148 9822 SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
+ 1148 9841 SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
+ 1148 9842 SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
+ 1148 9843 SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
+ 1148 9844 SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
+ 1148 9861 SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
+ 1148 9862 SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
+ 1148 9871 SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
+ 1148 9872 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
+ 1259 2970 AT-2970SX Gigabit Ethernet Adapter
+ 1259 2971 AT-2970LX Gigabit Ethernet Adapter
+ 1259 2972 AT-2970TX Gigabit Ethernet Adapter
+ 1259 2973 AT-2971SX Gigabit Ethernet Adapter
+ 1259 2974 AT-2971T Gigabit Ethernet Adapter
+ 1259 2975 AT-2970SX/2SC Gigabit Ethernet Adapter
+ 1259 2976 AT-2970LX/2SC Gigabit Ethernet Adapter
+ 1259 2977 AT-2970TX/2TX Gigabit Ethernet Adapter
+ 4320 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC
+ 1148 0121 Marvell RDK-8001 Adapter
+ 1148 0221 Marvell RDK-8002 Adapter
+ 1148 0321 Marvell RDK-8003 Adapter
+ 1148 0421 Marvell RDK-8004 Adapter
+ 1148 0621 Marvell RDK-8006 Adapter
+ 1148 0721 Marvell RDK-8007 Adapter
+ 1148 0821 Marvell RDK-8008 Adapter
+ 1148 0921 Marvell RDK-8009 Adapter
+ 1148 1121 Marvell RDK-8011 Adapter
+ 1148 1221 Marvell RDK-8012 Adapter
+ 1148 3221 SK-9521 V2.0 10/100/1000Base-T Adapter
+ 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
+ 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
+ 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+ 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+ 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+ 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+ 1148 9521 SK-9521 10/100/1000Base-T Adapter
+ 4400 SK-9Dxx Gigabit Ethernet Adapter
+ 4500 SK-9Mxx Gigabit Ethernet Adapter
+ 9000 SK-9S21 10/100/1000Base-T Server Adapter, PCI-X, Copper RJ-45
+ 9843 [Fujitsu] Gigabit Ethernet
+ 9e00 SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45
+ 1148 2100 SK-9E21 Server Adapter
+ 1148 21d0 SK-9E21D 10/100/1000Base-T Adapter
+ 1148 2200 SK-9E22 Server Adapter
+ 1148 8100 SK-9E81 Server Adapter
+ 1148 8200 SK-9E82 Server Adapter
+ 1148 9100 SK-9E91 Server Adapter
+ 1148 9200 SK-9E92 Server Adapter
+1149 Win System Corporation
+114a VMIC
+ 5579 VMIPCI-5579 (Reflective Memory Card)
+ 5587 VMIPCI-5587 (Reflective Memory Card)
+ 6504 VMIC PCI 7755 FPGA
+ 7587 VMIVME-7587
+114b Canopus Co., Ltd
+114c Annabooks
+114d IC Corporation
+114e Nikon Systems Inc
+114f Digi International
+ 0002 AccelePort EPC
+ 0003 RightSwitch SE-6
+ 0004 AccelePort Xem
+ 0005 AccelePort Xr
+ 0006 AccelePort Xr,C/X
+ 0009 AccelePort Xr/J
+ 000a AccelePort EPC/J
+ 000c DataFirePRIme T1 (1-port)
+ 000d SyncPort 2-Port (x.25/FR)
+ 0011 AccelePort 8r EIA-232 (IBM)
+ 0012 AccelePort 8r EIA-422
+ 0014 AccelePort 8r EIA-422
+ 0015 AccelePort Xem
+ 0016 AccelePort EPC/X
+ 0017 AccelePort C/X
+ 001a DataFirePRIme E1 (1-port)
+ 001b AccelePort C/X (IBM)
+ 001d DataFire RAS T1/E1/PRI
+ 114f 0050 DataFire RAS E1 Adapter
+ 114f 0051 DataFire RAS Dual E1 Adapter
+ 114f 0052 DataFire RAS T1 Adapter
+ 114f 0053 DataFire RAS Dual T1 Adapter
+ 0023 AccelePort RAS
+ 0024 DataFire RAS B4 ST/U
+ 114f 0030 DataFire RAS BRI U Adapter
+ 114f 0031 DataFire RAS BRI S/T Adapter
+ 0026 AccelePort 4r 920
+ 0027 AccelePort Xr 920
+ 0028 ClassicBoard 4
+ 0029 ClassicBoard 8
+ 0034 AccelePort 2r 920
+ 0035 DataFire DSP T1/E1/PRI cPCI
+ 0040 AccelePort Xp
+ 0042 AccelePort 2p
+ 0043 AccelePort 4p
+ 0044 AccelePort 8p
+ 0045 AccelePort 16p
+ 004e AccelePort 32p
+ 0070 Datafire Micro V IOM2 (Europe)
+ 0071 Datafire Micro V (Europe)
+ 0072 Datafire Micro V IOM2 (North America)
+ 0073 Datafire Micro V (North America)
+ 00b0 Digi Neo 4
+ 00b1 Digi Neo 8
+ 00c8 Digi Neo 2 DB9
+ 00c9 Digi Neo 2 DB9 PRI
+ 00ca Digi Neo 2 RJ45
+ 00cb Digi Neo 2 RJ45 PRI
+ 00d0 ClassicBoard 4 422
+ 00d1 ClassicBoard 8 422
+ 6001 Avanstar
+1150 Thinking Machines Corp
+1151 JAE Electronics Inc.
+1152 Megatek
+1153 Land Win Electronic Corp
+1154 Melco Inc
+1155 Pine Technology Ltd
+1156 Periscope Engineering
+1157 Avsys Corporation
+1158 Voarx R & D Inc
+ 3011 Tokenet/vg 1001/10m anylan
+ 9050 Lanfleet/Truevalue
+ 9051 Lanfleet/Truevalue
+1159 Mutech Corp
+ 0001 MV-1000
+115a Harlequin Ltd
+115b Parallax Graphics
+115c Photron Ltd.
+115d Xircom
+ 0003 Cardbus Ethernet 10/100
+ 1014 0181 10/100 EtherJet Cardbus Adapter
+ 1014 1181 10/100 EtherJet Cardbus Adapter
+ 1014 8181 10/100 EtherJet Cardbus Adapter
+ 1014 9181 10/100 EtherJet Cardbus Adapter
+ 115d 0181 Cardbus Ethernet 10/100
+ 115d 0182 RealPort2 CardBus Ethernet 10/100 (R2BE-100)
+ 115d 1181 Cardbus Ethernet 10/100
+ 1179 0181 Cardbus Ethernet 10/100
+ 8086 8181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
+ 8086 9181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
+ 0005 Cardbus Ethernet 10/100
+ 1014 0182 10/100 EtherJet Cardbus Adapter
+ 1014 1182 10/100 EtherJet Cardbus Adapter
+ 115d 0182 Cardbus Ethernet 10/100
+ 115d 1182 Cardbus Ethernet 10/100
+ 0007 Cardbus Ethernet 10/100
+ 1014 0182 10/100 EtherJet Cardbus Adapter
+ 1014 1182 10/100 EtherJet Cardbus Adapter
+ 115d 0182 Cardbus Ethernet 10/100
+ 115d 1182 Cardbus Ethernet 10/100
+ 000b Cardbus Ethernet 10/100
+ 1014 0183 10/100 EtherJet Cardbus Adapter
+ 115d 0183 Cardbus Ethernet 10/100
+ 000c Mini-PCI V.90 56k Modem
+ 000f Cardbus Ethernet 10/100
+ 1014 0183 10/100 EtherJet Cardbus Adapter
+ 115d 0183 Cardbus Ethernet 10/100
+ 00d4 Mini-PCI K56Flex Modem
+ 0101 Cardbus 56k modem
+ 115d 1081 Cardbus 56k Modem
+ 0103 Cardbus Ethernet + 56k Modem
+ 1014 9181 Cardbus 56k Modem
+ 1115 1181 Cardbus Ethernet 100 + 56k Modem
+ 115d 1181 CBEM56G-100 Ethernet + 56k Modem
+ 8086 9181 PRO/100 LAN + Modem56 CardBus
+115e Peer Protocols Inc
+115f Maxtor Corporation
+1160 Megasoft Inc
+1161 PFU Limited
+1162 OA Laboratory Co Ltd
+1163 Rendition
+ 0001 Verite 1000
+ 2000 Verite V2000/V2100/V2200
+ 1092 2000 Stealth II S220
+1164 Advanced Peripherals Technologies
+1165 Imagraph Corporation
+ 0001 Motion TPEG Recorder/Player with audio
+# nee ServerWorks
+1166 Broadcom
+ 0000 CMIC-LE
+ 0005 CNB20-LE Host Bridge
+ 0006 CNB20HE Host Bridge
+ 0007 CNB20-LE Host Bridge
+ 0008 CNB20HE Host Bridge
+ 0009 CNB20LE Host Bridge
+ 0010 CIOB30
+ 0011 CMIC-HE
+ 0012 CMIC-WS Host Bridge (GC-LE chipset)
+ 0013 CNB20-HE Host Bridge
+ 0014 CMIC-LE Host Bridge (GC-LE chipset)
+ 0015 CMIC-GC Host Bridge
+ 0016 CMIC-GC Host Bridge
+ 0017 GCNB-LE Host Bridge
+ 0036 HT1000 PCI/PCI-X bridge
+ 0101 CIOB-X2 PCI-X I/O Bridge
+ 0103 EPB PCI-Express to PCI-X Bridge
+ 0104 HT1000 PCI/PCI-X bridge
+ 0110 CIOB-E I/O Bridge with Gigabit Ethernet
+ 0130 HT2000 PCI-X bridge
+ 0132 HT2000 PCI-Express bridge
+ 1166 0132 HT2000 PCI-Express bridge
+ 0140 HT2100 PCI-Express Bridge
+ 0141 HT2100 PCI-Express Bridge
+ 0142 HT2100 PCI-Express Bridge
+ 0200 OSB4 South Bridge
+ 0201 CSB5 South Bridge
+ 4c53 1080 CT8 mainboard
+ 0203 CSB6 South Bridge
+ 1734 1012 Primergy RX300
+ 0205 HT1000 Legacy South Bridge
+ 0211 OSB4 IDE Controller
+ 0212 CSB5 IDE Controller
+ 4c53 1080 CT8 mainboard
+ 0213 CSB6 RAID/IDE Controller
+ 1028 4134 PowerEdge 600SC
+ 1028 c134 Poweredge SC600
+ 1734 1012 Primergy RX300
+ 0214 HT1000 Legacy IDE controller
+ 0217 CSB6 IDE Controller
+ 1028 4134 Poweredge SC600
+ 0220 OSB4/CSB5 OHCI USB Controller
+ 4c53 1080 CT8 mainboard
+ 0221 CSB6 OHCI USB Controller
+ 1734 1012 Primergy RX300
+ 0223 HT1000 USB Controller
+ 0225 CSB5 LPC bridge
+ 0227 GCLE-2 Host Bridge
+ 1734 1012 Primergy RX300
+ 0230 CSB5 LPC bridge
+ 4c53 1080 CT8 mainboard
+ 0234 HT1000 LPC Bridge
+ 0240 K2 SATA
+ 0241 RAIDCore RC4000
+ 0242 RAIDCore BC4000
+ 024a BCM5785 (HT1000) SATA Native SATA Mode
+# The device starts as 024a, and changes to 024b if set to PATA mode in BIOS
+ 024b BCM5785 (HT1000) PATA/IDE Mode
+1167 Mutoh Industries Inc
+1168 Thine Electronics Inc
+1169 Centre for Development of Advanced Computing
+116a Polaris Communications
+ 6100 Bus/Tag Channel
+ 6800 Escon Channel
+ 7100 Bus/Tag Channel
+ 7800 Escon Channel
+116b Connectware Inc
+116c Intelligent Resources Integrated Systems
+116d Martin-Marietta
+116e Electronics for Imaging
+116f Workstation Technology
+1170 Inventec Corporation
+1171 Loughborough Sound Images Plc
+1172 Altera Corporation
+1173 Adobe Systems, Inc
+1174 Bridgeport Machines
+1175 Mitron Computer Inc.
+1176 SBE Incorporated
+1177 Silicon Engineering
+1178 Alfa, Inc.
+ afa1 Fast Ethernet Adapter
+1179 Toshiba America Info Systems
+ 0102 Extended IDE Controller
+ 0103 EX-IDE Type-B
+ 0404 DVD Decoder card
+ 0406 Tecra Video Capture device
+ 0407 DVD Decoder card (Version 2)
+ 0601 CPU to PCI bridge
+ 1179 0001 Satellite Pro
+ 0603 ToPIC95 PCI to CardBus Bridge for Notebooks
+ 060a ToPIC95
+ 1179 0001 Satellite Pro
+ 060f ToPIC97
+ 0617 ToPIC100 PCI to Cardbus Bridge with ZV Support
+ 0618 CPU to PCI and PCI to ISA bridge
+# Claimed to be Lucent DSP1645 [Mars], but that's apparently incorrect. Does anyone know the correct ID?
+ 0701 FIR Port
+ 0804 TC6371AF SmartMedia Controller
+ 0805 SD TypA Controller
+ 0d01 FIR Port Type-DO
+ 1179 0001 FIR Port Type-DO
+117a A-Trend Technology
+117b L G Electronics, Inc.
+117c Atto Technology
+ 0030 Ultra320 SCSI Host Adapter
+ 117c 8013 ExpressPCI UL4D
+ 117c 8014 ExpressPCI UL4S
+117d Becton & Dickinson
+117e T/R Systems
+117f Integrated Circuit Systems
+1180 Ricoh Co Ltd
+ 0465 RL5c465
+ 0466 RL5c466
+ 0475 RL5c475
+ 144d c006 vpr Matrix 170B4 CardBus bridge
+ 0476 RL5c476 II
+ 1014 0185 ThinkPad A/T/X Series
+ 1028 0188 Inspiron 6000 laptop
+ 1043 1967 V6800V
+ 1043 1987 Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines )
+ 104d 80df Vaio PCG-FX403
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 144d c00c P35 notebook
+ 14ef 0220 PCD-RP-220S
+ 17aa 201c Thinkpad X60s
+ 0477 RL5c477
+ 0478 RL5c478
+ 1014 0184 ThinkPad A30p (2653-64G)
+ 0511 R5C511
+ 0522 R5C522 IEEE 1394 Controller
+ 1014 01cf ThinkPad A30p (2653-64G)
+ 1043 1967 V6800V
+ 0551 R5C551 IEEE 1394 Controller
+ 144d c006 vpr Matrix 170B4
+ 0552 R5C552 IEEE 1394 Controller
+ 1014 0511 ThinkPad A/T/X Series
+ 1028 0188 Inspiron 6000 laptop
+ 144d c00c P35 notebook
+ 17aa 201e Thinkpad X60s
+ 0554 R5C554
+ 0575 R5C575 SD Bus Host Adapter
+ 0576 R5C576 SD Bus Host Adapter
+ 0592 R5C592 Memory Stick Bus Host Adapter
+ 1043 1967 V6800V
+ 144d c018 X20 IV
+ 0811 R5C811
+ 0822 R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter
+ 1014 0556 Thinkpad X40
+ 1014 0598 Thinkpad Z60m
+ 1028 0188 Inspiron 6000 laptop
+ 1028 01a2 Inspiron 9200
+ 1043 1967 ASUS V6800V
+ 144d c018 X20 IV
+ 17aa 201d Thinkpad X60s
+ 0841 R5C841 CardBus/SD/SDIO/MMC/MS/MSPro/xD/IEEE1394
+ 0852 xD-Picture Card Controller
+ 1043 1967 V6800V
+1181 Telmatics International
+1183 Fujikura Ltd
+1184 Forks Inc
+1185 Dataworld International Ltd
+1186 D-Link System Inc
+ 0100 DC21041
+ 1002 DL10050 Sundance Ethernet
+ 1186 1002 DFE-550TX
+ 1186 1012 DFE-580TX
+ 1025 AirPlus Xtreme G DWL-G650 Adapter
+ 1026 AirXpert DWL-AG650 Wireless Cardbus Adapter
+ 1043 AirXpert DWL-AG650 Wireless Cardbus Adapter
+ 1300 RTL8139 Ethernet
+ 1186 1300 DFE-538TX 10/100 Ethernet Adapter
+ 1186 1301 DFE-530TX+ 10/100 Ethernet Adapter
+ 1186 1303 DFE-528TX 10/100 Fast Ethernet PCI Adapter
+ 1340 DFE-690TXD CardBus PC Card
+ 1405 DFE-520TX Fast Ethernet PCI Adapter
+ 1541 DFE-680TXD CardBus PC Card
+ 1561 DRP-32TXD Cardbus PC Card
+ 2027 AirPlus Xtreme G DWL-G520 Adapter
+ 3203 AirPlus Xtreme G DWL-G520 Adapter
+ 3300 DWL-510 2.4GHz Wireless PCI Adapter
+ 3a03 AirPro DWL-A650 Wireless Cardbus Adapter(rev.B)
+ 3a04 AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
+ 3a05 AirPro DWL-AB520 Multimode Wireless PCI Adapter
+ 3a07 AirXpert DWL-AG650 Wireless Cardbus Adapter
+ 3a08 AirXpert DWL-AG520 Wireless PCI Adapter
+ 3a10 AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
+ 3a11 AirXpert DWL-AG520 Wireless PCI Adapter(rev.B)
+ 3a12 AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
+ 3a13 AirPlus DWL-G520 Wireless PCI Adapter(rev.B)
+ 3a14 AirPremier DWL-AG530 Wireless PCI Adapter
+ 3a63 AirXpert DWL-AG660 Wireless Cardbus Adapter
+ 4000 DL2000-based Gigabit Ethernet
+ 4300 DGE-528T Gigabit Ethernet Adapter
+ 4b01 DGE-530T Gigabit Ethernet Adapter (rev 11)
+ 4c00 Gigabit Ethernet Adapter
+ 1186 4c00 DGE-530T Gigabit Ethernet Adapter
+ 8400 D-Link DWL-650+ CardBus PC Card
+1187 Advanced Technology Laboratories, Inc.
+1188 Shima Seiki Manufacturing Ltd.
+1189 Matsushita Electronics Co Ltd
+118a Hilevel Technology
+118b Hypertec Pty Limited
+118c Corollary, Inc
+ 0014 PCIB [C-bus II to PCI bus host bridge chip]
+ 1117 Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
+118d BitFlow Inc
+ 0001 Raptor-PCI framegrabber
+ 0012 Model 12 Road Runner Frame Grabber
+ 0014 Model 14 Road Runner Frame Grabber
+ 0024 Model 24 Road Runner Frame Grabber
+ 0044 Model 44 Road Runner Frame Grabber
+ 0112 Model 12 Road Runner Frame Grabber
+ 0114 Model 14 Road Runner Frame Grabber
+ 0124 Model 24 Road Runner Frame Grabber
+ 0144 Model 44 Road Runner Frame Grabber
+ 0212 Model 12 Road Runner Frame Grabber
+ 0214 Model 14 Road Runner Frame Grabber
+ 0224 Model 24 Road Runner Frame Grabber
+ 0244 Model 44 Road Runner Frame Grabber
+ 0312 Model 12 Road Runner Frame Grabber
+ 0314 Model 14 Road Runner Frame Grabber
+ 0324 Model 24 Road Runner Frame Grabber
+ 0344 Model 44 Road Runner Frame Grabber
+118e Hermstedt GmbH
+118f Green Logic
+1190 Tripace
+ c731 TP-910/920/940 PCI Ultra(Wide) SCSI Adapter
+1191 Artop Electronic Corp
+ 0003 SCSI Cache Host Adapter
+ 0004 ATP8400
+ 0005 ATP850UF
+ 0006 ATP860 NO-BIOS
+ 0007 ATP860
+ 0008 ATP865 NO-ROM
+ 0009 ATP865
+ 8002 AEC6710 SCSI-2 Host Adapter
+ 8010 AEC6712UW SCSI
+ 8020 AEC6712U SCSI
+ 8030 AEC6712S SCSI
+ 8040 AEC6712D SCSI
+ 8050 AEC6712SUW SCSI
+ 8060 AEC6712 SCSI
+ 8080 AEC67160 SCSI
+ 8081 AEC67160S SCSI
+ 808a AEC67162 2-ch. LVD SCSI
+1192 Densan Company Ltd
+1193 Zeitnet Inc.
+ 0001 1221
+ 0002 1225
+1194 Toucan Technology
+1195 Ratoc System Inc
+1196 Hytec Electronics Ltd
+1197 Gage Applied Sciences, Inc.
+ 010c CompuScope 82G 8bit 2GS/s Analog Input Card
+1198 Lambda Systems Inc
+1199 Attachmate Corporation
+119a Mind Share, Inc.
+119b Omega Micro Inc.
+ 1221 82C092G
+119c Information Technology Inst.
+119d Bug, Inc. Sapporo Japan
+119e Fujitsu Microelectronics Ltd.
+ 0001 FireStream 155
+ 0003 FireStream 50
+119f Bull HN Information Systems
+11a0 Convex Computer Corporation
+11a1 Hamamatsu Photonics K.K.
+11a2 Sierra Research and Technology
+11a3 Deuretzbacher GmbH & Co. Eng. KG
+11a4 Barco Graphics NV
+11a5 Microunity Systems Eng. Inc
+11a6 Pure Data Ltd.
+11a7 Power Computing Corp.
+11a8 Systech Corp.
+11a9 InnoSys Inc.
+ 4240 AMCC S933Q Intelligent Serial Card
+11aa Actel
+# Nee Galileo Technology, Inc.
+11ab Marvell Technology Group Ltd.
+ 0146 GT-64010/64010A System Controller
+ 138f W8300 802.11 Adapter (rev 07)
+ 1fa6 Marvell W8300 802.11 Adapter
+ 1fa7 88W8310 and 88W8000G [Libertas] 802.11g client chipset
+ 1faa 88w8335 [Libertas] 802.11b/g Wireless
+ 1385 4e00 WG511 v2 54MBit/ Wireless PC-Card
+ 4320 88E8001 Gigabit Ethernet Controller
+ 1019 0f38 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+ 1019 8001 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+ 1043 173c Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+ 1043 811a Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+ 105b 0c19 Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
+ 10b8 b452 EZ Card 1000 (SMC9452TXV.2)
+ 11ab 0121 Marvell RDK-8001
+ 11ab 0321 Marvell RDK-8003
+ 11ab 1021 Marvell RDK-8010
+ 11ab 4320 Marvell Yukon Gigabit Ethernet 10/100/1000Baset-T Constroller (Asus)
+ 11ab 5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
+ 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
+ 1458 e000 Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
+ 147b 1406 Marvell 88E8001 Gigabit Ethernet Controller (Abit)
+ 15d4 0047 Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
+ 1695 9025 Marvell 88E8001 Gigabit Ethernet Controller (Epox)
+ 17f2 1c03 Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
+ 270f 2803 Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
+ 4340 88E8021 PCI-X IPMI Gigabit Ethernet Controller
+ 4341 88E8022 PCI-X IPMI Gigabit Ethernet Controller
+ 4342 88E8061 PCI-E IPMI Gigabit Ethernet Controller
+ 4343 88E8062 PCI-E IPMI Gigabit Ethernet Controller
+ 4344 88E8021 PCI-X IPMI Gigabit Ethernet Controller
+ 4345 88E8022 PCI-X IPMI Gigabit Ethernet Controller
+ 4346 88E8061 PCI-E IPMI Gigabit Ethernet Controller
+ 4347 88E8062 PCI-E IPMI Gigabit Ethernet Controller
+ 4350 88E8035 PCI-E Fast Ethernet Controller
+ 1179 0001 Marvell 88E8035 Fast Ethernet Controller (Toshiba)
+ 11ab 3521 Marvell RDK-8035
+ 1854 000d Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 000e Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 000f Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0011 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0012 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0016 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0017 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0018 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0019 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 001c Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 001e Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 1854 0020 Marvell 88E8035 Fast Ethernet Controller (LGE)
+ 4351 88E8036 PCI-E Fast Ethernet Controller
+ 107b 4009 Marvell 88E8036 Fast Ethernet Controller (Wistron)
+ 10f7 8338 Marvell 88E8036 Fast Ethernet Controller (Panasonic)
+ 1179 0001 Marvell 88E8036 Fast Ethernet Controller (Toshiba)
+ 1179 ff00 Marvell 88E8036 Fast Ethernet Controller (Compal)
+ 1179 ff10 Marvell 88E8036 Fast Ethernet Controller (Inventec)
+ 11ab 3621 Marvell RDK-8036
+ 13d1 ac12 Abocom EFE3K - 10/100 Ethernet Expresscard
+ 161f 203d Marvell 88E8036 Fast Ethernet Controller (Arima)
+ 1854 000d Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 000e Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 000f Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0011 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0012 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0016 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0017 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0018 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0019 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 001c Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 001e Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 1854 0020 Marvell 88E8036 Fast Ethernet Controller (LGE)
+ 4352 88E8038 PCI-E Fast Ethernet Controller
+ 4360 88E8052 PCI-E ASF Gigabit Ethernet Controller
+ 1043 8134 Marvell 88E8052 Gigabit Ethernet Controller (Asus)
+ 107b 4009 Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
+ 11ab 5221 Marvell RDK-8052
+ 1458 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
+ 1462 052c Marvell 88E8052 Gigabit Ethernet Controller (MSI)
+ 1849 8052 Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
+ a0a0 0509 Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
+ 4361 88E8050 PCI-E ASF Gigabit Ethernet Controller
+ 107b 3015 Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
+ 11ab 5021 Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+ 8086 3063 D925XCVLK mainboard
+ 8086 3439 Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+ 4362 88E8053 PCI-E Gigabit Ethernet Controller
+ 103c 2a0d Marvell 88E8053 Gigabit Ethernet Controller (Asus)
+ 1043 8142 Marvell 88E8053 Gigabit Ethernet controller PCIe (Asus)
+ 109f 3197 Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
+ 10f7 8338 Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
+ 10fd a430 Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
+ 1179 0001 Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
+ 1179 ff00 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+ 1179 ff10 Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
+ 11ab 5321 Marvell RDK-8053
+ 1297 c240 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ 1297 c241 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ 1297 c242 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ 1297 c243 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ 1297 c244 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ 13d1 ac11 EGE5K - Giga Ethernet Expresscard
+ 1458 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
+ 1462 058c Marvell 88E8053 Gigabit Ethernet Controller (MSI)
+ 14c0 0012 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+ 1558 04a0 Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
+ 15bd 1003 Marvell 88E8053 Gigabit Ethernet Controller (DFI)
+ 161f 203c Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+ 161f 203d Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+ 1695 9029 Marvell 88E8053 Gigabit Ethernet Controller (Epox)
+ 17f2 2c08 Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
+ 17ff 0585 Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
+ 1849 8053 Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
+ 1854 000b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 000c Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 0010 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 0013 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 0014 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 0015 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 001a Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 001b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 001d Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 001f Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 0021 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 1854 0022 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ 270f 2801 Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
+ a0a0 0506 Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
+ 4363 88E8055 PCI-E Gigabit Ethernet Controller
+ 4611 GT-64115 System Controller
+ 4620 GT-64120/64120A/64121A System Controller
+ 4801 GT-48001
+ 5005 Belkin F5D5005 Gigabit Desktop Network PCI Card
+ 5040 MV88SX5040 4-port SATA I PCI-X Controller
+ 5041 MV88SX5041 4-port SATA I PCI-X Controller
+ 5080 MV88SX5080 8-port SATA I PCI-X Controller
+ 5081 MV88SX5081 8-port SATA I PCI-X Controller
+ 6041 MV88SX6041 4-port SATA II PCI-X Controller
+ 6081 MV88SX6081 8-port SATA II PCI-X Controller
+ 6460 MV64360/64361/64362 System Controller
+ 6480 MV64460/64461/64462 System Controller
+ f003 GT-64010 Primary Image Piranha Image Generator
+11ac Canon Information Systems Research Aust.
+11ad Lite-On Communications Inc
+ 0002 LNE100TX
+ 11ad 0002 LNE100TX
+ 11ad 0003 LNE100TX
+ 11ad f003 LNE100TX
+ 11ad ffff LNE100TX
+ 1385 f004 FA310TX
+ c115 LNE100TX [Linksys EtherFast 10/100]
+ 11ad c001 LNE100TX [ver 2.0]
+11ae Aztech System Ltd
+11af Avid Technology Inc.
+ 0001 Cinema
+ ee40 Digidesign Audiomedia III
+11b0 V3 Semiconductor Inc.
+ 0002 V300PSC
+ 0292 V292PBC [Am29030/40 Bridge]
+ 0960 V96xPBC
+ c960 V96DPC
+11b1 Apricot Computers
+11b2 Eastman Kodak
+11b3 Barr Systems Inc.
+11b4 Leitch Technology International
+11b5 Radstone Technology Plc
+11b6 United Video Corp
+11b7 Motorola
+11b8 XPoint Technologies, Inc
+ 0001 Quad PeerMaster
+11b9 Pathlight Technology Inc.
+ c0ed SSA Controller
+11ba Videotron Corp
+11bb Pyramid Technology
+11bc Network Peripherals Inc
+ 0001 NP-PCI
+11bd Pinnacle Systems Inc.
+ 002e PCTV 40i
+ bede AV/DV Studio Capture Card
+11be International Microcircuits Inc
+11bf Astrodesign, Inc.
+11c0 Hewlett Packard
+# Nee Lucent Microelectronics
+11c1 Agere Systems
+ 0440 56k WinModem
+ 1033 8015 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 1033 8047 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 1033 804f LT WinModem 56k Data+Fax+Voice+Dsvd
+ 10cf 102c LB LT Modem V.90 56k
+ 10cf 104a BIBLO LT Modem 56k
+ 10cf 105f LB2 LT Modem V.90 56k
+ 1179 0001 Internal V.90 Modem
+ 11c1 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 122d 4101 MDP7800-U Modem
+ 122d 4102 MDP7800SP-U Modem
+ 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 13e0 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 13e0 0441 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 13e0 0450 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 13e0 f100 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 13e0 f101 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 144d 2101 LT56PV Modem
+ 149f 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 0441 56k WinModem
+ 1033 804d LT WinModem 56k Data+Fax
+ 1033 8065 LT WinModem 56k Data+Fax
+ 1092 0440 Supra 56i
+ 1179 0001 Internal V.90 Modem
+ 11c1 0440 LT WinModem 56k Data+Fax
+ 11c1 0441 LT WinModem 56k Data+Fax
+ 122d 4100 MDP7800-U Modem
+ 13e0 0040 LT WinModem 56k Data+Fax
+ 13e0 0100 LT WinModem 56k Data+Fax
+ 13e0 0410 LT WinModem 56k Data+Fax
+ 13e0 0420 TelePath Internet 56k WinModem
+ 13e0 0440 LT WinModem 56k Data+Fax
+ 13e0 0443 LT WinModem 56k Data+Fax
+ 13e0 f102 LT WinModem 56k Data+Fax
+ 1416 9804 CommWave 56k Modem
+ 141d 0440 LT WinModem 56k Data+Fax
+ 144f 0441 Lucent 56k V.90 DF Modem
+ 144f 0449 Lucent 56k V.90 DF Modem
+ 144f 110d Lucent Win Modem
+ 1468 0441 Presario 56k V.90 DF Modem
+ 1668 0440 Lucent Win Modem
+ 0442 56k WinModem
+ 11c1 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 11c1 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 13e0 0412 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 13e0 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 13fc 2471 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 144d 2104 LT56PT Modem
+ 144f 1104 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 149f 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 1668 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 0443 LT WinModem
+ 0444 LT WinModem
+ 0445 LT WinModem
+ 8086 2203 PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
+ 8086 2204 PRO/100+ MiniPCI on Armada E500
+ 0446 LT WinModem
+ 0447 LT WinModem
+ 0448 WinModem 56k
+ 1014 0131 Lucent Win Modem
+ 1033 8066 LT WinModem 56k Data+Fax+Voice+Dsvd
+ 13e0 0030 56k Voice Modem
+ 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
+# Actiontech eth+modem card as used by Dell &c.
+ 1668 2400 LT WinModem 56k (MiniPCI Ethernet+Modem)
+ 0449 WinModem 56k
+ 0e11 b14d 56k V.90 Modem
+ 13e0 0020 LT WinModem 56k Data+Fax
+ 13e0 0041 TelePath Internet 56k WinModem
+ 1436 0440 Lucent Win Modem
+ 144f 0449 Lucent 56k V.90 DFi Modem
+ 1468 0410 IBM ThinkPad T23 (2647-4MG)
+ 1468 0440 Lucent Win Modem
+ 1468 0449 Presario 56k V.90 DFi Modem
+ 044a F-1156IV WinModem (V90, 56KFlex)
+ 10cf 1072 LB Global LT Modem
+ 13e0 0012 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 13e0 0042 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 144f 1005 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ 044b LT WinModem
+ 044c LT WinModem
+ 044d LT WinModem
+ 044e LT WinModem
+ 044f V90 WildWire Modem
+ 0450 LT WinModem
+ 1033 80a8 Versa Note Vxi
+ 144f 4005 Magnia SG20
+ 1468 0450 Evo N600c
+ 4005 144f LifeBook C Series
+ 0451 LT WinModem
+ 0452 LT WinModem
+ 0453 LT WinModem
+ 0454 LT WinModem
+ 0455 LT WinModem
+ 0456 LT WinModem
+ 0457 LT WinModem
+ 0458 LT WinModem
+ 0459 LT WinModem
+ 045a LT WinModem
+ 045c LT WinModem
+ 0461 V90 WildWire Modem
+ 0462 V90 WildWire Modem
+ 0480 Venus Modem (V90, 56KFlex)
+ 048c V.92 56K WinModem
+# InPorte Home Internal 56k Modem/fax/answering machine/SMS Features
+ 048f V.92 56k WinModem
+ 5801 USB
+ 5802 USS-312 USB Controller
+ 5803 USS-344S USB Controller
+ 5811 FW323
+ 8086 524c D865PERL mainboard
+ dead 0800 FireWire Host Bus Adapter
+ 8110 T8110 H.100/H.110 TDM switch
+ 12d9 000c E1/T1 PMXc cPCI carrier card
+ ab10 WL60010 Wireless LAN MAC
+ ab11 WL60040 Multimode Wireles LAN MAC
+ 11c1 ab12 WaveLAN 11abg Cardbus card (Model 1102)
+ 11c1 ab13 WaveLAN 11abg MiniPCI card (Model 0512)
+ 11c1 ab15 WaveLAN 11abg Cardbus card (Model 1106)
+ 11c1 ab16 WaveLAN 11abg MiniPCI card (Model 0516)
+ ab20 ORiNOCO PCI Adapter
+ ab21 Agere Wireless PCI Adapter
+ ab30 Hermes2 Mini-PCI WaveLAN a/b/g
+ 14cd 2012 Hermes2 Mini-PCI WaveLAN a/b/g
+ ed00 ET-131x PCI-E Ethernet Controller
+11c2 Sand Microelectronics
+11c3 NEC Corporation
+11c4 Document Technologies, Inc
+11c5 Shiva Corporation
+11c6 Dainippon Screen Mfg. Co. Ltd
+11c7 D.C.M. Data Systems
+11c8 Dolphin Interconnect Solutions AS
+ 0658 PSB32 SCI-Adapter D31x
+ d665 PSB64 SCI-Adapter D32x
+ d667 PSB66 SCI-Adapter D33x
+11c9 Magma
+ 0010 16-line serial port w/- DMA
+ 0011 4-line serial port w/- DMA
+11ca LSI Systems, Inc
+11cb Specialix Research Ltd.
+ 2000 PCI_9050
+ 11cb 0200 SX
+ 11cb b008 I/O8+
+ 4000 SUPI_1
+ 8000 T225
+11cc Michels & Kleberhoff Computer GmbH
+11cd HAL Computer Systems, Inc.
+11ce Netaccess
+11cf Pioneer Electronic Corporation
+11d0 Lockheed Martin Federal Systems-Manassas
+11d1 Auravision
+ 01f7 VxP524
+11d2 Intercom Inc.
+11d3 Trancell Systems Inc
+11d4 Analog Devices
+ 1535 Blackfin BF535 processor
+ 1805 SM56 PCI modem
+ 1889 AD1889 sound chip
+ 1986 AD1986A sound chip
+ 5340 AD1881 sound chip
+11d5 Ikon Corporation
+ 0115 10115
+ 0117 10117
+11d6 Tekelec Telecom
+11d7 Trenton Technology, Inc.
+11d8 Image Technologies Development
+11d9 TEC Corporation
+11da Novell
+11db Sega Enterprises Ltd
+11dc Questra Corporation
+11dd Crosfield Electronics Limited
+11de Zoran Corporation
+ 6057 ZR36057PQC Video cutting chipset
+ 1031 7efe DC10 Plus
+ 1031 fc00 MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
+ 12f8 8a02 Tekram Video Kit
+ 13ca 4231 JPEG/TV Card
+ 6120 ZR36120
+ 1328 f001 Cinemaster C DVD Decoder
+ 13c2 0000 MediaFocus Satellite TV Card
+ 1de1 9fff Video Kit C210
+11df New Wave PDG
+11e0 Cray Communications A/S
+11e1 GEC Plessey Semi Inc.
+11e2 Samsung Information Systems America
+11e3 Quicklogic Corporation
+ 0001 COM-ON-AIR Dosch&Amand DECT
+ 5030 PC Watchdog
+11e4 Second Wave Inc
+11e5 IIX Consulting
+11e6 Mitsui-Zosen System Research
+11e7 Toshiba America, Elec. Company
+11e8 Digital Processing Systems Inc.
+11e9 Highwater Designs Ltd.
+11ea Elsag Bailey
+11eb Formation Inc.
+11ec Coreco Inc
+11ed Mediamatics
+11ee Dome Imaging Systems Inc
+11ef Nicolet Technologies B.V.
+11f0 Compu-Shack
+ 4231 FDDI
+ 4232 FASTline UTP Quattro
+ 4233 FASTline FO
+ 4234 FASTline UTP
+ 4235 FASTline-II UTP
+ 4236 FASTline-II FO
+ 4731 GIGAline
+11f1 Symbios Logic Inc
+11f2 Picture Tel Japan K.K.
+11f3 Keithley Metrabyte
+11f4 Kinetic Systems Corporation
+ 2915 CAMAC controller
+11f5 Computing Devices International
+11f6 Compex
+ 0112 ENet100VG4
+ 0113 FreedomLine 100
+ 1401 ReadyLink 2000
+ 2011 RL100-ATX 10/100
+ 11f6 2011 RL100-ATX
+ 2201 ReadyLink 100TX (Winbond W89C840)
+ 11f6 2011 ReadyLink 100TX
+ 9881 RL100TX Fast Ethernet
+11f7 Scientific Atlanta
+11f8 PMC-Sierra Inc.
+ 7375 PM7375 [LASAR-155 ATM SAR]
+11f9 I-Cube Inc
+11fa Kasan Electronics Company, Ltd.
+11fb Datel Inc
+11fc Silicon Magic
+11fd High Street Consultants
+11fe Comtrol Corporation
+ 0001 RocketPort 32 port w/external I/F
+ 0002 RocketPort 8 port w/external I/F
+ 0003 RocketPort 16 port w/external I/F
+ 0004 RocketPort 4 port w/quad cable
+ 0005 RocketPort 8 port w/octa cable
+ 0006 RocketPort 8 port w/RJ11 connectors
+ 0007 RocketPort 4 port w/RJ11 connectors
+ 0008 RocketPort 8 port w/ DB78 SNI (Siemens) connector
+ 0009 RocketPort 16 port w/ DB78 SNI (Siemens) connector
+ 000a RocketPort Plus 4 port
+ 000b RocketPort Plus 8 port
+ 000c RocketModem 6 port
+ 000d RocketModem 4-port
+ 000e RocketPort Plus 2 port RS232
+ 000f RocketPort Plus 2 port RS422
+ 0801 RocketPort UPCI 32 port w/external I/F
+ 0802 RocketPort UPCI 8 port w/external I/F
+ 0803 RocketPort UPCI 16 port w/external I/F
+ 0805 RocketPort UPCI 8 port w/octa cable
+ 080c RocketModem III 8 port
+ 080d RocketModem III 4 port
+ 0812 RocketPort UPCI Plus 8 port RS422
+ 0903 RocketPort Compact PCI 16 port w/external I/F
+ 8015 RocketPort 4-port UART 16954
+11ff Scion Corporation
+ 0003 AG-5
+1200 CSS Corporation
+1201 Vista Controls Corp
+1202 Network General Corp.
+ 4300 Gigabit Ethernet Adapter
+ 1202 9841 SK-9841 LX
+ 1202 9842 SK-9841 LX dual link
+ 1202 9843 SK-9843 SX
+ 1202 9844 SK-9843 SX dual link
+1203 Bayer Corporation, Agfa Division
+1204 Lattice Semiconductor Corporation
+1205 Array Corporation
+1206 Amdahl Corporation
+1208 Parsytec GmbH
+ 4853 HS-Link Device
+1209 SCI Systems Inc
+120a Synaptel
+120b Adaptive Solutions
+120c Technical Corp.
+120d Compression Labs, Inc.
+120e Cyclades Corporation
+ 0100 Cyclom-Y below first megabyte
+ 0101 Cyclom-Y above first megabyte
+ 0102 Cyclom-4Y below first megabyte
+ 0103 Cyclom-4Y above first megabyte
+ 0104 Cyclom-8Y below first megabyte
+ 0105 Cyclom-8Y above first megabyte
+ 0200 Cyclades-Z below first megabyte
+ 0201 Cyclades-Z above first megabyte
+ 0300 PC300/RSV or /X21 (2 ports)
+ 0301 PC300/RSV or /X21 (1 port)
+ 0310 PC300/TE (2 ports)
+ 0311 PC300/TE (1 port)
+ 0320 PC300/TE-M (2 ports)
+ 0321 PC300/TE-M (1 port)
+ 0400 PC400
+120f Essential Communications
+ 0001 Roadrunner serial HIPPI
+1210 Hyperparallel Technologies
+1211 Braintech Inc
+1212 Kingston Technology Corp.
+1213 Applied Intelligent Systems, Inc.
+1214 Performance Technologies, Inc.
+1215 Interware Co., Ltd
+1216 Purup Prepress A/S
+1217 O2 Micro, Inc.
+ 00f7 Firewire (IEEE 1394)
+ 6729 OZ6729
+ 673a OZ6730
+ 6832 OZ6832/6833 CardBus Controller
+ 6836 OZ6836/6860 CardBus Controller
+ 6872 OZ6812 CardBus Controller
+ 6925 OZ6922 CardBus Controller
+ 6933 OZ6933/711E1 CardBus/SmartCardBus Controller
+ 1025 1016 Travelmate 612 TX
+ 6972 OZ601/6912/711E0 CardBus/SmartCardBus Controller
+ 1014 020c ThinkPad R30
+ 1179 0001 Magnia Z310
+ 7110 OZ711Mx 4-in-1 MemoryCardBus Accelerator
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 1734 106c Amilo A1645
+ 7112 OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
+ 7113 OZ711EC1 SmartCardBus Controller
+ 7114 OZ711M1/MC1 4-in-1 MemoryCardBus Controller
+ 7120 Integrated MMC/SD Controller
+ 7130 Integrated MS/xD Controller
+ 7134 OZ711MP1/MS1 MemoryCardBus Controller
+ 7135 Cardbus bridge
+ 71e2 OZ711E2 SmartCardBus Controller
+ 7212 OZ711M2 4-in-1 MemoryCardBus Controller
+ 7213 OZ6933E CardBus Controller
+ 7223 OZ711M3/MC3 4-in-1 MemoryCardBus Controller
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 7233 OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
+1218 Hybricon Corp.
+1219 First Virtual Corporation
+121a 3Dfx Interactive, Inc.
+ 0001 Voodoo
+ 0002 Voodoo 2
+ 0003 Voodoo Banshee
+ 1092 0003 Monster Fusion
+ 1092 4000 Monster Fusion
+ 1092 4002 Monster Fusion
+ 1092 4801 Monster Fusion AGP
+ 1092 4803 Monster Fusion AGP
+ 1092 8030 Monster Fusion
+ 1092 8035 Monster Fusion AGP
+ 10b0 0001 Dragon 4000
+ 1102 1018 3D Blaster Banshee VE
+ 121a 0001 Voodoo Banshee AGP
+ 121a 0003 Voodoo Banshee AGP SGRAM
+ 121a 0004 Voodoo Banshee
+ 139c 0016 Raven
+ 139c 0017 Raven
+ 14af 0002 Maxi Gamer Phoenix
+ 0004 Voodoo Banshee [Velocity 100]
+ 0005 Voodoo 3
+ 121a 0004 Voodoo3 AGP
+ 121a 0030 Voodoo3 AGP
+ 121a 0031 Voodoo3 AGP
+ 121a 0034 Voodoo3 AGP
+ 121a 0036 Voodoo3 2000 PCI
+ 121a 0037 Voodoo3 AGP
+ 121a 0038 Voodoo3 AGP
+ 121a 003a Voodoo3 AGP
+ 121a 0044 Voodoo3
+ 121a 004b Velocity 100
+ 121a 004c Velocity 200
+ 121a 004d Voodoo3 AGP
+ 121a 004e Voodoo3 AGP
+ 121a 0051 Voodoo3 AGP
+ 121a 0052 Voodoo3 AGP
+ 121a 0057 Voodoo3 3000 PCI
+ 121a 0060 Voodoo3 3500 TV (NTSC)
+ 121a 0061 Voodoo3 3500 TV (PAL)
+ 121a 0062 Voodoo3 3500 TV (SECAM)
+ 0009 Voodoo 4 / Voodoo 5
+ 121a 0003 Voodoo5 PCI 5500
+ 121a 0009 Voodoo5 AGP 5500/6000
+ 0057 Voodoo 3/3000 [Avenger]
+121b Advanced Telecommunications Modules
+121c Nippon Texaco., Ltd
+121d Lippert Automationstechnik GmbH
+121e CSPI
+ 0201 Myrinet 2000 Scalable Cluster Interconnect
+121f Arcus Technology, Inc.
+1220 Ariel Corporation
+ 1220 AMCC 5933 TMS320C80 DSP/Imaging board
+1221 Contec Co., Ltd
+1222 Ancor Communications, Inc.
+1223 Artesyn Communication Products
+ 0003 PM/Link
+ 0004 PM/T1
+ 0005 PM/E1
+ 0008 PM/SLS
+ 0009 BajaSpan Resource Target
+ 000a BajaSpan Section 0
+ 000b BajaSpan Section 1
+ 000c BajaSpan Section 2
+ 000d BajaSpan Section 3
+ 000e PM/PPC
+1224 Interactive Images
+1225 Power I/O, Inc.
+1227 Tech-Source
+ 0006 Raptor GFX 8P
+ 0023 Raptor GFX [1100T]
+1228 Norsk Elektro Optikk A/S
+1229 Data Kinesis Inc.
+122a Integrated Telecom
+122b LG Industrial Systems Co., Ltd
+122c Sican GmbH
+122d Aztech System Ltd
+ 1206 368DSP
+ 1400 Trident PCI288-Q3DII (NX)
+ 50dc 3328 Audio
+ 122d 0001 3328 Audio
+ 80da 3328 Audio
+ 122d 0001 3328 Audio
+122e Xyratex
+122f Andrew Corporation
+1230 Fishcamp Engineering
+1231 Woodward McCoach, Inc.
+1232 GPT Limited
+1233 Bus-Tech, Inc.
+# Also Bochs uses this for virtual VGA...
+1234 Technical Corp.
+1235 Risq Modular Systems, Inc.
+1236 Sigma Designs Corporation
+ 0000 RealMagic64/GX
+ 6401 REALmagic 64/GX (SD 6425)
+1237 Alta Technology Corporation
+1238 Adtran
+1239 3DO Company
+123a Visicom Laboratories, Inc.
+123b Seeq Technology, Inc.
+123c Century Systems, Inc.
+123d Engineering Design Team, Inc.
+ 0000 EasyConnect 8/32
+ 0002 EasyConnect 8/64
+ 0003 EasyIO
+123e Simutech, Inc.
+123f C-Cube Microsystems
+ 00e4 MPEG
+ 8120 E4?
+ 11bd 0006 DV500 E4
+ 11bd 000a DV500 E4
+ 11bd 000f DV500 E4
+ 1809 0016 Emuzed MAUI-III PCI PVR FM TV
+ 8888 Cinemaster C 3.0 DVD Decoder
+ 1002 0001 Cinemaster C 3.0 DVD Decoder
+ 1002 0002 Cinemaster C 3.0 DVD Decoder
+ 1328 0001 Cinemaster C 3.0 DVD Decoder
+1240 Marathon Technologies Corp.
+1241 DSC Communications
+# Formerly Jaycor Networks, Inc.
+1242 JNI Corporation
+ 1560 JNIC-1560 PCI-X Fibre Channel Controller
+ 1242 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
+ 1242 656a FCX-6562 PCI-X Fibre Channel Adapter
+ 4643 FCI-1063 Fibre Channel Adapter
+ 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
+ 656a FCX-6562 PCI-X Fibre Channel Adapter
+1243 Delphax
+1244 AVM Audiovisuelles MKTG & Computer System GmbH
+ 0700 B1 ISDN
+ 0800 C4 ISDN
+ 0a00 A1 ISDN [Fritz]
+ 1244 0a00 FRITZ!Card ISDN Controller
+ 0e00 Fritz!PCI v2.0 ISDN
+ 1100 C2 ISDN
+ 1200 T1 ISDN
+ 2700 Fritz!Card DSL SL
+ 2900 Fritz!Card DSL v2.0
+1245 A.P.D., S.A.
+1246 Dipix Technologies, Inc.
+1247 Xylon Research, Inc.
+1248 Central Data Corporation
+1249 Samsung Electronics Co., Ltd.
+124a AEG Electrocom GmbH
+124b SBS/Greenspring Modular I/O
+ 0040 PCI-40A or cPCI-200 Quad IndustryPack carrier
+ 124b 9080 PCI9080 Bridge
+124c Solitron Technologies, Inc.
+124d Stallion Technologies, Inc.
+ 0000 EasyConnection 8/32
+ 0002 EasyConnection 8/64
+ 0003 EasyIO
+ 0004 EasyConnection/RA
+124e Cylink
+124f Infortrend Technology, Inc.
+ 0041 IFT-2000 Series RAID Controller
+1250 Hitachi Microcomputer System Ltd
+1251 VLSI Solutions Oy
+1253 Guzik Technical Enterprises
+1254 Linear Systems Ltd.
+1255 Optibase Ltd
+ 1110 MPEG Forge
+ 1210 MPEG Fusion
+ 2110 VideoPlex
+ 2120 VideoPlex CC
+ 2130 VideoQuest
+1256 Perceptive Solutions, Inc.
+ 4201 PCI-2220I
+ 4401 PCI-2240I
+ 5201 PCI-2000
+1257 Vertex Networks, Inc.
+1258 Gilbarco, Inc.
+1259 Allied Telesyn International
+ 2560 AT-2560 Fast Ethernet Adapter (i82557B)
+ a117 RTL81xx Fast Ethernet
+ a120 21x4x DEC-Tulip compatible 10/100 Ethernet
+125a ABB Power Systems
+125b Asix Electronics Corporation
+ 1400 ALFA GFC2204 Fast Ethernet
+ 1186 1100 AX8814X Based PCI Fast Ethernet Adapter
+125c Aurora Technologies, Inc.
+ 0101 Saturn 4520P
+ 0640 Aries 16000P
+125d ESS Technology
+ 0000 ES336H Fax Modem (Early Model)
+ 1948 Solo?
+ 1968 ES1968 Maestro 2
+ 1028 0085 ES1968 Maestro-2 PCI
+ 1033 8051 ES1968 Maestro-2 Audiodrive
+ 1969 ES1969 Solo-1 Audiodrive
+ 1014 0166 ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
+ 125d 8888 Solo-1 Audio Adapter
+ 153b 111b Terratec 128i PCI
+ 1978 ES1978 Maestro 2E
+ 0e11 b112 Armada M700/E500
+ 1033 803c ES1978 Maestro-2E Audiodrive
+ 1033 8058 ES1978 Maestro-2E Audiodrive
+ 1092 4000 Monster Sound MX400
+ 1179 0001 ES1978 Maestro-2E Audiodrive
+ 1988 ES1988 Allegro-1
+ 0e11 0098 Evo N600c
+ 1092 4100 Sonic Impact S100
+ 125d 1988 ESS Allegro-1 Audiodrive
+ 1989 ESS Modem
+ 125d 1989 ESS Modem
+ 1998 ES1983S Maestro-3i PCI Audio Accelerator
+ 1028 00b1 Latitude C600
+ 1028 00e6 ES1983S Maestro-3i (Dell Inspiron 8100)
+ 1999 ES1983S Maestro-3i PCI Modem Accelerator
+ 199a ES1983S Maestro-3i PCI Audio Accelerator
+ 199b ES1983S Maestro-3i PCI Modem Accelerator
+ 2808 ES336H Fax Modem (Later Model)
+ 2838 ES2838/2839 SuperLink Modem
+ 2898 ES2898 Modem
+ 125d 0424 ES56-PI Data Fax Modem
+ 125d 0425 ES56T-PI Data Fax Modem
+ 125d 0426 ES56V-PI Data Fax Modem
+ 125d 0427 VW-PI Data Fax Modem
+ 125d 0428 ES56ST-PI Data Fax Modem
+ 125d 0429 ES56SV-PI Data Fax Modem
+ 147a c001 ES56-PI Data Fax Modem
+ 14fe 0428 ES56-PI Data Fax Modem
+ 14fe 0429 ES56-PI Data Fax Modem
+125e Specialvideo Engineering SRL
+125f Concurrent Technologies, Inc.
+1260 Intersil Corporation
+ 3872 Prism 2.5 Wavelan chipset
+ 1468 0202 LAN-Express IEEE 802.11b Wireless LAN
+ 3873 Prism 2.5 Wavelan chipset
+ 1186 3501 DWL-520 Wireless PCI Adapter
+ 1186 3700 DWL-520 Wireless PCI Adapter, Rev E1
+ 1385 4105 MA311 802.11b wireless adapter
+ 1668 0414 HWP01170-01 802.11b PCI Wireless Adapter
+ 16a5 1601 AIR.mate PC-400 PCI Wireless LAN Adapter
+ 1737 3874 WMP11 Wireless 802.11b PCI Adapter
+ 8086 2513 Wireless 802.11b MiniPCI Adapter
+ 3886 ISL3886 [Prism Javelin/Prism Xbow]
+ 17cf 0037 XG-901 and clones Wireless Adapter
+ 3890 ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow]
+ 10b8 2802 SMC2802W Wireless PCI Adapter
+ 10b8 2835 SMC2835W Wireless Cardbus Adapter
+ 10b8 a835 SMC2835W V2 Wireless Cardbus Adapter
+ 1113 4203 WN4201B
+ 1113 ee03 SMC2802W V2 Wireless PCI Adapter [ISL3886]
+ 1113 ee08 SMC2835W V3 EU Wireless Cardbus Adapter
+ 1186 3202 DWL-G650 A1 Wireless Adapter
+ 1259 c104 CG-WLCB54GT Wireless Adapter
+ 1385 4800 WG511 Wireless Adapter
+ 16a5 1605 ALLNET ALL0271 Wireless PCI Adapter
+ 17cf 0014 XG-600 and clones Wireless Adapter
+ 17cf 0020 XG-900 and clones Wireless Adapter
+ 8130 HMP8130 NTSC/PAL Video Decoder
+ 8131 HMP8131 NTSC/PAL Video Decoder
+# This is probably more likely a HW fault, but I am keeping it for now --mj
+ ffff ISL3886IK
+ 1260 0000 Senao 3054MP+ (J) mini-PCI WLAN 802.11g adapter
+1261 Matsushita-Kotobuki Electronics Industries, Ltd.
+1262 ES Computer Company, Ltd.
+1263 Sonic Solutions
+1264 Aval Nagasaki Corporation
+1265 Casio Computer Co., Ltd.
+1266 Microdyne Corporation
+ 0001 NE10/100 Adapter (i82557B)
+ 1910 NE2000Plus (RT8029) Ethernet Adapter
+ 1266 1910 NE2000Plus Ethernet Adapter
+1267 S. A. Telecommunications
+ 5352 PCR2101
+ 5a4b Telsat Turbo
+1268 Tektronix
+1269 Thomson-CSF/TTM
+126a Lexmark International, Inc.
+126b Adax, Inc.
+126c Northern Telecom
+ 1211 10/100BaseTX [RTL81xx]
+ 126c 802.11b Wireless Ethernet Adapter
+126d Splash Technology, Inc.
+126e Sumitomo Metal Industries, Ltd.
+126f Silicon Motion, Inc.
+ 0501 SM501 VoyagerGX Rev. AA
+ 0510 SM501 VoyagerGX Rev. B
+ 0710 SM710 LynxEM
+ 0712 SM712 LynxEM+
+ 0720 SM720 Lynx3DM
+ 0730 SM731 Cougar3DR
+ 0810 SM810 LynxE
+ 0811 SM811 LynxE
+ 0820 SM820 Lynx3D
+ 0910 SM910
+1270 Olympus Optical Co., Ltd.
+1271 GW Instruments
+1272 Telematics International
+1273 Hughes Network Systems
+ 0002 DirecPC
+1274 Ensoniq
+ 1171 ES1373 [AudioPCI] (also Creative Labs CT5803)
+ 1371 ES1371 [AudioPCI-97]
+ 0e11 0024 AudioPCI on Motherboard Compaq Deskpro
+ 0e11 b1a7 ES1371, ES1373 AudioPCI
+ 1033 80ac ES1371, ES1373 AudioPCI
+ 1042 1854 Tazer
+ 107b 8054 Tabor2
+ 1274 1371 Creative Sound Blaster AudioPCI64V, AudioPCI128
+ 1274 8001 CT4751 board
+ 1462 6470 ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
+ 1462 6560 ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
+ 1462 6630 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
+ 1462 6631 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
+ 1462 6632 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
+ 1462 6633 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
+ 1462 6820 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
+ 1462 6822 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
+ 1462 6830 ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
+ 1462 6880 ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
+ 1462 6900 ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
+ 1462 6910 ES1371, ES1373 AudioPCI On Motherboard MS-6191
+ 1462 6930 ES1371, ES1373 AudioPCI On Motherboard MS-6193
+ 1462 6990 ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
+ 1462 6991 ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
+ 14a4 2077 ES1371, ES1373 AudioPCI On Motherboard KR639
+ 14a4 2105 ES1371, ES1373 AudioPCI On Motherboard MR800
+ 14a4 2107 ES1371, ES1373 AudioPCI On Motherboard MR801
+ 14a4 2172 ES1371, ES1373 AudioPCI On Motherboard DR739
+ 1509 9902 ES1371, ES1373 AudioPCI On Motherboard KW11
+ 1509 9903 ES1371, ES1373 AudioPCI On Motherboard KW31
+ 1509 9904 ES1371, ES1373 AudioPCI On Motherboard KA11
+ 1509 9905 ES1371, ES1373 AudioPCI On Motherboard KC13
+ 152d 8801 ES1371, ES1373 AudioPCI On Motherboard CP810E
+ 152d 8802 ES1371, ES1373 AudioPCI On Motherboard CP810
+ 152d 8803 ES1371, ES1373 AudioPCI On Motherboard P3810E
+ 152d 8804 ES1371, ES1373 AudioPCI On Motherboard P3810-S
+ 152d 8805 ES1371, ES1373 AudioPCI On Motherboard P3820-S
+ 270f 2001 ES1371, ES1373 AudioPCI On Motherboard 6CTR
+ 270f 2200 ES1371, ES1373 AudioPCI On Motherboard 6WTX
+ 270f 3000 ES1371, ES1373 AudioPCI On Motherboard 6WSV
+ 270f 3100 ES1371, ES1373 AudioPCI On Motherboard 6WIV2
+ 270f 3102 ES1371, ES1373 AudioPCI On Motherboard 6WIV
+ 270f 7060 ES1371, ES1373 AudioPCI On Motherboard 6ASA2
+ 8086 4249 ES1371, ES1373 AudioPCI On Motherboard BI440ZX
+ 8086 424c ES1371, ES1373 AudioPCI On Motherboard BL440ZX
+ 8086 425a ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
+ 8086 4341 ES1371, ES1373 AudioPCI On Motherboard Cayman
+ 8086 4343 ES1371, ES1373 AudioPCI On Motherboard Cape Cod
+ 8086 4541 D815EEA Motherboard
+ 8086 4649 ES1371, ES1373 AudioPCI On Motherboard Fire Island
+ 8086 464a ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
+ 8086 4d4f ES1371, ES1373 AudioPCI On Motherboard Montreal
+ 8086 4f43 ES1371, ES1373 AudioPCI On Motherboard OC440LX
+ 8086 5243 ES1371, ES1373 AudioPCI On Motherboard RC440BX
+ 8086 5352 ES1371, ES1373 AudioPCI On Motherboard SunRiver
+ 8086 5643 ES1371, ES1373 AudioPCI On Motherboard Vancouver
+ 8086 5753 ES1371, ES1373 AudioPCI On Motherboard WS440BX
+ 5000 ES1370 [AudioPCI]
+ 5880 5880 AudioPCI
+ 1274 2000 Creative Sound Blaster AudioPCI128
+ 1274 2003 Creative SoundBlaster AudioPCI 128
+ 1274 5880 Creative Sound Blaster AudioPCI128
+ 1274 8001 Sound Blaster 16PCI 4.1ch
+ 1458 a000 5880 AudioPCI On Motherboard 6OXET
+ 1462 6880 5880 AudioPCI On Motherboard MS-6188 1.00
+ 270f 2001 5880 AudioPCI On Motherboard 6CTR
+ 270f 2200 5880 AudioPCI On Motherboard 6WTX
+ 270f 7040 5880 AudioPCI On Motherboard 6ATA4
+1275 Network Appliance Corporation
+1276 Switched Network Technologies, Inc.
+1277 Comstream
+1278 Transtech Parallel Systems Ltd.
+ 0701 TPE3/TM3 PowerPC Node
+ 0710 TPE5 PowerPC PCI board
+1279 Transmeta Corporation
+ 0060 TM8000 Northbridge
+ 0061 TM8000 AGP bridge
+ 0295 Northbridge
+ 0395 LongRun Northbridge
+ 0396 SDRAM controller
+ 0397 BIOS scratchpad
+127a Rockwell International
+ 1002 HCF 56k Data/Fax Modem
+ 1092 094c SupraExpress 56i PRO [Diamond SUP2380]
+ 122d 4002 HPG / MDP3858-U
+ 122d 4005 MDP3858-E
+ 122d 4007 MDP3858-A/-NZ
+ 122d 4012 MDP3858-SA
+ 122d 4017 MDP3858-W
+ 122d 4018 MDP3858-W
+ 127a 1002 Rockwell 56K D/F HCF Modem
+ 1003 HCF 56k Data/Fax Modem
+ 0e11 b0bc 229-DF Zephyr
+ 0e11 b114 229-DF Cheetah
+ 1033 802b 229-DF
+ 13df 1003 PCI56RX Modem
+ 13e0 0117 IBM
+ 13e0 0147 IBM F-1156IV+/R3 Spain V.90 Modem
+ 13e0 0197 IBM
+ 13e0 01c7 IBM F-1156IV+/R3 WW V.90 Modem
+ 13e0 01f7 IBM
+ 1436 1003 IBM
+ 1436 1103 IBM 5614PM3G V.90 Modem
+ 1436 1602 Compaq 229-DF Ducati
+ 1004 HCF 56k Data/Fax/Voice Modem
+ 1048 1500 MicroLink 56k Modem
+ 10cf 1059 Fujitsu 229-DFRT
+ 1005 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1005 127a AOpen FM56-P
+ 1033 8029 229-DFSV
+ 1033 8054 Modem
+ 10cf 103c Fujitsu
+ 10cf 1055 Fujitsu 229-DFSV
+ 10cf 1056 Fujitsu 229-DFSV
+ 122d 4003 MDP3858SP-U
+ 122d 4006 Packard Bell MDP3858V-E
+ 122d 4008 MDP3858SP-A/SP-NZ
+ 122d 4009 MDP3858SP-E
+ 122d 4010 MDP3858V-U
+ 122d 4011 MDP3858SP-SA
+ 122d 4013 MDP3858V-A/V-NZ
+ 122d 4015 MDP3858SP-W
+ 122d 4016 MDP3858V-W
+ 122d 4019 MDP3858V-SA
+ 13df 1005 PCI56RVP Modem
+ 13e0 0187 IBM
+ 13e0 01a7 IBM
+ 13e0 01b7 IBM DF-1156IV+/R3 Spain V.90 Modem
+ 13e0 01d7 IBM DF-1156IV+/R3 WW V.90 Modem
+ 1436 1005 IBM
+ 1436 1105 IBM
+ 1437 1105 IBM 5614PS3G V.90 Modem
+ 1022 HCF 56k Modem
+ 1436 1303 M3-5614PM3G V.90 Modem
+ 1023 HCF 56k Data/Fax Modem
+ 122d 4020 Packard Bell MDP3858-WE
+ 122d 4023 MDP3858-UE
+ 13e0 0247 IBM F-1156IV+/R6 Spain V.90 Modem
+ 13e0 0297 IBM
+ 13e0 02c7 IBM F-1156IV+/R6 WW V.90 Modem
+ 1436 1203 IBM
+ 1436 1303 IBM
+ 1024 HCF 56k Data/Fax/Voice Modem
+ 1025 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 10cf 106a Fujitsu 235-DFSV
+ 122d 4021 Packard Bell MDP3858V-WE
+ 122d 4022 MDP3858SP-WE
+ 122d 4024 MDP3858V-UE
+ 122d 4025 MDP3858SP-UE
+ 1026 HCF 56k PCI Speakerphone Modem
+ 1032 HCF 56k Modem
+ 1033 HCF 56k Modem
+ 1034 HCF 56k Modem
+ 1035 HCF 56k PCI Speakerphone Modem
+ 1036 HCF 56k Modem
+ 1085 HCF 56k Volcano PCI Modem
+ 2005 HCF 56k Data/Fax Modem
+ 104d 8044 229-DFSV
+ 104d 8045 229-DFSV
+ 104d 8055 PBE/Aztech 235W-DFSV
+ 104d 8056 235-DFSV
+ 104d 805a Modem
+ 104d 805f Modem
+ 104d 8074 Modem
+ 2013 HSF 56k Data/Fax Modem
+ 1179 0001 Modem
+ 1179 ff00 Modem
+ 2014 HSF 56k Data/Fax/Voice Modem
+ 10cf 1057 Fujitsu Citicorp III
+ 122d 4050 MSP3880-U
+ 122d 4055 MSP3880-W
+ 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 10cf 1063 Fujitsu
+ 10cf 1064 Fujitsu
+ 1468 2015 Fujitsu
+ 2016 HSF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4051 MSP3880V-W
+ 122d 4052 MSP3880SP-W
+ 122d 4054 MSP3880V-U
+ 122d 4056 MSP3880SP-U
+ 122d 4057 MSP3880SP-A
+ 4311 Riptide HSF 56k PCI Modem
+ 127a 4311 Ring Modular? Riptide HSF RT HP Dom
+ 13e0 0210 HP-GVC
+ 4320 Riptide PCI Audio Controller
+ 1235 4320 Riptide PCI Audio Controller
+ 4321 Riptide HCF 56k PCI Modem
+ 1235 4321 Hewlett Packard DF
+ 1235 4324 Hewlett Packard DF
+ 13e0 0210 Hewlett Packard DF
+ 144d 2321 Riptide
+ 4322 Riptide PCI Game Controller
+ 1235 4322 Riptide PCI Game Controller
+ 8234 RapidFire 616X ATM155 Adapter
+ 108d 0022 RapidFire 616X ATM155 Adapter
+ 108d 0027 RapidFire 616X ATM155 Adapter
+127b Pixera Corporation
+127c Crosspoint Solutions, Inc.
+127d Vela Research
+127e Winnov, L.P.
+127f Fujifilm
+1280 Photoscript Group Ltd.
+1281 Yokogawa Electric Corporation
+1282 Davicom Semiconductor, Inc.
+ 9009 Ethernet 100/10 MBit
+ 9100 21x4x DEC-Tulip compatible 10/100 Ethernet
+ 9102 21x4x DEC-Tulip compatible 10/100 Ethernet
+ 9132 Ethernet 100/10 MBit
+1283 Integrated Technology Express, Inc.
+ 673a IT8330G
+ 8211 ITE 8211F Single Channel UDMA 133 (ASUS 8211 (ITE IT8212 ATA RAID Controller))
+ 1043 8138 P5GD1-VW Mainboard
+ 8212 IT/ITE8212 Dual channel ATA RAID controller (PCI version seems to be IT8212, embedded seems to be ITE8212)
+ 1283 0001 IT/ITE8212 Dual channel ATA RAID controller
+ 8330 IT8330G
+ 8872 IT8874F PCI Dual Serial Port Controller
+ 8888 IT8888F PCI to ISA Bridge with SMB
+ 8889 IT8889F PCI to ISA Bridge
+ e886 IT8330G
+1284 Sahara Networks, Inc.
+1285 Platform Technologies, Inc.
+ 0100 AGOGO sound chip (aka ESS Maestro 1)
+1286 Mazet GmbH
+1287 M-Pact, Inc.
+ 001e LS220D DVD Decoder
+ 001f LS220C DVD Decoder
+1288 Timestep Corporation
+1289 AVC Technology, Inc.
+128a Asante Technologies, Inc.
+128b Transwitch Corporation
+128c Retix Corporation
+128d G2 Networks, Inc.
+ 0021 ATM155 Adapter
+128e Hoontech Corporation/Samho Multi Tech Ltd.
+ 0008 ST128 WSS/SB
+ 0009 ST128 SAM9407
+ 000a ST128 Game Port
+ 000b ST128 MPU Port
+ 000c ST128 Ctrl Port
+128f Tateno Dennou, Inc.
+1290 Sord Computer Corporation
+1291 NCS Computer Italia
+1292 Tritech Microelectronics Inc
+1293 Media Reality Technology
+1294 Rhetorex, Inc.
+1295 Imagenation Corporation
+1296 Kofax Image Products
+1297 Holco Enterprise Co, Ltd/Shuttle Computer
+1298 Spellcaster Telecommunications Inc.
+1299 Knowledge Technology Lab.
+129a VMetro, inc.
+ 0615 PBT-615 PCI-X Bus Analyzer
+129b Image Access
+129c Jaycor
+129d Compcore Multimedia, Inc.
+129e Victor Company of Japan, Ltd.
+129f OEC Medical Systems, Inc.
+12a0 Allen-Bradley Company
+12a1 Simpact Associates, Inc.
+12a2 Newgen Systems Corporation
+12a3 Lucent Technologies
+ 8105 T8105 H100 Digital Switch
+12a4 NTT Electronics Technology Company
+12a5 Vision Dynamics Ltd.
+12a6 Scalable Networks, Inc.
+12a7 AMO GmbH
+12a8 News Datacom
+12a9 Xiotech Corporation
+12aa SDL Communications, Inc.
+12ab Yuan Yuan Enterprise Co., Ltd.
+ 0002 AU8830 [Vortex2] Based Sound Card With A3D Support
+ 3000 MPG-200C PCI DVD Decoder Card
+12ac Measurex Corporation
+12ad Multidata GmbH
+12ae Alteon Networks Inc.
+ 0001 AceNIC Gigabit Ethernet
+ 1014 0104 Gigabit Ethernet-SX PCI Adapter
+ 12ae 0001 Gigabit Ethernet-SX (Universal)
+ 1410 0104 Gigabit Ethernet-SX PCI Adapter
+ 0002 AceNIC Gigabit Ethernet (Copper)
+ 10a9 8002 Acenic Gigabit Ethernet
+ 12ae 0002 Gigabit Ethernet-T (3C986-T)
+ 00fa Farallon PN9100-T Gigabit Ethernet
+12af TDK USA Corp
+12b0 Jorge Scientific Corp
+12b1 GammaLink
+12b2 General Signal Networks
+12b3 Inter-Face Co Ltd
+12b4 FutureTel Inc
+12b5 Granite Systems Inc.
+12b6 Natural Microsystems
+12b7 Cognex Modular Vision Systems Div. - Acumen Inc.
+12b8 Korg
+# Nee US Robotics
+12b9 3Com Corp, Modem Division
+ 1006 WinModem
+ 12b9 005c USR 56k Internal Voice WinModem (Model 3472)
+ 12b9 005e USR 56k Internal WinModem (Models 662975)
+ 12b9 0062 USR 56k Internal Voice WinModem (Model 662978)
+ 12b9 0068 USR 56k Internal Voice WinModem (Model 5690)
+ 12b9 007a USR 56k Internal Voice WinModem (Model 662974)
+ 12b9 007f USR 56k Internal WinModem (Models 5698, 5699)
+ 12b9 0080 USR 56k Internal WinModem (Models 2975, 3528)
+ 12b9 0081 USR 56k Internal Voice WinModem (Models 2974, 3529)
+ 12b9 0091 USR 56k Internal Voice WinModem (Model 2978)
+ 1007 USR 56k Internal WinModem
+ 12b9 00a3 USR 56k Internal WinModem (Model 3595)
+ 12b9 00c4 U.S. Robotics 56K Voice Win Int (2884a)
+ 1008 56K FaxModem Model 5610
+ 12b9 00a2 USR 56k Internal FAX Modem (Model 2977)
+ 12b9 00aa USR 56k Internal Voice Modem (Model 2976)
+ 12b9 00ab USR 56k Internal Voice Modem (Model 5609)
+ 12b9 00ac USR 56k Internal Voice Modem (Model 3298)
+ 12b9 00ad USR 56k Internal FAX Modem (Model 5610)
+12ba BittWare, Inc.
+12bb Nippon Unisoft Corporation
+12bc Array Microsystems
+12bd Computerm Corp.
+12be Anchor Chips Inc.
+ 3041 AN3041Q CO-MEM
+ 3042 AN3042Q CO-MEM Lite
+ 12be 3042 Anchor Chips Lite Evaluation Board
+12bf Fujifilm Microdevices
+12c0 Infimed
+12c1 GMM Research Corp
+12c2 Mentec Limited
+12c3 Holtek Microelectronics Inc
+ 0058 PCI NE2K Ethernet
+ 5598 PCI NE2K Ethernet
+12c4 Connect Tech Inc
+ 0001 Blue HEAT/PCI 8 (RS232/CL/RJ11)
+ 0002 Blue HEAT/PCI 4 (RS232)
+ 0003 Blue HEAT/PCI 2 (RS232)
+ 0004 Blue HEAT/PCI 8 (UNIV, RS485)
+ 0005 Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485)
+ 0006 Blue HEAT/PCI 4 (OPTO, RS485)
+ 0007 Blue HEAT/PCI 2+2 (RS232/485)
+ 0008 Blue HEAT/PCI 2 (OPTO, Tx, RS485)
+ 0009 Blue HEAT/PCI 2+6 (RS232/485)
+ 000a Blue HEAT/PCI 8 (Tx, RS485)
+ 000b Blue HEAT/PCI 4 (Tx, RS485)
+ 000c Blue HEAT/PCI 2 (20 MHz, RS485)
+ 000d Blue HEAT/PCI 2 PTM
+ 0100 NT960/PCI
+ 0201 cPCI Titan - 2 Port
+ 0202 cPCI Titan - 4 Port
+ 0300 CTI PCI UART 2 (RS232)
+ 0301 CTI PCI UART 4 (RS232)
+ 0302 CTI PCI UART 8 (RS232)
+ 0310 CTI PCI UART 1+1 (RS232/485)
+ 0311 CTI PCI UART 2+2 (RS232/485)
+ 0312 CTI PCI UART 4+4 (RS232/485)
+ 0320 CTI PCI UART 2
+ 0321 CTI PCI UART 4
+ 0322 CTI PCI UART 8
+ 0330 CTI PCI UART 2 (RS485)
+ 0331 CTI PCI UART 4 (RS485)
+ 0332 CTI PCI UART 8 (RS485)
+12c5 Picture Elements Incorporated
+ 007e Imaging/Scanning Subsystem Engine
+ 007f Imaging/Scanning Subsystem Engine
+ 0081 PCIVST [Grayscale Thresholding Engine]
+ 0085 Video Simulator/Sender
+ 0086 THR2 Multi-scale Thresholder
+12c6 Mitani Corporation
+12c7 Dialogic Corp
+12c8 G Force Co, Ltd
+12c9 Gigi Operations
+12ca Integrated Computing Engines
+12cb Antex Electronics Corporation
+12cc Pluto Technologies International
+12cd Aims Lab
+12ce Netspeed Inc.
+12cf Prophet Systems, Inc.
+12d0 GDE Systems, Inc.
+12d1 PSITech
+12d2 NVidia / SGS Thomson (Joint Venture)
+ 0008 NV1
+ 0009 DAC64
+ 0018 Riva128
+ 1048 0c10 VICTORY Erazor
+ 107b 8030 STB Velocity 128
+ 1092 0350 Viper V330
+ 1092 1092 Viper V330
+ 10b4 1b1b STB Velocity 128
+ 10b4 1b1d STB Velocity 128
+ 10b4 1b1e STB Velocity 128, PAL TV-Out
+ 10b4 1b20 STB Velocity 128 Sapphire
+ 10b4 1b21 STB Velocity 128
+ 10b4 1b22 STB Velocity 128 AGP, NTSC TV-Out
+ 10b4 1b23 STB Velocity 128 AGP, PAL TV-Out
+ 10b4 1b27 STB Velocity 128 DVD
+ 10b4 1b88 MVP Pro 128
+ 10b4 222a STB Velocity 128 AGP
+ 10b4 2230 STB Velocity 128
+ 10b4 2232 STB Velocity 128
+ 10b4 2235 STB Velocity 128 AGP
+ 2a15 54a3 3DVision-SAGP / 3DexPlorer 3000
+ 0019 Riva128ZX
+ 0020 TNT
+ 0028 TNT2
+ 0029 UTNT2
+ 002c VTNT2
+ 00a0 ITNT2
+12d3 Vingmed Sound A/S
+12d4 Ulticom (Formerly DGM&S)
+ 0200 T1 Card
+12d5 Equator Technologies Inc
+ 0003 BSP16
+ 1000 BSP15
+12d6 Analogic Corp
+12d7 Biotronic SRL
+12d8 Pericom Semiconductor
+ 8150 PCI to PCI Bridge
+12d9 Aculab PLC
+ 0002 PCI Prosody
+ 0004 cPCI Prosody
+ 0005 Aculab E1/T1 PCI card
+ 1078 Prosody X class e1000 device
+ 12d9 000d Prosody X PCI
+12da True Time Inc.
+12db Annapolis Micro Systems, Inc
+12dc Symicron Computer Communication Ltd.
+12dd Management Graphics
+12de Rainbow Technologies
+ 0200 CryptoSwift CS200
+12df SBS Technologies Inc
+12e0 Chase Research
+ 0010 ST16C654 Quad UART
+ 0020 ST16C654 Quad UART
+ 0030 ST16C654 Quad UART
+12e1 Nintendo Co, Ltd
+12e2 Datum Inc. Bancomm-Timing Division
+12e3 Imation Corp - Medical Imaging Systems
+12e4 Brooktrout Technology Inc
+12e5 Apex Semiconductor Inc
+12e6 Cirel Systems
+12e7 Sunsgroup Corporation
+12e8 Crisc Corp
+12e9 GE Spacenet
+12ea Zuken
+12eb Aureal Semiconductor
+ 0001 Vortex 1
+ 104d 8036 AU8820 Vortex Digital Audio Processor
+ 1092 2000 Sonic Impact A3D
+ 1092 2100 Sonic Impact A3D
+ 1092 2110 Sonic Impact A3D
+ 1092 2200 Sonic Impact A3D
+ 122d 1002 AU8820 Vortex Digital Audio Processor
+ 12eb 0001 AU8820 Vortex Digital Audio Processor
+ 5053 3355 Montego
+ 0002 Vortex 2
+ 104d 8049 AU8830 Vortex 3D Digital Audio Processor
+ 104d 807b AU8830 Vortex 3D Digital Audio Processor
+ 1092 3000 Monster Sound II
+ 1092 3001 Monster Sound II
+ 1092 3002 Monster Sound II
+ 1092 3003 Monster Sound II
+ 1092 3004 Monster Sound II
+ 12eb 0002 AU8830 Vortex 3D Digital Audio Processor
+ 12eb 0088 AU8830 Vortex 3D Digital Audio Processor
+ 144d 3510 AU8830 Vortex 3D Digital Audio Processor
+ 5053 3356 Montego II
+ 0003 AU8810 Vortex Digital Audio Processor
+ 104d 8049 AU8810 Vortex Digital Audio Processor
+ 104d 8077 AU8810 Vortex Digital Audio Processor
+ 109f 1000 AU8810 Vortex Digital Audio Processor
+ 12eb 0003 AU8810 Vortex Digital Audio Processor
+ 1462 6780 AU8810 Vortex Digital Audio Processor
+ 14a4 2073 AU8810 Vortex Digital Audio Processor
+ 14a4 2091 AU8810 Vortex Digital Audio Processor
+ 14a4 2104 AU8810 Vortex Digital Audio Processor
+ 14a4 2106 AU8810 Vortex Digital Audio Processor
+ 8803 Vortex 56k Software Modem
+ 12eb 8803 Vortex 56k Software Modem
+12ec 3A International, Inc.
+12ed Optivision Inc.
+12ee Orange Micro
+12ef Vienna Systems
+12f0 Pentek
+12f1 Sorenson Vision Inc
+12f2 Gammagraphx, Inc.
+12f3 Radstone Technology
+12f4 Megatel
+12f5 Forks
+12f6 Dawson France
+12f7 Cognex
+12f8 Electronic Design GmbH
+ 0002 VideoMaker
+12f9 Four Fold Ltd
+12fb Spectrum Signal Processing
+ 0001 PMC-MAI
+ 00f5 F5 Dakar
+ 02ad PMC-2MAI
+ 2adc ePMC-2ADC
+ 3100 PRO-3100
+ 3500 PRO-3500
+ 4d4f Modena
+ 8120 ePMC-8120
+ da62 Daytona C6201 PCI (Hurricane)
+ db62 Ingliston XBIF
+ dc62 Ingliston PLX9054
+ dd62 Ingliston JTAG/ISP
+ eddc ePMC-MSDDC
+ fa01 ePMC-FPGA
+12fc Capital Equipment Corp
+12fd I2S
+12fe ESD Electronic System Design GmbH
+12ff Lexicon
+1300 Harman International Industries Inc
+1302 Computer Sciences Corp
+1303 Innovative Integration
+1304 Juniper Networks
+1305 Netphone, Inc
+1306 Duet Technologies
+# Nee ComputerBoards
+1307 Measurement Computing
+ 0001 PCI-DAS1602/16
+ 000b PCI-DIO48H
+ 000c PCI-PDISO8
+ 000d PCI-PDISO16
+ 000f PCI-DAS1200
+ 0010 PCI-DAS1602/12
+ 0014 PCI-DIO24H
+ 0015 PCI-DIO24H/CTR3
+ 0016 PCI-DIO48H/CTR15
+ 0017 PCI-DIO96H
+ 0018 PCI-CTR05
+ 0019 PCI-DAS1200/JR
+ 001a PCI-DAS1001
+ 001b PCI-DAS1002
+ 001c PCI-DAS1602JR/16
+ 001d PCI-DAS6402/16
+ 001e PCI-DAS6402/12
+ 001f PCI-DAS16/M1
+ 0020 PCI-DDA02/12
+ 0021 PCI-DDA04/12
+ 0022 PCI-DDA08/12
+ 0023 PCI-DDA02/16
+ 0024 PCI-DDA04/16
+ 0025 PCI-DDA08/16
+ 0026 PCI-DAC04/12-HS
+ 0027 PCI-DAC04/16-HS
+ 0028 PCI-DIO24
+ 0029 PCI-DAS08
+ 002c PCI-INT32
+ 0033 PCI-DUAL-AC5
+ 0034 PCI-DAS-TC
+ 0035 PCI-DAS64/M1/16
+ 0036 PCI-DAS64/M2/16
+ 0037 PCI-DAS64/M3/16
+ 004c PCI-DAS1000
+ 004d PCI-QUAD04
+ 0052 PCI-DAS4020/12
+ 0054 PCI-DIO96
+ 005e PCI-DAS6025
+1308 Jato Technologies Inc.
+ 0001 NetCelerator Adapter
+ 1308 0001 NetCelerator Adapter
+1309 AB Semiconductor Ltd
+130a Mitsubishi Electric Microcomputer
+130b Colorgraphic Communications Corp
+130c Ambex Technologies, Inc
+130d Accelerix Inc
+130e Yamatake-Honeywell Co. Ltd
+130f Advanet Inc
+1310 Gespac
+1311 Videoserver, Inc
+1312 Acuity Imaging, Inc
+1313 Yaskawa Electric Co.
+1316 Teradyne Inc
+1317 ADMtek
+ 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
+ 0985 NC100 Network Everywhere Fast Ethernet 10/100
+ 1734 100c Scenic N300 ADMtek AN983 10/100 Mbps PCI Adapter
+ 1985 21x4x DEC-Tulip compatible 10/100 Ethernet
+ 2850 HSP MicroModem 56
+ 5120 ADM5120 OpenGate System-on-Chip
+ 8201 ADM8211 802.11b Wireless Interface
+ 10b8 2635 SMC2635W 802.11b (11Mbps) wireless lan pcmcia (cardbus) card
+ 1317 8201 SMC2635W 802.11b (11mbps) wireless lan pcmcia (cardbus) card
+ 8211 ADM8211 802.11b Wireless Interface
+ 9511 21x4x DEC-Tulip compatible 10/100 Ethernet
+1318 Packet Engines Inc.
+ 0911 GNIC-II PCI Gigabit Ethernet [Hamachi]
+1319 Fortemedia, Inc
+ 0801 Xwave QS3000A [FM801]
+ 1319 1319 FM801 PCI Audio
+ 0802 Xwave QS3000A [FM801 game port]
+ 1319 1319 FM801 PCI Joystick
+ 1000 FM801 PCI Audio
+ 1001 FM801 PCI Joystick
+131a Finisar Corp.
+131c Nippon Electro-Sensory Devices Corp
+131d Sysmic, Inc.
+131e Xinex Networks Inc
+131f Siig Inc
+ 1000 CyberSerial (1-port) 16550
+ 1001 CyberSerial (1-port) 16650
+ 1002 CyberSerial (1-port) 16850
+ 1010 Duet 1S(16550)+1P
+ 1011 Duet 1S(16650)+1P
+ 1012 Duet 1S(16850)+1P
+ 1020 CyberParallel (1-port)
+ 1021 CyberParallel (2-port)
+ 1030 CyberSerial (2-port) 16550
+ 1031 CyberSerial (2-port) 16650
+ 1032 CyberSerial (2-port) 16850
+ 1034 Trio 2S(16550)+1P
+ 1035 Trio 2S(16650)+1P
+ 1036 Trio 2S(16850)+1P
+ 1050 CyberSerial (4-port) 16550
+ 1051 CyberSerial (4-port) 16650
+ 1052 CyberSerial (4-port) 16850
+ 2000 CyberSerial (1-port) 16550
+ 2001 CyberSerial (1-port) 16650
+ 2002 CyberSerial (1-port) 16850
+ 2010 Duet 1S(16550)+1P
+ 2011 Duet 1S(16650)+1P
+ 2012 Duet 1S(16850)+1P
+ 2020 CyberParallel (1-port)
+ 2021 CyberParallel (2-port)
+ 2030 CyberSerial (2-port) 16550
+ 131f 2030 PCI Serial Card
+ 2031 CyberSerial (2-port) 16650
+ 2032 CyberSerial (2-port) 16850
+ 2040 Trio 1S(16550)+2P
+ 2041 Trio 1S(16650)+2P
+ 2042 Trio 1S(16850)+2P
+ 2050 CyberSerial (4-port) 16550
+ 2051 CyberSerial (4-port) 16650
+ 2052 CyberSerial (4-port) 16850
+ 2060 Trio 2S(16550)+1P
+ 2061 Trio 2S(16650)+1P
+ 2062 Trio 2S(16850)+1P
+ 2081 CyberSerial (8-port) ST16654
+1320 Crypto AG
+1321 Arcobel Graphics BV
+1322 MTT Co., Ltd
+1323 Dome Inc
+1324 Sphere Communications
+1325 Salix Technologies, Inc
+1326 Seachange international
+1327 Voss scientific
+1328 quadrant international
+1329 Productivity Enhancement
+132a Microcom Inc.
+132b Broadband Technologies
+132c Micrel Inc
+132d Integrated Silicon Solution, Inc.
+1330 MMC Networks
+1331 Radisys Corp.
+ 0030 ENP-2611
+ 8200 82600 Host Bridge
+ 8201 82600 IDE
+ 8202 82600 USB
+ 8210 82600 PCI Bridge
+1332 Micro Memory
+ 5415 MM-5415CN PCI Memory Module with Battery Backup
+ 5425 MM-5425CN PCI 64/66 Memory Module with Battery Backup
+ 6140 MM-6140D
+1334 Redcreek Communications, Inc
+1335 Videomail, Inc
+1337 Third Planet Publishing
+1338 BT Electronics
+133a Vtel Corp
+133b Softcom Microsystems
+133c Holontech Corp
+133d SS Technologies
+133e Virtual Computer Corp
+133f SCM Microsystems
+1340 Atalla Corp
+1341 Kyoto Microcomputer Co
+1342 Promax Systems Inc
+1343 Phylon Communications Inc
+1344 Crucial Technology
+1345 Arescom Inc
+1347 Odetics
+1349 Sumitomo Electric Industries, Ltd.
+134a DTC Technology Corp.
+ 0001 Domex 536
+ 0002 Domex DMX3194UP SCSI Adapter
+134b ARK Research Corp.
+134c Chori Joho System Co. Ltd
+134d PCTel Inc
+ 2189 HSP56 MicroModem
+ 2486 2304WT V.92 MDC Modem
+ 7890 HSP MicroModem 56
+ 134d 0001 PCT789 adapter
+ 7891 HSP MicroModem 56
+ 134d 0001 HSP MicroModem 56
+ 7892 HSP MicroModem 56
+ 7893 HSP MicroModem 56
+ 7894 HSP MicroModem 56
+ 7895 HSP MicroModem 56
+ 7896 HSP MicroModem 56
+ 7897 HSP MicroModem 56
+134e CSTI
+134f Algo System Co Ltd
+1350 Systec Co. Ltd
+1351 Sonix Inc
+1353 Thales Idatys
+ 0002 Proserver
+ 0003 PCI-FUT
+ 0004 PCI-S0
+ 0005 PCI-FUT-S0
+1354 Dwave System Inc
+1355 Kratos Analytical Ltd
+1356 The Logical Co
+1359 Prisa Networks
+135a Brain Boxes
+135b Giganet Inc
+135c Quatech Inc
+ 0010 QSC-100
+ 0020 DSC-100
+ 0030 DSC-200/300
+ 0040 QSC-200/300
+ 0050 ESC-100D
+ 0060 ESC-100M
+ 00f0 MPAC-100 Syncronous Serial Card (Zilog 85230)
+ 0170 QSCLP-100
+ 0180 DSCLP-100
+ 0190 SSCLP-100
+ 01a0 QSCLP-200/300
+ 01b0 DSCLP-200/300
+ 01c0 SSCLP-200/300
+135d ABB Network Partner AB
+135e Sealevel Systems Inc
+ 5101 Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32)
+ 7101 Single Port RS-232/422/485/530
+ 7201 Dual Port RS-232/422/485 Interface
+ 7202 Dual Port RS-232 Interface
+ 7401 Four Port RS-232 Interface
+ 7402 Four Port RS-422/485 Interface
+ 7801 Eight Port RS-232 Interface
+ 7804 Eight Port RS-232/422/485 Interface
+ 8001 8001 Digital I/O Adapter
+135f I-Data International A-S
+1360 Meinberg Funkuhren
+ 0101 PCI32 DCF77 Radio Clock
+ 0102 PCI509 DCF77 Radio Clock
+ 0103 PCI510 DCF77 Radio Clock
+ 0104 PCI511 DCF77 Radio Clock
+ 0201 GPS167PCI GPS Receiver
+ 0202 GPS168PCI GPS Receiver
+ 0203 GPS169PCI GPS Receiver
+ 0204 GPS170PCI GPS Receiver
+ 0301 TCR510PCI IRIG Timecode Reader
+ 0302 TCR167PCI IRIG Timecode Reader
+ 0303 TCR511PCI IRIG Timecode Reader
+1361 Soliton Systems K.K.
+1362 Fujifacom Corporation
+1363 Phoenix Technology Ltd
+1364 ATM Communications Inc
+1365 Hypercope GmbH
+1366 Teijin Seiki Co. Ltd
+1367 Hitachi Zosen Corporation
+1368 Skyware Corporation
+1369 Digigram
+136a High Soft Tech
+ 0004 HST Saphir VII mini PCI
+136b Kawasaki Steel Corporation
+ ff01 KL5A72002 Motion JPEG
+136c Adtek System Science Co Ltd
+136d Gigalabs Inc
+136f Applied Magic Inc
+1370 ATL Products
+1371 CNet Technology Inc
+ 434e GigaCard Network Adapter
+ 1371 434e N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
+1373 Silicon Vision Inc
+1374 Silicom Ltd.
+ 0024 Silicom Dual port Giga Ethernet BGE Bypass Server Adapter
+ 0025 Silicom Quad port Giga Ethernet BGE Bypass Server Adapter
+ 0026 Silicom Dual port Fiber Giga Ethernet 546 Bypass Server Adapter
+ 0027 Silicom Dual port Fiber LX Giga Ethernet 546 Bypass Server Adapter
+ 0029 Silicom Dual port Copper Giga Ethernet 546GB Bypass Server Adapter
+ 002a Silicom Dual port Fiber Giga Ethernet 546 TAP/Bypass Server Adapter
+ 002b Silicom Dual port Copper Fast Ethernet 546 TAP/Bypass Server Adapter (PXE2TBI)
+ 002c Silicom Quad port Copper Giga Ethernet 546GB Bypass Server Adapter (PXG4BPI)
+ 002d Silicom Quad port Fiber-SX Giga Ethernet 546GB Bypass Server Adapter (PXG4BPFI)
+ 002e Silicom Quad port Fiber-LX Giga Ethernet 546GB Bypass Server Adapter (PXG4BPFI-LX)
+ 002f Silicom Dual port Fiber-SX Giga Ethernet 546GB Low profile Bypass Server Adapter (PXG2BPFIL)
+ 0030 Silicom Dual port Fiber-LX Giga Ethernet 546GB Low profile Bypass Server Adapter
+ 0031 Silicom Quad port Copper Giga Ethernet PCI-E Bypass Server Adapter
+ 0032 Silicom Dual port Copper Fast Ethernet 546 TAP/Bypass Server Adapter
+ 0034 Silicom Dual port Copper Giga Ethernet PCI-E BGE Bypass Server Adapter
+ 0035 Silicom Quad port Copper Giga Ethernet PCI-E BGE Bypass Server Adapter
+ 0036 Silicom Dual port Fiber Giga Ethernet PCI-E BGE Bypass Server Adapter
+ 0037 Silicom Quad port Copper Ethernet PCI-E Intel based Bypass Server Adapter
+ 0038 Silicom Quad port Copper Ethernet PCI-E Intel based Bypass Server Adapter
+ 0039 Silicom Dual port Fiber-SX Ethernet PCI-E Intel based Bypass Server Adapter
+ 003a Silicom Dual port Fiber-LX Ethernet PCI-E Intel based Bypass Server Adapter
+1375 Argosystems Inc
+1376 LMC
+1377 Electronic Equipment Production & Distribution GmbH
+1378 Telemann Co. Ltd
+1379 Asahi Kasei Microsystems Co Ltd
+137a Mark of the Unicorn Inc
+ 0001 PCI-324 Audiowire Interface
+137b PPT Vision
+137c Iwatsu Electric Co Ltd
+137d Dynachip Corporation
+137e Patriot Scientific Corporation
+137f Japan Satellite Systems Inc
+1380 Sanritz Automation Co Ltd
+1381 Brains Co. Ltd
+1382 Marian - Electronic & Software
+ 0001 ARC88 audio recording card
+ 2008 Prodif 96 Pro sound system
+ 2048 Prodif Plus sound system
+ 2088 Marc 8 Midi sound system
+ 20c8 Marc A sound system
+ 4008 Marc 2 sound system
+ 4010 Marc 2 Pro sound system
+ 4048 Marc 4 MIDI sound system
+ 4088 Marc 4 Digi sound system
+ 4248 Marc X sound system
+ 4424 TRACE D4 Sound System
+1383 Controlnet Inc
+1384 Reality Simulation Systems Inc
+1385 Netgear
+ 0013 WG311T 108 Mbps Wireless PCI Adapter
+ 311a GA511 Gigabit Ethernet
+ 4100 802.11b Wireless Adapter (MA301)
+ 4105 MA311 802.11b wireless adapter
+ 4251 WG111T 108 Mbps Wireless USB 2.0 Adapter
+ 4400 WAG511 802.11a/b/g Dual Band Wireless PC Card
+ 4600 WAG511 802.11a/b/g Dual Band Wireless PC Card
+ 4601 WAG511 802.11a/b/g Dual Band Wireless PC Card
+ 4610 WAG511 802.11a/b/g Dual Band Wireless PC Card
+ 4800 WG511(v1) 54 Mbps Wireless PC Card
+ 4900 WG311v1 54 Mbps Wireless PCI Adapter
+ 4a00 WAG311 802.11a/g Wireless PCI Adapter
+ 4b00 WG511T 108 Mbps Wireless PC Card
+ 4c00 WG311v2 54 Mbps Wireless PCI Adapter
+ 4d00 WG311T 108 Mbps Wireless PCI Adapter
+ 4e00 WG511v2 54 Mbps Wireless PC Card
+ 4f00 WG511U Double 108 Mbps Wireless PC Card
+ 5200 GA511 Gigabit PC Card
+ 620a GA620 Gigabit Ethernet
+ 622a GA622
+ 630a GA630 Gigabit Ethernet
+ 6b00 WG311v3 54 Mbps Wireless PCI Adapter
+ 6d00 WPNT511 RangeMax 240 Mbps Wireless PC Card
+ 7b00 WN511B RangeMax Next 280 Mbps Wireless PC Card
+ 7c00 WN511T RangeMax Next 300 Mbps Wireless PC Card
+ f004 FA310TX
+1386 Video Domain Technologies
+1387 Systran Corp
+1388 Hitachi Information Technology Co Ltd
+1389 Applicom International
+ 0001 PCI1500PFB [Intelligent fieldbus adaptor]
+138a Fusion Micromedia Corp
+138b Tokimec Inc
+138c Silicon Reality
+138d Future Techno Designs pte Ltd
+138e Basler GmbH
+138f Patapsco Designs Inc
+1390 Concept Development Inc
+1391 Development Concepts Inc
+1392 Medialight Inc
+1393 Moxa Technologies Co Ltd
+ 1040 Smartio C104H/PCI
+ 1141 Industrio CP-114
+ 1680 Smartio C168H/PCI
+ 2040 Intellio CP-204J
+ 2180 Intellio C218 Turbo PCI
+ 3200 Intellio C320 Turbo PCI
+1394 Level One Communications
+ 0001 LXT1001 Gigabit Ethernet
+ 1394 0001 NetCelerator Adapter
+1395 Ambicom Inc
+1396 Cipher Systems Inc
+1397 Cologne Chip Designs GmbH
+ 08b4 ISDN network Controller [HFC-4S]
+ 1397 b520 HFC-4S [IOB4ST]
+ 1397 b540 HFC-4S [Swyx 4xS0 SX2 QuadBri]
+ 16b8 ISDN network Controller [HFC-8S]
+ 2bd0 ISDN network controller [HFC-PCI]
+ 0675 1704 ISDN Adapter (PCI Bus, D, C)
+ 0675 1708 ISDN Adapter (PCI Bus, D, C, ACPI)
+ 1397 2bd0 ISDN Board
+ e4bf 1000 CI1-1-Harp
+1398 Clarion co. Ltd
+1399 Rios systems Co Ltd
+139a Alacritech Inc
+ 0001 Quad Port 10/100 Server Accelerator
+ 0003 Single Port 10/100 Server Accelerator
+ 0005 Single Port Gigabit Server Accelerator
+139b Mediasonic Multimedia Systems Ltd
+139c Quantum 3d Inc
+139d EPL limited
+139e Media4
+139f Aethra s.r.l.
+13a0 Crystal Group Inc
+13a1 Kawasaki Heavy Industries Ltd
+13a2 Ositech Communications Inc
+13a3 Hifn Inc.
+ 0005 7751 Security Processor
+ 0006 6500 Public Key Processor
+ 0007 7811 Security Processor
+ 0012 7951 Security Processor
+ 0014 78XX Security Processor
+ 0016 8065 Security Processor
+ 0017 8165 Security Processor
+ 0018 8154 Security Processor
+ 001d 7956 Security Processor
+ 0020 7955 Security Processor
+ 0026 8155 Security Processor
+13a4 Rascom Inc
+13a5 Audio Digital Imaging Inc
+13a6 Videonics Inc
+13a7 Teles AG
+13a8 Exar Corp.
+ 0152 XR17C/D152 Dual PCI UART
+ 0154 XR17C154 Quad UART
+ 0158 XR17C158 Octal UART
+13a9 Siemens Medical Systems, Ultrasound Group
+13aa Broadband Networks Inc
+13ab Arcom Control Systems Ltd
+13ac Motion Media Technology Ltd
+13ad Nexus Inc
+13ae ALD Technology Ltd
+13af T.Sqware
+13b0 Maxspeed Corp
+13b1 Tamura corporation
+13b2 Techno Chips Co. Ltd
+13b3 Lanart Corporation
+13b4 Wellbean Co Inc
+13b5 ARM
+13b6 Dlog GmbH
+13b7 Logic Devices Inc
+13b8 Nokia Telecommunications oy
+13b9 Elecom Co Ltd
+13ba Oxford Instruments
+13bb Sanyo Technosound Co Ltd
+13bc Bitran Corporation
+13bd Sharp corporation
+13be Miroku Jyoho Service Co. Ltd
+13bf Sharewave Inc
+13c0 Microgate Corporation
+ 0010 SyncLink Adapter v1
+ 0020 SyncLink SCC Adapter
+ 0030 SyncLink Multiport Adapter
+ 0210 SyncLink Adapter v2
+13c1 3ware Inc
+ 1000 5xxx/6xxx-series PATA-RAID
+ 1001 7xxx/8xxx-series PATA/SATA-RAID
+ 13c1 1001 7xxx/8xxx-series PATA/SATA-RAID
+ 1002 9xxx-series SATA-RAID
+ 1003 9550SX SATA-RAID
+13c2 Technotrend Systemtechnik GmbH
+ 000e Technotrend/Hauppauge DVB card rev2.3
+13c3 Janz Computer AG
+13c4 Phase Metrics
+13c5 Alphi Technology Corp
+13c6 Condor Engineering Inc
+ 0520 CEI-520 A429 Card
+ 0620 CEI-620 A429 Card
+ 0820 CEI-820 A429 Card
+13c7 Blue Chip Technology Ltd
+13c8 Apptech Inc
+13c9 Eaton Corporation
+13ca Iomega Corporation
+13cb Yano Electric Co Ltd
+13cc Metheus Corporation
+13cd Compatible Systems Corporation
+13ce Cocom A/S
+13cf Studio Audio & Video Ltd
+13d0 Techsan Electronics Co Ltd
+ 2103 B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card
+ 2200 B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card
+13d1 Abocom Systems Inc
+ ab02 ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
+ ab03 21x4x DEC-Tulip compatible 10/100 Ethernet
+ ab06 RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
+ ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
+13d2 Shark Multimedia Inc
+13d3 IMC Networks
+13d4 Graphics Microsystems Inc
+13d5 Media 100 Inc
+13d6 K.I. Technology Co Ltd
+13d7 Toshiba Engineering Corporation
+13d8 Phobos corporation
+13d9 Apex PC Solutions Inc
+13da Intresource Systems pte Ltd
+13db Janich & Klass Computertechnik GmbH
+13dc Netboost Corporation
+13dd Multimedia Bundle Inc
+13de ABB Robotics Products AB
+13df E-Tech Inc
+ 0001 PCI56RVP Modem
+ 13df 0001 PCI56RVP Modem
+13e0 GVC Corporation
+13e1 Silicom Multimedia Systems Inc
+13e2 Dynamics Research Corporation
+13e3 Nest Inc
+13e4 Calculex Inc
+13e5 Telesoft Design Ltd
+13e6 Argosy research Inc
+13e7 NAC Incorporated
+13e8 Chip Express Corporation
+13e9 Intraserver Technology Inc
+13ea Dallas Semiconductor
+13eb Hauppauge Computer Works Inc
+13ec Zydacron Inc
+ 000a NPC-RC01 Remote control receiver
+13ed Raytheion E-Systems
+13ee Hayes Microcomputer Products Inc
+13ef Coppercom Inc
+13f0 Sundance Technology Inc / IC Plus Corp
+ 0200 IC Plus IP100A Integrated 10/100 Ethernet MAC + PHY
+ 0201 ST201 Sundance Ethernet
+ 1023 IC Plus IP1000 Family Gigabit Ethernet
+13f1 Oce' - Technologies B.V.
+13f2 Ford Microelectronics Inc
+13f3 Mcdata Corporation
+13f4 Troika Networks, Inc.
+ 1401 Zentai Fibre Channel Adapter
+13f5 Kansai Electric Co. Ltd
+13f6 C-Media Electronics Inc
+ 0011 CMI8738
+ 0100 CM8338A
+ 13f6 ffff CMI8338/C3DX PCI Audio Device
+ 0101 CM8338B
+ 13f6 0101 CMI8338-031 PCI Audio Device
+ 0111 CM8738
+ 1019 0970 P6STP-FL motherboard
+ 1043 8035 CUSI-FX motherboard
+ 1043 8077 CMI8738 6-channel audio controller
+ 1043 80e2 CMI8738 6ch-MX
+ 13f6 0111 CMI8738/C3DX PCI Audio Device
+ 1681 a000 Gamesurround MUSE XL
+ 0211 CM8738
+13f7 Wildfire Communications
+13f8 Ad Lib Multimedia Inc
+13f9 NTT Advanced Technology Corp.
+13fa Pentland Systems Ltd
+13fb Aydin Corp
+13fc Computer Peripherals International
+13fd Micro Science Inc
+13fe Advantech Co. Ltd
+ 1240 PCI-1240 4-channel stepper motor controller card
+ 1600 PCI-1612 4-port RS-232/422/485 PCI communication card
+ 1733 PCI-1733 32-channel isolated digital input card
+ 1752 PCI-1752
+ 1754 PCI-1754
+ 1756 PCI-1756
+13ff Silicon Spice Inc
+1400 Artx Inc
+ 1401 9432 TX
+1401 CR-Systems A/S
+1402 Meilhaus Electronic GmbH
+1403 Ascor Inc
+1404 Fundamental Software Inc
+1405 Excalibur Systems Inc
+1406 Oce' Printing Systems GmbH
+1407 Lava Computer mfg Inc
+ 0100 Lava Dual Serial
+ 0101 Lava Quatro A
+ 0102 Lava Quatro B
+ 0110 Lava DSerial-PCI Port A
+ 0111 Lava DSerial-PCI Port B
+ 0120 Quattro-PCI A
+ 0121 Quattro-PCI B
+ 0180 Lava Octo A
+ 0181 Lava Octo B
+ 0200 Lava Port Plus
+ 0201 Lava Quad A
+ 0202 Lava Quad B
+ 0220 Lava Quattro PCI Ports A/B
+ 0221 Lava Quattro PCI Ports C/D
+ 0500 Lava Single Serial
+ 0600 Lava Port 650
+ 8000 Lava Parallel
+ 8001 Dual parallel port controller A
+ 8002 Lava Dual Parallel port A
+ 8003 Lava Dual Parallel port B
+ 8800 BOCA Research IOPPAR
+1408 Aloka Co. Ltd
+1409 Timedia Technology Co Ltd
+ 7168 PCI2S550 (Dual 16550 UART)
+140a DSP Research Inc
+140b Ramix Inc
+140c Elmic Systems Inc
+140d Matsushita Electric Works Ltd
+140e Goepel Electronic GmbH
+140f Salient Systems Corp
+1410 Midas lab Inc
+1411 Ikos Systems Inc
+# Nee IC Ensemble Inc.
+1412 VIA Technologies Inc.
+ 1712 ICE1712 [Envy24] PCI Multi-Channel I/O Controller
+ 1412 1712 Hoontech ST Audio DSP 24
+ 1412 d630 M-Audio Delta 1010
+ 1412 d631 M-Audio Delta DiO
+ 1412 d632 M-Audio Delta 66
+ 1412 d633 M-Audio Delta 44
+ 1412 d634 M-Audio Delta Audiophile
+ 1412 d635 M-Audio Delta TDIF
+ 1412 d637 M-Audio Delta RBUS
+ 1412 d638 M-Audio Delta 410
+ 1412 d63b M-Audio Delta 1010LT
+ 1412 d63c Digigram VX442
+ 1416 1712 Hoontech ST Audio DSP 24 Media 7.1
+ 153b 1115 EWS88 MT
+ 153b 1125 EWS88 MT (Master)
+ 153b 112b EWS88 D
+ 153b 112c EWS88 D (Master)
+ 153b 1130 EWX 24/96
+ 153b 1138 DMX 6fire 24/96
+ 153b 1151 PHASE88
+ 16ce 1040 Edirol DA-2496
+ 1724 VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
+ 1412 1724 Albatron PX865PE 7.1
+ 1412 3630 M-Audio Revolution 7.1
+ 1412 3631 M-Audio Revolution 5.1
+ 153b 1145 Aureon 7.1 Space
+ 153b 1147 Aureon 5.1 Sky
+ 153b 1153 Aureon 7.1 Universe
+ 270f f641 ZNF3-150
+ 270f f645 ZNF3-250
+1413 Addonics
+1414 Microsoft Corporation
+1415 Oxford Semiconductor Ltd
+ 8403 VScom 011H-EP1 1 port parallel adaptor
+ 9500 OX16PCI954 (Quad 16950 UART) function 0 (Disabled)
+ 9501 OX16PCI954 (Quad 16950 UART) function 0 (Uart)
+ 12c4 0202 Titan/cPCI (4 port)
+ 12c4 0203 Titan/cPCI (8 port)
+ 12c4 0210 Titan/104-Plus (8 port, p1-4)
+ 131f 2050 CyberPro (4-port)
+# Model IO1085, Part No: JJ-P46012
+ 131f 2051 CyberSerial 4S Plus
+ 15ed 2000 MCCR Serial p0-3 of 8
+ 15ed 2001 MCCR Serial p0-3 of 16
+ 950a EXSYS EX-41092 Dual 16950 Serial adapter
+ 950b OXCB950 Cardbus 16950 UART
+ 9510 OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
+ 12c4 0200 Titan/cPCI (Unused)
+ 9511 OX16PCI954 (Quad 16950 UART) function 1 (8bit bus)
+ 12c4 0211 Titan/104-Plus (8 port, p5-8)
+ 15ed 2000 MCCR Serial p4-7 of 8
+ 15ed 2001 MCCR Serial p4-15 of 16
+ 9512 OX16PCI954 (Quad 16950 UART) function 1 (32bit bus)
+ 9513 OX16PCI954 (Quad 16950 UART) function 1 (parallel port)
+ 9521 OX16PCI952 (Dual 16950 UART)
+ 9523 OX16PCI952 Integrated Parallel Port
+1416 Multiwave Innovation pte Ltd
+1417 Convergenet Technologies Inc
+1418 Kyushu electronics systems Inc
+1419 Excel Switching Corp
+141a Apache Micro Peripherals Inc
+141b Zoom Telephonics Inc
+141d Digitan Systems Inc
+141e Fanuc Ltd
+141f Visiontech Ltd
+1420 Psion Dacom plc
+ 8002 Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part)
+ 8003 Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part)
+1421 Ads Technologies Inc
+1422 Ygrec Systems Co Ltd
+1423 Custom Technology Corp.
+1424 Videoserver Connections
+1425 Chelsio Communications Inc
+ 000b T210 Protocol Engine
+1426 Storage Technology Corp.
+1427 Better On-Line Solutions
+1428 Edec Co Ltd
+1429 Unex Technology Corp.
+142a Kingmax Technology Inc
+142b Radiolan
+142c Minton Optic Industry Co Ltd
+142d Pix stream Inc
+142e Vitec Multimedia
+ 4020 VM2-2 [Video Maker 2] MPEG1/2 Encoder
+ 4337 VM2-2-C7 [Video Maker 2 rev. C7] MPEG1/2 Encoder
+142f Radicom Research Inc
+1430 ITT Aerospace/Communications Division
+1431 Gilat Satellite Networks
+1432 Edimax Computer Co.
+ 9130 RTL81xx Fast Ethernet
+1433 Eltec Elektronik GmbH
+# Nee Real Time Devices US Inc.
+1435 RTD Embedded Technologies, Inc.
+1436 CIS Technology Inc
+1437 Nissin Inc Co
+1438 Atmel-dream
+1439 Outsource Engineering & Mfg. Inc
+143a Stargate Solutions Inc
+143b Canon Research Center, America
+143c Amlogic Inc
+143d Tamarack Microelectronics Inc
+143e Jones Futurex Inc
+143f Lightwell Co Ltd - Zax Division
+1440 ALGOL Corp.
+1441 AGIE Ltd
+1442 Phoenix Contact GmbH & Co.
+1443 Unibrain S.A.
+1444 TRW
+1445 Logical DO Ltd
+1446 Graphin Co Ltd
+1447 AIM GmBH
+1448 Alesis Studio Electronics
+1449 TUT Systems Inc
+144a Adlink Technology
+ 7296 PCI-7296
+ 7432 PCI-7432
+ 7433 PCI-7433
+ 7434 PCI-7434
+ 7841 PCI-7841
+ 8133 PCI-8133
+ 8164 PCI-8164
+ 8554 PCI-8554
+ 9111 PCI-9111
+ 9113 PCI-9113
+ 9114 PCI-9114
+144b Loronix Information Systems Inc
+144c Catalina Research Inc
+144d Samsung Electronics Co Ltd
+ c00c P35 laptop
+144e OLITEC
+144f Askey Computer Corp.
+1450 Octave Communications Ind.
+1451 SP3D Chip Design GmBH
+1453 MYCOM Inc
+1454 Altiga Networks
+1455 Logic Plus Plus Inc
+1456 Advanced Hardware Architectures
+1457 Nuera Communications Inc
+1458 Giga-byte Technology
+ 0c11 K8NS Pro Mainboard
+ e911 GN-WIAG02
+1459 DOOIN Electronics
+145a Escalate Networks Inc
+145b PRAIM SRL
+145c Cryptek
+145d Gallant Computer Inc
+145e Aashima Technology B.V.
+145f Baldor Electric Company
+ 0001 NextMove PCI
+1460 DYNARC INC
+1461 Avermedia Technologies Inc
+ f436 AVerTV Hybrid+FM
+1462 Micro-Star International Co., Ltd.
+ 5501 nVidia NV15DDR [GeForce2 Ti]
+# MSI CB54G Wireless PC Card that seems to use the Broadcom 4306 Chipset
+ 6819 Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G]
+ 6825 PCI Card wireless 11g [PC54G]
+ 6834 RaLink RT2500 802.11g [PC54G2]
+ 7125 K8N motherboard
+ 8725 NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter
+ 9000 NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter
+ 9110 GeFORCE FX5200
+ 9119 NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter
+ 9123 NVIDIA NV31 [GeForce FX 5600] FX5600-VTDR128 [MS-8912]
+ 9510 Radeon 9600XT
+ 9511 Radeon 9600XT
+ 9591 nVidia Corporation NV36 [GeForce FX 5700LE]
+1463 Fast Corporation
+1464 Interactive Circuits & Systems Ltd
+1465 GN NETTEST Telecom DIV.
+1466 Designpro Inc.
+1467 DIGICOM SPA
+1468 AMBIT Microsystem Corp.
+1469 Cleveland Motion Controls
+146a IFR
+146b Parascan Technologies Ltd
+146c Ruby Tech Corp.
+ 1430 FE-1430TX Fast Ethernet PCI Adapter
+146d Tachyon, INC.
+146e Williams Electronics Games, Inc.
+146f Multi Dimensional Consulting Inc
+1470 Bay Networks
+1471 Integrated Telecom Express Inc
+1472 DAIKIN Industries, Ltd
+1473 ZAPEX Technologies Inc
+1474 Doug Carson & Associates
+1475 PICAZO Communications
+1476 MORTARA Instrument Inc
+1477 Net Insight
+1478 DIATREND Corporation
+1479 TORAY Industries Inc
+147a FORMOSA Industrial Computing
+147b ABIT Computer Corp.
+147c AWARE, Inc.
+147d Interworks Computer Products
+147e Matsushita Graphic Communication Systems, Inc.
+147f NIHON UNISYS, Ltd.
+1480 SCII Telecom
+1481 BIOPAC Systems Inc
+1482 ISYTEC - Integrierte Systemtechnik GmBH
+1483 LABWAY Corporation
+1484 Logic Corporation
+1485 ERMA - Electronic GmBH
+1486 L3 Communications Telemetry & Instrumentation
+1487 MARQUETTE Medical Systems
+1488 KONTRON Electronik GmBH
+1489 KYE Systems Corporation
+148a OPTO
+148b INNOMEDIALOGIC Inc.
+148c C.P. Technology Co. Ltd
+148d DIGICOM Systems, Inc.
+ 1003 HCF 56k Data/Fax Modem
+148e OSI Plus Corporation
+148f Plant Equipment, Inc.
+1490 Stone Microsystems PTY Ltd.
+1491 ZEAL Corporation
+1492 Time Logic Corporation
+1493 MAKER Communications
+1494 WINTOP Technology, Inc.
+1495 TOKAI Communications Industry Co. Ltd
+1496 JOYTECH Computer Co., Ltd.
+1497 SMA Regelsysteme GmBH
+ 1497 SMA Technologie AG
+1498 TEWS Datentechnik GmBH
+ 0330 TPMC816 2 Channel CAN bus controller.
+ 0385 TPMC901 Extended CAN bus with 2/4/6 CAN controller
+ 21cc TCP460 CompactPCI 16 Channel Serial Interface RS232/RS422
+ 21cd TCP461 CompactPCI 8 Channel Serial Interface RS232/RS422
+ 30c8 TPCI200
+1499 EMTEC CO., Ltd
+149a ANDOR Technology Ltd
+149b SEIKO Instruments Inc
+149c OVISLINK Corp.
+149d NEWTEK Inc
+ 0001 Video Toaster for PC
+149e Mapletree Networks Inc.
+149f LECTRON Co Ltd
+14a0 SOFTING GmBH
+14a1 Systembase Co Ltd
+14a2 Millennium Engineering Inc
+14a3 Maverick Networks
+14a4 GVC/BCM Advanced Research
+14a5 XIONICS Document Technologies Inc
+14a6 INOVA Computers GmBH & Co KG
+14a7 MYTHOS Systems Inc
+14a8 FEATRON Technologies Corporation
+14a9 HIVERTEC Inc
+14aa Advanced MOS Technology Inc
+14ab Mentor Graphics Corp.
+14ac Novaweb Technologies Inc
+14ad Time Space Radio AB
+14ae CTI, Inc
+14af Guillemot Corporation
+ 7102 3D Prophet II MX
+14b0 BST Communication Technology Ltd
+14b1 Nextcom K.K.
+14b2 ENNOVATE Networks Inc
+14b3 XPEED Inc
+ 0000 DSL NIC
+14b4 PHILIPS Business Electronics B.V.
+14b5 Creamware GmBH
+ 0200 Scope
+ 0300 Pulsar
+ 0400 PulsarSRB
+ 0600 Pulsar2
+ 0800 DSP-Board
+ 0900 DSP-Board
+ 0a00 DSP-Board
+ 0b00 DSP-Board
+14b6 Quantum Data Corp.
+14b7 PROXIM Inc
+ 0001 Symphony 4110
+14b8 Techsoft Technology Co Ltd
+14b9 AIRONET Wireless Communications
+ 0001 PC4800
+ 0340 PC4800
+ 0350 PC4800
+ 4500 PC4500
+ 4800 Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800
+ a504 Cisco Aironet Wireless 802.11b
+ a505 Cisco Aironet CB20a 802.11a Wireless LAN Adapter
+ a506 Cisco Aironet Mini PCI b/g
+14ba INTERNIX Inc.
+14bb SEMTECH Corporation
+14bc Globespan Semiconductor Inc.
+14bd CARDIO Control N.V.
+14be L3 Communications
+14bf SPIDER Communications Inc.
+14c0 COMPAL Electronics Inc
+14c1 MYRICOM Inc.
+ 0008 Myri-10G Dual-Protocol NIC (10G-PCIE-8A)
+ 8043 Myrinet 2000 Scalable Cluster Interconnect
+ 103c 1240 Myrinet M2L-PCI64/2-3.0 LANai 7.4 (HP OEM)
+14c2 DTK Computer
+14c3 MEDIATEK Corp.
+14c4 IWASAKI Information Systems Co Ltd
+14c5 Automation Products AB
+14c6 Data Race Inc
+14c7 Modular Technology Holdings Ltd
+14c8 Turbocomm Tech. Inc.
+14c9 ODIN Telesystems Inc
+14ca PE Logic Corp.
+14cb Billionton Systems Inc
+14cc NAKAYO Telecommunications Inc
+14cd Universal Scientific Ind.
+14ce Whistle Communications
+14cf TEK Microsystems Inc.
+14d0 Ericsson Axe R & D
+14d1 Computer Hi-Tech Co Ltd
+14d2 Titan Electronics Inc
+ 8001 VScom 010L 1 port parallel adaptor
+ 8002 VScom 020L 2 port parallel adaptor
+ 8010 VScom 100L 1 port serial adaptor
+ 8011 VScom 110L 1 port serial and 1 port parallel adaptor
+ 8020 VScom 200L 1 port serial adaptor
+ 8021 VScom 210L 2 port serial and 1 port parallel adaptor
+ 8040 VScom 400L 4 port serial adaptor
+ 8080 VScom 800L 8 port serial adaptor
+ a000 VScom 010H 1 port parallel adaptor
+ a001 VScom 100H 1 port serial adaptor
+ a003 VScom 400H 4 port serial adaptor
+ a004 VScom 400HF1 4 port serial adaptor
+ a005 VScom 200H 2 port serial adaptor
+ e001 VScom 010HV2 1 port parallel adaptor
+ e010 VScom 100HV2 1 port serial adaptor
+ e020 VScom 200HV2 2 port serial adaptor
+14d3 CIRTECH (UK) Ltd
+14d4 Panacom Technology Corp
+14d5 Nitsuko Corporation
+14d6 Accusys Inc
+14d7 Hirakawa Hewtech Corp
+14d8 HOPF Elektronik GmBH
+# Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc.
+14d9 Alliance Semiconductor Corporation
+ 0010 AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
+ 9000 AS90L10204/10208 HyperTransport to PCI-X Bridge
+14da National Aerospace Laboratories
+14db AFAVLAB Technology Inc
+ 2120 TK9902
+ 2182 AFAVLAB Technology Inc. 8-port serial card
+14dc Amplicon Liveline Ltd
+ 0000 PCI230
+ 0001 PCI242
+ 0002 PCI244
+ 0003 PCI247
+ 0004 PCI248
+ 0005 PCI249
+ 0006 PCI260
+ 0007 PCI224
+ 0008 PCI234
+ 0009 PCI236
+ 000a PCI272
+ 000b PCI215
+14dd Boulder Design Labs Inc
+14de Applied Integration Corporation
+14df ASIC Communications Corp
+14e1 INVERTEX
+14e2 INFOLIBRIA
+14e3 AMTELCO
+14e4 Broadcom Corporation
+ 0800 Sentry5 Chipcommon I/O Controller
+ 0804 Sentry5 PCI Bridge
+ 0805 Sentry5 MIPS32 CPU
+ 0806 Sentry5 Ethernet Controller
+ 080b Sentry5 Crypto Accelerator
+ 080f Sentry5 DDR/SDR RAM Controller
+ 0811 Sentry5 External Interface Core
+ 0816 BCM3302 Sentry5 MIPS32 CPU
+ 1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express
+ 107b 5048 E4500 Onboard
+ 1601 NetXtreme BCM5752M Gigabit Ethernet PCI Express
+ 1644 NetXtreme BCM5700 Gigabit Ethernet
+ 1014 0277 Broadcom Vigil B5700 1000Base-T
+ 1028 00d1 Broadcom BCM5700
+ 1028 0106 Broadcom BCM5700
+ 1028 0109 Broadcom BCM5700 1000Base-T
+ 1028 010a Broadcom BCM5700 1000BaseTX
+ 10b7 1000 3C996-T 1000Base-T
+ 10b7 1001 3C996B-T 1000Base-T
+ 10b7 1002 3C996C-T 1000Base-T
+ 10b7 1003 3C997-T 1000Base-T Dual Port
+ 10b7 1004 3C996-SX 1000Base-SX
+ 10b7 1005 3C997-SX 1000Base-SX Dual Port
+ 10b7 1008 3C942 Gigabit LOM (31X31)
+ 14e4 0002 NetXtreme 1000Base-SX
+ 14e4 0003 NetXtreme 1000Base-SX
+ 14e4 0004 NetXtreme 1000Base-T
+ 14e4 1028 NetXtreme 1000BaseTX
+ 14e4 1644 BCM5700 1000Base-T
+ 1645 NetXtreme BCM5701 Gigabit Ethernet
+ 0e11 007c NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+ 0e11 007d NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+ 0e11 0085 NC7780 Gigabit Server Adapter (embedded, WOL)
+ 0e11 0099 NC7780 Gigabit Server Adapter (embedded, WOL)
+ 0e11 009a NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+ 0e11 00c1 NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+ 1028 0121 Broadcom BCM5701 1000Base-T
+ 103c 128a 1000Base-T (PCI) [A7061A]
+ 103c 128b 1000Base-SX (PCI) [A7073A]
+ 103c 12a4 Core Lan 1000Base-T
+ 103c 12c1 IOX Core Lan 1000Base-T [A7109AX]
+ 103c 1300 Core LAN/SCSI Combo [A6794A]
+ 10a9 8010 IO9/IO10 Gigabit Ethernet (Copper)
+ 10a9 8011 Gigabit Ethernet (Copper)
+ 10a9 8012 Gigabit Ethernet (Fiber)
+ 10b7 1004 3C996-SX 1000Base-SX
+ 10b7 1006 3C996B-T 1000Base-T
+ 10b7 1007 3C1000-T 1000Base-T
+ 10b7 1008 3C940-BR01 1000Base-T
+ 14e4 0001 BCM5701 1000Base-T
+ 14e4 0005 BCM5701 1000Base-T
+ 14e4 0006 BCM5701 1000Base-T
+ 14e4 0007 BCM5701 1000Base-SX
+ 14e4 0008 BCM5701 1000Base-T
+ 14e4 8008 BCM5701 1000Base-T
+ 1646 NetXtreme BCM5702 Gigabit Ethernet
+ 0e11 00bb NC7760 1000BaseTX
+ 1028 0126 Broadcom BCM5702 1000BaseTX
+ 14e4 8009 BCM5702 1000BaseTX
+ 1647 NetXtreme BCM5703 Gigabit Ethernet
+ 0e11 0099 NC7780 1000BaseTX
+ 0e11 009a NC7770 1000BaseTX
+ 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
+ 14e4 0009 BCM5703 1000BaseTX
+ 14e4 000a BCM5703 1000BaseSX
+ 14e4 000b BCM5703 1000BaseTX
+ 14e4 8009 BCM5703 1000BaseTX
+ 14e4 800a BCM5703 1000BaseTX
+ 1648 NetXtreme BCM5704 Gigabit Ethernet
+ 0e11 00cf NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 0e11 00d0 NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 0e11 00d1 NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 10a9 8013 Dual Port Gigabit Ethernet (PCI-X,Copper)
+ 10a9 8018 Dual Port Gigabit Ethernet (A330)
+ 10a9 801a Dual Port Gigabit Ethernet (IA-blade)
+ 10a9 801b Quad Port Gigabit Ethernet (PCI-E,Copper)
+ 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X
+ 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X
+ 1166 1648 NetXtreme CIOB-E 1000Base-T
+ 1734 100b Primergy RX300
+ 164a NetXtreme II BCM5706 Gigabit Ethernet
+ 103c 3101 NC370T MultifuNCtion Gigabit Server Adapter
+ 164c NetXtreme II BCM5708 Gigabit Ethernet
+ 164d NetXtreme BCM5702FE Gigabit Ethernet
+ 1653 NetXtreme BCM5705 Gigabit Ethernet
+ 0e11 00e3 NC7761 Gigabit Server Adapter
+ 1654 NetXtreme BCM5705_2 Gigabit Ethernet
+ 0e11 00e3 NC7761 Gigabit Server Adapter
+ 103c 3100 NC1020 HP ProLiant Gigabit Server Adapter 32 PCI
+ 103c 3226 NC150T 4-port Gigabit Combo Switch & Adapter
+ 1659 NetXtreme BCM5721 Gigabit Ethernet PCI Express
+ 1014 02c6 eServer xSeries server mainboard
+ 103c 7031 NC320T PCIe Gigabit Server Adapter
+ 103c 7032 NC320i PCIe Gigabit Server Adapter
+ 1734 1061 Primergy RX300 S2
+ 165d NetXtreme BCM5705M Gigabit Ethernet
+ 1028 865d Latitude D400
+ 165e NetXtreme BCM5705M_2 Gigabit Ethernet
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 099c NX6110/NC6120
+ 1668 NetXtreme BCM5714 Gigabit Ethernet
+ 103c 7039 NC324i PCIe Dual Port Gigabit Server Adapter
+ 1669 NetXtreme 5714S Gigabit Ethernet
+ 166a NetXtreme BCM5780 Gigabit Ethernet
+ 166b NetXtreme BCM5780S Gigabit Ethernet
+ 166e 570x 10/100 Integrated Controller
+ 1672 NetXtreme BCM5754M Gigabit Ethernet PCI Express
+ 1673 NetXtreme BCM5755M Gigabit Ethernet PCI Express
+ 1677 NetXtreme BCM5751 Gigabit Ethernet PCI Express
+ 1028 0179 Optiplex GX280
+ 1028 0182 Latitude D610
+ 1028 0187 Precision M70
+ 1028 01ad Optiplex GX620
+ 103c 3006 DC7100 SFF(DX878AV)
+ 1734 105d Scenic W620
+ 1678 NetXtreme BCM5715 Gigabit Ethernet
+ 1679 NetXtreme 5715S Gigabit Ethernet
+ 103c 703c NC326i PCIe Dual Port Gigabit Server Adapter
+ 167a NetXtreme BCM5754 Gigabit Ethernet PCI Express
+ 167b NetXtreme BCM5755 Gigabit Ethernet PCI Express
+ 167d NetXtreme BCM5751M Gigabit Ethernet PCI Express
+ 167e NetXtreme BCM5751F Fast Ethernet PCI Express
+ 1693 NetLink BCM5787M Gigabit Ethernet PCI Express
+ 1696 NetXtreme BCM5782 Gigabit Ethernet
+ 103c 12bc HP d530 CMT (DG746A)
+ 14e4 000d NetXtreme BCM5782 1000Base-T
+ 169a NetLink BCM5786 Gigabit Ethernet PCI Express
+ 169b NetLink BCM5787 Gigabit Ethernet PCI Express
+ 169c NetXtreme BCM5788 Gigabit Ethernet
+ 103c 308b MX6125
+ 169d NetLink BCM5789 Gigabit Ethernet PCI Express
+ 16a6 NetXtreme BCM5702X Gigabit Ethernet
+ 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+ 1028 0126 BCM5702 1000Base-T
+ 14e4 000c BCM5702 1000Base-T
+ 14e4 8009 BCM5702 1000Base-T
+ 16a7 NetXtreme BCM5703X Gigabit Ethernet
+ 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 14e4 0009 NetXtreme BCM5703 1000Base-T
+ 14e4 000a NetXtreme BCM5703 1000Base-SX
+ 14e4 000b NetXtreme BCM5703 1000Base-T
+ 14e4 800a NetXtreme BCM5703 1000Base-T
+ 16a8 NetXtreme BCM5704S Gigabit Ethernet
+ 10a9 8014 Dual Port Gigabit Ethernet (PCI-X,Fiber)
+ 10a9 801c Quad Port Gigabit Ethernet (PCI-E,Fiber)
+ 10b7 2001 3C998-SX Dual Port 1000-SX PCI-X
+ 16aa NetXtreme II BCM5706S Gigabit Ethernet
+ 103c 3102 NC370F MultifuNCtion Gigabit Server Adapter
+ 16ac NetXtreme II BCM5708S Gigabit Ethernet
+ 16c6 NetXtreme BCM5702A3 Gigabit Ethernet
+ 10b7 1100 3C1000B-T 10/100/1000 PCI
+ 14e4 000c BCM5702 1000Base-T
+ 14e4 8009 BCM5702 1000Base-T
+ 16c7 NetXtreme BCM5703 Gigabit Ethernet
+ 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ 103c 12c3 Combo FC/GigE-SX [A9782A]
+ 103c 12ca Combo FC/GigE-T [A9784A]
+ 14e4 0009 NetXtreme BCM5703 1000Base-T
+ 14e4 000a NetXtreme BCM5703 1000Base-SX
+ 16dd NetLink BCM5781 Gigabit Ethernet PCI Express
+ 16f7 NetXtreme BCM5753 Gigabit Ethernet PCI Express
+ 16fd NetXtreme BCM5753M Gigabit Ethernet PCI Express
+ 16fe NetXtreme BCM5753F Fast Ethernet PCI Express
+ 170c BCM4401-B0 100Base-TX
+ 1028 0188 Inspiron 6000 laptop
+ 1028 0196 Inspiron 5160
+ 103c 099c NX6110/NC6120
+ 170d NetXtreme BCM5901 100Base-TX
+ 1014 0545 ThinkPad R40e (2684-HVG) builtin ethernet controller
+ 170e NetXtreme BCM5901 100Base-TX
+ 3352 BCM3352
+ 3360 BCM3360
+ 4210 BCM4210 iLine10 HomePNA 2.0
+ 4211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
+ 4212 BCM4212 v.90 56k modem
+ 4301 BCM4303 802.11b Wireless LAN Controller
+ 1028 0407 TrueMobile 1180 Onboard WLAN
+ 1043 0120 WL-103b Wireless LAN PC Card
+ 4305 BCM4307 V.90 56k Modem
+ 4306 BCM4307 Ethernet Controller
+ 4307 BCM4307 802.11b Wireless LAN Controller
+ 4310 BCM4310 Chipcommon I/OController
+ 4311 Dell Wireless 1390 WLAN Mini-PCI Card
+ 4312 BCM4310 UART
+ 4313 BCM4310 Ethernet Controller
+ 4315 BCM4310 USB Controller
+ 4318 BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller
+ 103c 1356 MX6125
+ 1043 120f A6U notebook embedded card
+ 1468 0311 Aspire 3022WLMi, 5024WLMi
+ 1468 0312 TravelMate 2410
+ 14e4 0449 Gateway 7510GX
+ 14e4 4318 WPC54G version 3 [Wireless-G Notebook Adapter] 802.11g Wireless Lan Controller
+ 16ec 0119 U.S.Robotics Wireless MAXg PC Card
+ 1737 0048 WPC54G-EU version 3 [Wireless-G Notebook Adapter]
+ 4319 Dell Wireless 1470 DualBand WLAN
+ 4320 BCM4306 802.11b/g Wireless LAN Controller
+ 1028 0001 TrueMobile 1300 WLAN Mini-PCI Card
+ 1028 0003 Wireless 1350 WLAN Mini-PCI Card
+ 103c 12f4 NX9500 Built-in Wireless
+ 103c 12fa Presario R3000 802.11b/g
+ 1043 100f WL-100G
+ 1057 7025 WN825G
+ 106b 004e AirPort Extreme
+ 1154 0330 Buffalo WLI2-PCI-G54S High Speed Mode Wireless Desktop Adapter
+ 144f 7050 eMachines M6805 802.11g Built-in Wireless
+ 14e4 4320 Linksys WMP54G PCI
+ 1737 4320 WPC54G
+ 1799 7001 Belkin F5D7001 High-Speed Mode Wireless G Network Card
+ 1799 7010 Belkin F5D7010 54g Wireless Network card
+ 1799 7011 F5D7011 54g+ Wireless Network card
+ 185f 1220 TravelMate 290E WLAN Mini-PCI Card
+ 4321 BCM4306 802.11a Wireless LAN Controller
+ 4322 BCM4306 UART
+ 4324 BCM4309 802.11a/b/g
+ 1028 0001 Truemobile 1400
+ 1028 0003 Truemobile 1450 MiniPCI
+ 4325 BCM43xG 802.11b/g
+ 1414 0003 Wireless Notebook Adapter MN-720
+ 1414 0004 Wireless PCI Adapter MN-730
+# probably this is a correct ID...
+ 4326 BCM4307 Chipcommon I/O Controller?
+ 4329 BCM43XG
+ 4401 BCM4401 100Base-T
+ 103c 08b0 tc1100 tablet
+ 1043 80a8 A7V8X motherboard
+ 4402 BCM4402 Integrated 10/100BaseT
+ 4403 BCM4402 V.90 56k Modem
+ 4410 BCM4413 iLine32 HomePNA 2.0
+ 4411 BCM4413 V.90 56k modem
+ 4412 BCM4412 10/100BaseT
+ 4430 BCM44xx CardBus iLine32 HomePNA 2.0
+ 4432 BCM4432 CardBus 10/100BaseT
+ 4610 BCM4610 Sentry5 PCI to SB Bridge
+ 4611 BCM4610 Sentry5 iLine32 HomePNA 1.0
+ 4612 BCM4610 Sentry5 V.90 56k Modem
+ 4613 BCM4610 Sentry5 Ethernet Controller
+ 4614 BCM4610 Sentry5 External Interface
+ 4615 BCM4610 Sentry5 USB Controller
+ 4704 BCM4704 PCI to SB Bridge
+ 4705 BCM4704 Sentry5 802.11b Wireless LAN Controller
+ 4706 BCM4704 Sentry5 Ethernet Controller
+ 4707 BCM4704 Sentry5 USB Controller
+ 4708 BCM4704 Crypto Accelerator
+ 4710 BCM4710 Sentry5 PCI to SB Bridge
+ 4711 BCM47xx Sentry5 iLine32 HomePNA 2.0
+ 4712 BCM47xx V.92 56k modem
+ 4713 Sentry5 Ethernet Controller
+ 4714 BCM47xx Sentry5 External Interface
+ 4715 Sentry5 USB Controller
+ 4716 BCM47xx Sentry5 USB Host Controller
+ 4717 BCM47xx Sentry5 USB Device Controller
+ 4718 Sentry5 Crypto Accelerator
+ 4719 BCM47xx/53xx RoboSwitch Core
+ 4720 BCM4712 MIPS CPU
+ 5365 BCM5365P Sentry5 Host Bridge
+ 5600 BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
+ 5605 BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
+ 5615 BCM5615 StrataSwitch 24+2 Ethernet Switch Controller
+ 5625 BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
+ 5645 BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
+ 5670 BCM5670 8-Port 10GE Ethernet Switch Fabric
+ 5680 BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller
+ 5690 BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
+ 5691 BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
+ 5692 BCM5692 12-port Multi-Layer Gigabit Ethernet Switch
+ 5820 BCM5820 Crypto Accelerator
+ 5821 BCM5821 Crypto Accelerator
+ 5822 BCM5822 Crypto Accelerator
+ 5823 BCM5823 Crypto Accelerator
+ 5824 BCM5824 Crypto Accelerator
+ 5840 BCM5840 Crypto Accelerator
+ 5841 BCM5841 Crypto Accelerator
+ 5850 BCM5850 Crypto Accelerator
+14e5 Pixelfusion Ltd
+14e6 SHINING Technology Inc
+14e7 3CX
+14e8 RAYCER Inc
+14e9 GARNETS System CO Ltd
+14ea Planex Communications, Inc
+ ab06 FNW-3603-TX CardBus Fast Ethernet
+ ab07 RTL81xx RealTek Ethernet
+ ab08 FNW-3602-TX CardBus Fast Ethernet
+14eb SEIKO EPSON Corp
+14ec ACQIRIS
+14ed DATAKINETICS Ltd
+14ee MASPRO KENKOH Corp
+14ef CARRY Computer ENG. CO Ltd
+14f0 CANON RESEACH CENTRE FRANCE
+14f1 Conexant
+ 1002 HCF 56k Modem
+ 1003 HCF 56k Modem
+ 1004 HCF 56k Modem
+ 1005 HCF 56k Modem
+ 1006 HCF 56k Modem
+ 1022 HCF 56k Modem
+ 1023 HCF 56k Modem
+ 1024 HCF 56k Modem
+ 1025 HCF 56k Modem
+ 1026 HCF 56k Modem
+ 1032 HCF 56k Modem
+ 1033 HCF 56k Data/Fax Modem
+ 1033 8077 NEC
+ 122d 4027 Dell Zeus - MDP3880-W(B) Data Fax Modem
+ 122d 4030 Dell Mercury - MDP3880-U(B) Data Fax Modem
+ 122d 4034 Dell Thor - MDP3880-W(U) Data Fax Modem
+ 13e0 020d Dell Copper
+ 13e0 020e Dell Silver
+ 13e0 0261 IBM
+ 13e0 0290 Compaq Goldwing
+ 13e0 02a0 IBM
+ 13e0 02b0 IBM
+ 13e0 02c0 Compaq Scooter
+ 13e0 02d0 IBM
+ 144f 1500 IBM P85-DF (1)
+ 144f 1501 IBM P85-DF (2)
+ 144f 150a IBM P85-DF (3)
+ 144f 150b IBM P85-DF Low Profile (1)
+ 144f 1510 IBM P85-DF Low Profile (2)
+ 1034 HCF 56k Data/Fax/Voice Modem
+ 1035 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 10cf 1098 Fujitsu P85-DFSV
+ 1036 HCF 56k Data/Fax/Voice/Spkp Modem
+ 104d 8067 HCF 56k Modem
+ 122d 4029 MDP3880SP-W
+ 122d 4031 MDP3880SP-U
+ 13e0 0209 Dell Titanium
+ 13e0 020a Dell Graphite
+ 13e0 0260 Gateway Red Owl
+ 13e0 0270 Gateway White Horse
+ 1052 HCF 56k Data/Fax Modem (Worldwide)
+ 1053 HCF 56k Data/Fax Modem (Worldwide)
+ 1054 HCF 56k Data/Fax/Voice Modem (Worldwide)
+ 1055 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
+ 1056 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+ 1057 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
+ 1059 HCF 56k Data/Fax/Voice Modem (Worldwide)
+ 1063 HCF 56k Data/Fax Modem
+ 1064 HCF 56k Data/Fax/Voice Modem
+ 1065 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1066 HCF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4033 Dell Athena - MDP3900V-U
+ 1085 HCF V90 56k Data/Fax/Voice/Spkp PCI Modem
+ 1433 HCF 56k Data/Fax Modem
+ 1434 HCF 56k Data/Fax/Voice Modem
+ 1435 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1436 HCF 56k Data/Fax Modem
+ 1453 HCF 56k Data/Fax Modem
+ 13e0 0240 IBM
+ 13e0 0250 IBM
+ 144f 1502 IBM P95-DF (1)
+ 144f 1503 IBM P95-DF (2)
+ 1454 HCF 56k Data/Fax/Voice Modem
+ 1455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 1456 HCF 56k Data/Fax/Voice/Spkp Modem
+ 122d 4035 Dell Europa - MDP3900V-W
+ 122d 4302 Dell MP3930V-W(C) MiniPCI
+ 1610 ADSL AccessRunner PCI Arbitration Device
+ 1611 AccessRunner PCI ADSL Interface Device
+ 1620 AccessRunner V2 PCI ADSL Arbitration Device
+ 1621 AccessRunner V2 PCI ADSL Interface Device
+ 1622 AccessRunner V2 PCI ADSL Yukon WAN Adapter
+ 1803 HCF 56k Modem
+ 0e11 0023 623-LAN Grizzly
+ 0e11 0043 623-LAN Yogi
+ 1811 Conextant MiniPCI Network Adapter
+ 1815 HCF 56k Modem
+ 0e11 0022 Grizzly
+ 0e11 0042 Yogi
+ 2003 HSF 56k Data/Fax Modem
+ 2004 HSF 56k Data/Fax/Voice Modem
+ 2005 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 2006 HSF 56k Data/Fax/Voice/Spkp Modem
+ 2013 HSF 56k Data/Fax Modem
+ 0e11 b195 Bear
+ 0e11 b196 Seminole 1
+ 0e11 b1be Seminole 2
+ 1025 8013 Acer
+ 1033 809d NEC
+ 1033 80bc NEC
+ 155d 6793 HP
+ 155d 8850 E Machines
+ 2014 HSF 56k Data/Fax/Voice Modem
+ 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
+ 2016 HSF 56k Data/Fax/Voice/Spkp Modem
+ 2043 HSF 56k Data/Fax Modem (WorldW SmartDAA)
+ 2044 HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA)
+ 2045 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
+ 14f1 2045 Generic SoftK56
+ 2046 HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
+ 2063 HSF 56k Data/Fax Modem (SmartDAA)
+ 2064 HSF 56k Data/Fax/Voice Modem (SmartDAA)
+ 2065 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
+ 2066 HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
+ 2093 HSF 56k Modem
+ 155d 2f07 Legend
+ 2143 HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
+ 2144 HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA)
+ 2145 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA)
+ 2146 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA)
+ 2163 HSF 56k Data/Fax/Cell Modem (Mob SmartDAA)
+ 2164 HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA)
+ 2165 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA)
+ 2166 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA)
+ 2343 HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA)
+ 2344 HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA)
+ 2345 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA)
+ 2346 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA)
+ 2363 HSF 56k Data/Fax CardBus Modem (Mob SmartDAA)
+ 2364 HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA)
+ 2365 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
+ 2366 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
+ 2443 HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
+ 104d 8075 Modem
+ 104d 8083 Modem
+ 104d 8097 Modem
+ 2444 HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
+ 2445 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
+ 2446 HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
+ 2463 HSF 56k Data/Fax Modem (Mob SmartDAA)
+ 2464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
+ 2465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
+ 2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
+ 2bfa HDAudio Soft Data Fax Modem with SmartCP
+ 2f00 HSF 56k HSFi Modem
+ 13e0 8d84 IBM HSFi V.90
+ 13e0 8d85 Compaq Stinger
+ 14f1 2004 Dynalink 56PMi
+ 2f02 HSF 56k HSFi Data/Fax
+ 2f11 HSF 56k HSFi Modem
+ 2f20 HSF 56k Data/Fax Modem
+ 8234 RS8234 ATM SAR Controller [ServiceSAR Plus]
+ 8800 CX23880/1/2/3 PCI Video and Audio Decoder
+ 0070 2801 Hauppauge WinTV 28xxx (Roslyn) models
+ 0070 3401 Hauppauge WinTV 34xxx models
+ 0070 9001 Nova-T DVB-T
+ 0070 9200 Nova-SE2 DVB-S
+ 0070 9202 Nova-S-Plus DVB-S
+ 0070 9402 WinTV-HVR1100 DVB-T/Hybrid
+ 0070 9802 WinTV-HVR1100 DVB-T/Hybrid (Low Profile)
+ 1002 00f8 ATI TV Wonder Pro
+ 1002 a101 HDTV Wonder
+ 1043 4823 ASUS PVR-416
+ 107d 6613 Leadtek Winfast 2000XP Expert
+ 107d 6620 Leadtek Winfast DV2000
+ 107d 663c Leadtek PVR 2000
+ 107d 665f WinFast DTV1000-T
+ 10fc d003 IODATA GV-VCP3/PCI
+ 10fc d035 IODATA GV/BCTV7E
+ 1421 0334 Instant TV DVB-T PCI
+ 1461 000a AVerTV 303 (M126)
+ 1461 000b AverTV Studio 303 (M126)
+ 1461 8011 UltraTV Media Center PCI 550
+ 1462 8606 MSI TV-@nywhere Master
+ 14c7 0107 GDI Black Gold
+ 14f1 0187 Conexant DVB-T reference design
+ 14f1 0342 Digital-Logic MICROSPACE Entertainment Center (MEC)
+ 153b 1166 Cinergy 1400 DVB-T
+ 1540 2580 Provideo PV259
+ 1554 4811 PixelView
+ 1554 4813 Club 3D ZAP1000 MCE Edition
+ 17de 08a1 KWorld/VStream XPert DVB-T with cx22702
+ 17de 08a6 KWorld/VStream XPert DVB-T
+ 17de 08b2 KWorld DVB-S 100
+ 17de a8a6 digitalnow DNTV Live! DVB-T
+ 1822 0025 digitalnow DNTV Live! DVB-T Pro
+ 18ac d500 FusionHDTV 5 Gold
+ 18ac d810 FusionHDTV 3 Gold-Q
+ 18ac d820 FusionHDTV 3 Gold-T
+ 18ac db00 FusionHDTV DVB-T1
+ 18ac db11 FusionHDTV DVB-T Plus
+ 18ac db50 FusionHDTV DVB-T Dual Digital
+ 7063 3000 pcHDTV HD3000 HDTV
+ 8801 CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port]
+ 0070 2801 Hauppauge WinTV 28xxx (Roslyn) models
+ 8802 CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port]
+ 0070 2801 Hauppauge WinTV 28xxx (Roslyn) models
+ 0070 9002 Nova-T DVB-T Model 909
+ 1043 4823 ASUS PVR-416
+ 107d 663c Leadtek PVR 2000
+ 14f1 0187 Conexant DVB-T reference design
+ 17de 08a1 XPert DVB-T PCI BDA DVBT 23880 Transport Stream Capture
+ 17de 08a6 KWorld/VStream XPert DVB-T
+ 18ac d500 DViCO FusionHDTV5 Gold
+ 18ac d810 DViCO FusionHDTV3 Gold-Q
+ 18ac d820 DViCO FusionHDTV3 Gold-T
+ 18ac db00 DVICO FusionHDTV DVB-T1
+ 18ac db10 DVICO FusionHDTV DVB-T Plus
+ 7063 3000 pcHDTV HD3000 HDTV
+ 8804 CX23880/1/2/3 PCI Video and Audio Decoder [IR Port]
+ 0070 9002 Nova-T DVB-T Model 909
+ 8811 CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port]
+ 0070 3401 Hauppauge WinTV 34xxx models
+ 1462 8606 MSI TV-@nywhere Master
+ 18ac d500 DViCO FusionHDTV5 Gold
+ 18ac d810 DViCO FusionHDTV3 Gold-Q
+ 18ac d820 DViCO FusionHDTV3 Gold-T
+ 18ac db00 DVICO FusionHDTV DVB-T1
+14f2 MOBILITY Electronics
+ 0120 EV1000 bridge
+ 0121 EV1000 Parallel port
+ 0122 EV1000 Serial port
+ 0123 EV1000 Keyboard controller
+ 0124 EV1000 Mouse controller
+14f3 BroadLogic
+ 2030 2030 DVB-S Satellite Reciever
+ 2050 2050 DVB-T Terrestrial (Cable) Reciever
+ 2060 2060 ATSC Terrestrial (Cable) Reciever
+14f4 TOKYO Electronic Industry CO Ltd
+14f5 SOPAC Ltd
+14f6 COYOTE Technologies LLC
+14f7 WOLF Technology Inc
+14f8 AUDIOCODES Inc
+ 2077 TP-240 dual span E1 VoIP PCI card
+14f9 AG COMMUNICATIONS
+14fa WANDEL & GOLTERMANN
+14fb TRANSAS MARINE (UK) Ltd
+14fc Quadrics Ltd
+ 0000 QsNet Elan3 Network Adapter
+ 0001 QsNetII Elan4 Network Adapter
+ 0002 QsNetIII Elan5 Network Adapter
+14fd JAPAN Computer Industry Inc
+14fe ARCHTEK TELECOM Corp
+14ff TWINHEAD INTERNATIONAL Corp
+1500 DELTA Electronics, Inc
+ 1360 RTL81xx RealTek Ethernet
+1501 BANKSOFT CANADA Ltd
+1502 MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd
+1503 KAWASAKI LSI USA Inc
+1504 KAISER Electronics
+1505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH
+1506 CHAMELEON Systems Inc
+# Should be HTEC Ltd, but there are no known HTEC chips and 1507 is already used by mistake by Motorola (see vendor ID 1057).
+1507 Motorola ?? / HTEC
+ 0001 MPC105 [Eagle]
+ 0002 MPC106 [Grackle]
+ 0003 MPC8240 [Kahlua]
+ 0100 MC145575 [HFC-PCI]
+ 0431 KTI829c 100VG
+ 4801 Raven
+ 4802 Falcon
+ 4803 Hawk
+ 4806 CPX8216
+1508 HONDA CONNECTORS/MHOTRONICS Inc
+1509 FIRST INTERNATIONAL Computer Inc
+150a FORVUS RESEARCH Inc
+150b YAMASHITA Systems Corp
+150c KYOPAL CO Ltd
+150d WARPSPPED Inc
+150e C-PORT Corp
+150f INTEC GmbH
+1510 BEHAVIOR TECH Computer Corp
+1511 CENTILLIUM Technology Corp
+1512 ROSUN Technologies Inc
+1513 Raychem
+1514 TFL LAN Inc
+1515 Advent design
+1516 MYSON Technology Inc
+ 0800 MTD-8xx 100/10M Ethernet PCI Adapter
+ 0803 SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
+ 1320 10bd SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
+ 0891 MTD-8xx 100/10M Ethernet PCI Adapter
+1517 ECHOTEK Corp
+1518 PEP MODULAR Computers GmbH
+1519 TELEFON AKTIEBOLAGET LM Ericsson
+151a Globetek
+ 1002 PCI-1002
+ 1004 PCI-1004
+ 1008 PCI-1008
+151b COMBOX Ltd
+151c DIGITAL AUDIO LABS Inc
+ 0003 Prodif T 2496
+ 4000 Prodif 88
+151d Fujitsu Computer Products Of America
+151e MATRIX Corp
+151f TOPIC SEMICONDUCTOR Corp
+ 0000 TP560 Data/Fax/Voice 56k modem
+1520 CHAPLET System Inc
+1521 BELL Corp
+1522 MainPine Ltd
+ 0100 PCI <-> IOBus Bridge
+ 1522 0200 RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
+ 1522 0300 RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
+ 1522 0400 RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
+ 1522 0500 RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
+ 1522 0600 RockForce+ 2 Port V.90 Data/Fax/Voice Modem
+ 1522 0700 RockForce+ 4 Port V.90 Data/Fax/Voice Modem
+ 1522 0800 RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
+ 1522 0c00 RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+ 1522 0d00 RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+ 1522 1d00 RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+ 1522 2000 RockForceD1 1 Port V.90 Data Modem
+ 1522 2100 RockForceF1 1 Port V.34 Super-G3 Fax Modem
+ 1522 2200 RockForceD2 2 Port V.90 Data Modem
+ 1522 2300 RockForceF2 2 Port V.34 Super-G3 Fax Modem
+ 1522 2400 RockForceD4 4 Port V.90 Data Modem
+ 1522 2500 RockForceF4 4 Port V.34 Super-G3 Fax Modem
+ 1522 2600 RockForceD8 8 Port V.90 Data Modem
+ 1522 2700 RockForceF8 8 Port V.34 Super-G3 Fax Modem
+1523 MUSIC Semiconductors
+1524 ENE Technology Inc
+ 0510 CB710 Memory Card Reader Controller
+ 103c 006a NX9500
+ 0520 FLASH memory: ENE Technology Inc:
+ 0530 ENE PCI Memory Stick Card Reader Controller
+ 0550 ENE PCI Secure Digital Card Reader Controller
+ 0610 PCI Smart Card Reader Controller
+ 1211 CB1211 Cardbus Controller
+ 1225 CB1225 Cardbus Controller
+ 1410 CB1410 Cardbus Controller
+ 1025 003c CL50 motherboard
+ 1025 005a TravelMate 290
+ 1411 CB-710/2/4 Cardbus Controller
+ 103c 006a NX9500
+ 1412 CB-712/4 Cardbus Controller
+ 1420 CB1420 Cardbus Controller
+ 1421 CB-720/2/4 Cardbus Controller
+ 1422 CB-722/4 Cardbus Controller
+1525 IMPACT Technologies
+1526 ISS, Inc
+1527 SOLECTRON
+1528 ACKSYS
+1529 AMERICAN MICROSystems Inc
+152a QUICKTURN DESIGN Systems
+152b FLYTECH Technology CO Ltd
+152c MACRAIGOR Systems LLC
+152d QUANTA Computer Inc
+152e MELEC Inc
+152f PHILIPS - CRYPTO
+1530 ACQIS Technology Inc
+1531 CHRYON Corp
+1532 ECHELON Corp
+ 0020 LonWorks PCLTA-20 PCI LonTalk Adapter
+1533 BALTIMORE
+1534 ROAD Corp
+1535 EVERGREEN Technologies Inc
+1537 DATALEX COMMUNCATIONS
+1538 ARALION Inc
+ 0303 ARS106S Ultra ATA 133/100/66 Host Controller
+1539 ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A.
+153a ONO SOKKI
+153b TERRATEC Electronic GmbH
+ 1144 Aureon 5.1
+# Terratec seems to use several IDs for the same card.
+ 1147 Aureon 5.1 Sky
+ 1158 Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV]
+153c ANTAL Electronic
+153d FILANET Corp
+153e TECHWELL Inc
+153f MIPS Technologies, Inc.
+ 0001 SOC-it 101 System Controller
+1540 PROVIDEO MULTIMEDIA Co Ltd
+1541 MACHONE Communications
+1542 Concurrent Computer Corporation
+ 9260 RCIM-II Real-Time Clock & Interrupt Module
+1543 SILICON Laboratories
+ 3052 Intel 537 [Winmodem]
+ 4c22 Si3036 MC'97 DAA
+1544 DCM DATA Systems
+1545 VISIONTEK
+1546 IOI Technology Corp
+1547 MITUTOYO Corp
+1548 JET PROPULSION Laboratory
+1549 INTERCONNECT Systems Solutions
+154a MAX Technologies Inc
+154b COMPUTEX Co Ltd
+154c VISUAL Technology Inc
+154d PAN INTERNATIONAL Industrial Corp
+154e SERVOTEST Ltd
+154f STRATABEAM Technology
+1550 OPEN NETWORK Co Ltd
+1551 SMART Electronic DEVELOPMENT GmBH
+1552 RACAL AIRTECH Ltd
+1553 CHICONY Electronics Co Ltd
+1554 PROLINK Microsystems Corp
+1555 GESYTEC GmBH
+1556 PLD APPLICATIONS
+1557 MEDIASTAR Co Ltd
+1558 CLEVO/KAPOK Computer
+1559 SI LOGIC Ltd
+155a INNOMEDIA Inc
+155b PROTAC INTERNATIONAL Corp
+155c Cemax-Icon Inc
+155d Mac System Co Ltd
+155e LP Elektronik GmbH
+155f Perle Systems Ltd
+1560 Terayon Communications Systems
+1561 Viewgraphics Inc
+1562 Symbol Technologies
+1563 A-Trend Technology Co Ltd
+1564 Yamakatsu Electronics Industry Co Ltd
+1565 Biostar Microtech Int'l Corp
+1566 Ardent Technologies Inc
+1567 Jungsoft
+1568 DDK Electronics Inc
+1569 Palit Microsystems Inc.
+156a Avtec Systems
+156b 2wire Inc
+156c Vidac Electronics GmbH
+156d Alpha-Top Corp
+156e Alfa Inc
+156f M-Systems Flash Disk Pioneers Ltd
+1570 Lecroy Corp
+1571 Contemporary Controls
+ a001 CCSI PCI20-485 ARCnet
+ a002 CCSI PCI20-485D ARCnet
+ a003 CCSI PCI20-485X ARCnet
+ a004 CCSI PCI20-CXB ARCnet
+ a005 CCSI PCI20-CXS ARCnet
+ a006 CCSI PCI20-FOG-SMA ARCnet
+ a007 CCSI PCI20-FOG-ST ARCnet
+ a008 CCSI PCI20-TB5 ARCnet
+ a009 CCSI PCI20-5-485 5Mbit ARCnet
+ a00a CCSI PCI20-5-485D 5Mbit ARCnet
+ a00b CCSI PCI20-5-485X 5Mbit ARCnet
+ a00c CCSI PCI20-5-FOG-ST 5Mbit ARCnet
+ a00d CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
+ a201 CCSI PCI22-485 10Mbit ARCnet
+ a202 CCSI PCI22-485D 10Mbit ARCnet
+ a203 CCSI PCI22-485X 10Mbit ARCnet
+ a204 CCSI PCI22-CHB 10Mbit ARCnet
+ a205 CCSI PCI22-FOG_ST 10Mbit ARCnet
+ a206 CCSI PCI22-THB 10Mbit ARCnet
+1572 Otis Elevator Company
+1573 Lattice - Vantis
+1574 Fairchild Semiconductor
+1575 Voltaire Advanced Data Security Ltd
+1576 Viewcast COM
+1578 HITT
+ 5615 VPMK3 [Video Processor Mk III]
+1579 Dual Technology Corp
+157a Japan Elecronics Ind Inc
+157b Star Multimedia Corp
+157c Eurosoft (UK)
+ 8001 Fix2000 PCI Y2K Compliance Card
+157d Gemflex Networks
+157e Transition Networks
+157f PX Instruments Technology Ltd
+1580 Primex Aerospace Co
+1581 SEH Computertechnik GmbH
+1582 Cytec Corp
+1583 Inet Technologies Inc
+1584 Uniwill Computer Corp
+1585 Logitron
+1586 Lancast Inc
+1587 Konica Corp
+1588 Solidum Systems Corp
+1589 Atlantek Microsystems Pty Ltd
+158a Digalog Systems Inc
+158b Allied Data Technologies
+158c Hitachi Semiconductor & Devices Sales Co Ltd
+158d Point Multimedia Systems
+158e Lara Technology Inc
+158f Ditect Coop
+1590 3pardata Inc
+1591 ARN
+1592 Syba Tech Ltd
+ 0781 Multi-IO Card
+ 0782 Parallel Port Card 2xEPP
+ 0783 Multi-IO Card
+ 0785 Multi-IO Card
+ 0786 Multi-IO Card
+ 0787 Multi-IO Card
+ 0788 Multi-IO Card
+ 078a Multi-IO Card
+1593 Bops Inc
+1594 Netgame Ltd
+1595 Diva Systems Corp
+1596 Folsom Research Inc
+1597 Memec Design Services
+1598 Granite Microsystems
+1599 Delta Electronics Inc
+159a General Instrument
+159b Faraday Technology Corp
+159c Stratus Computer Systems
+159d Ningbo Harrison Electronics Co Ltd
+159e A-Max Technology Co Ltd
+159f Galea Network Security
+15a0 Compumaster SRL
+15a1 Geocast Network Systems
+15a2 Catalyst Enterprises Inc
+ 0001 TA700 PCI Bus Analyzer/Exerciser
+15a3 Italtel
+15a4 X-Net OY
+15a5 Toyota Macs Inc
+15a6 Sunlight Ultrasound Technologies Ltd
+15a7 SSE Telecom Inc
+15a8 Shanghai Communications Technologies Center
+15aa Moreton Bay
+15ab Bluesteel Networks Inc
+15ac North Atlantic Instruments
+15ad VMware Inc
+ 0405 [VMware SVGA II] PCI Display Adapter
+ 0710 Virtual SVGA
+ 0720 VMware High-Speed Virtual NIC [vmxnet]
+15ae Amersham Pharmacia Biotech
+15b0 Zoltrix International Ltd
+15b1 Source Technology Inc
+15b2 Mosaid Technologies Inc
+15b3 Mellanox Technologies
+ 5274 MT21108 InfiniBridge
+ 5a44 MT23108 InfiniHost
+ 5a45 MT23108 [Infinihost HCA Flash Recovery]
+ 5a46 MT23108 PCI Bridge
+ 5e8d MT25204 [InfiniHost III Lx HCA Flash Recovery]
+ 6274 MT25204 [InfiniHost III Lx HCA]
+ 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
+ 6279 MT25208 [InfiniHost III Ex HCA Flash Recovery]
+ 6282 MT25208 InfiniHost III Ex
+15b4 CCI/TRIAD
+15b5 Cimetrics Inc
+15b6 Texas Memory Systems Inc
+15b7 Sandisk Corp
+15b8 ADDI-DATA GmbH
+15b9 Maestro Digital Communications
+15ba Impacct Technology Corp
+15bb Portwell Inc
+15bc Agilent Technologies
+ 1100 E8001-66442 PCI Express CIC
+ 2922 64 Bit, 133MHz PCI-X Exerciser & Protocol Checker
+ 2928 64 Bit, 66MHz PCI Exerciser & Analyzer
+ 2929 64 Bit, 133MHz PCI-X Analyzer & Exerciser
+15bd DFI Inc
+15be Sola Electronics
+15bf High Tech Computer Corp (HTC)
+15c0 BVM Ltd
+15c1 Quantel
+15c2 Newer Technology Inc
+15c3 Taiwan Mycomp Co Ltd
+15c4 EVSX Inc
+15c5 Procomp Informatics Ltd
+ 8010 1394b - 1394 Firewire 3-Port Host Adapter Card
+15c6 Technical University of Budapest
+15c7 Tateyama System Laboratory Co Ltd
+ 0349 Tateyama C-PCI PLC/NC card Rev.01A
+15c8 Penta Media Co Ltd
+15c9 Serome Technology Inc
+15ca Bitboys OY
+15cb AG Electronics Ltd
+15cc Hotrail Inc
+15cd Dreamtech Co Ltd
+15ce Genrad Inc
+15cf Hilscher GmbH
+15d1 Infineon Technologies AG
+15d2 FIC (First International Computer Inc)
+15d3 NDS Technologies Israel Ltd
+15d4 Iwill Corp
+15d5 Tatung Co
+15d6 Entridia Corp
+15d7 Rockwell-Collins Inc
+15d8 Cybernetics Technology Co Ltd
+15d9 Super Micro Computer Inc
+15da Cyberfirm Inc
+15db Applied Computing Systems Inc
+15dc Litronic Inc
+ 0001 Argus 300 PCI Cryptography Module
+15dd Sigmatel Inc
+15de Malleable Technologies Inc
+15df Infinilink Corp
+15e0 Cacheflow Inc
+15e1 Voice Technologies Group Inc
+15e2 Quicknet Technologies Inc
+15e3 Networth Technologies Inc
+15e4 VSN Systemen BV
+15e5 Valley technologies Inc
+15e6 Agere Inc
+15e7 Get Engineering Corp
+15e8 National Datacomm Corp
+ 0130 Wireless PCI Card
+15e9 Pacific Digital Corp
+ 1841 ADMA-100 DiscStaQ ATA Controller
+15ea Tokyo Denshi Sekei K.K.
+15eb Drsearch GmbH
+15ec Beckhoff GmbH
+ 3101 FC3101 Profibus DP 1 Channel PCI
+ 5102 FC5102
+15ed Macrolink Inc
+15ee In Win Development Inc
+15ef Intelligent Paradigm Inc
+15f0 B-Tree Systems Inc
+15f1 Times N Systems Inc
+15f2 Diagnostic Instruments Inc
+15f3 Digitmedia Corp
+15f4 Valuesoft
+15f5 Power Micro Research
+15f6 Extreme Packet Device Inc
+15f7 Banctec
+15f8 Koga Electronics Co
+15f9 Zenith Electronics Corp
+15fa J.P. Axzam Corp
+15fb Zilog Inc
+15fc Techsan Electronics Co Ltd
+15fd N-CUBED.NET
+15fe Kinpo Electronics Inc
+15ff Fastpoint Technologies Inc
+1600 Northrop Grumman - Canada Ltd
+1601 Tenta Technology
+1602 Prosys-tec Inc
+1603 Nokia Wireless Communications
+1604 Central System Research Co Ltd
+1605 Pairgain Technologies
+1606 Europop AG
+1607 Lava Semiconductor Manufacturing Inc
+1608 Automated Wagering International
+1609 Scimetric Instruments Inc
+1612 Telesynergy Research Inc.
+1619 FarSite Communications Ltd
+ 0400 FarSync T2P (2 port X.21/V.35/V.24)
+ 0440 FarSync T4P (4 port X.21/V.35/V.24)
+ 0610 FarSync T1U (1 port X.21/V.35/V.24)
+ 0620 FarSync T2U (2 port X.21/V.35/V.24)
+ 0640 FarSync T4U (4 port X.21/V.35/V.24)
+ 1610 FarSync TE1 (T1,E1)
+ 2610 FarSync DSL-S1 (SHDSL)
+161f Rioworks
+1626 TDK Semiconductor Corp.
+ 8410 RTL81xx Fast Ethernet
+1629 Kongsberg Spacetec AS
+ 1003 Format synchronizer v3.0
+ 2002 Fast Universal Data Output
+# This seems to occur on their 802.11b Wireless card WMP-11
+1637 Linksys
+ 3874 Linksys 802.11b WMP11 PCI Wireless card
+1638 Standard Microsystems Corp [SMC]
+ 1100 SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000
+163c Smart Link Ltd.
+ 3052 SmartLink SmartPCI562 56K Modem
+ 5449 SmartPCI561 Modem
+1657 Brocade Communications Systems, Inc.
+165a Epix Inc
+ c100 PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
+ d200 PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
+ d300 PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
+165d Hsing Tech. Enterprise Co., Ltd.
+165f Linux Media Labs, LLC
+ 1020 LMLM4 MPEG-4 encoder
+1661 Worldspace Corp.
+1668 Actiontec Electronics Inc
+ 0100 Mini-PCI bridge
+# Formerly SiByte, Inc.
+166d Broadcom Corporation
+ 0001 SiByte BCM1125/1125H/1250 System-on-a-Chip PCI
+ 0002 SiByte BCM1125H/1250 System-on-a-Chip HyperTransport
+1677 Bernecker + Rainer
+ 104e 5LS172.6 B&R Dual CAN Interface Card
+ 12d7 5LS172.61 B&R Dual CAN Interface Card
+167b ZyDAS Technology Corp.
+ 2102 ZyDAS ZD1202
+ 187e 3406 ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
+167d Samsung Electro-Mechanics Co., Ltd.
+ a000 IPW2200 miniPCI Wireless
+1681 Hercules
+ 0010 Hercules 3d Prophet II Ultra 64MB (350 MHz NV15BR core)
+1682 XFX Pine Group Inc.
+1688 CastleNet Technology Inc.
+ 1170 WLAN 802.11b card
+168c Atheros Communications, Inc.
+ 0007 AR5000 802.11a Wireless Adapter
+ 0011 AR5210 802.11a NIC
+ 0012 AR5211 802.11ab NIC
+ 0013 AR5212 802.11abg NIC
+ 1113 d301 Philips CPWNA100 Wireless CardBus adapter
+ 1186 3202 D-link DWL-G650 (Rev B3,B5) Wireless cardbus adapter
+ 1186 3203 DWL-G520 Wireless PCI Adapter
+ 1186 3a12 D-Link AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
+ 1186 3a13 D-Link AirPlus DWL-G520 Wireless PCI Adapter(rev.B)
+ 1186 3a14 D-Link AirPremier DWL-AG530 Wireless PCI Adapter
+ 1186 3a17 D-Link AirPremier DWL-G680 Wireless Cardbus Adapter
+ 1186 3a18 D-Link AirPremier DWL-G550 Wireless PCI Adapter
+ 1186 3a63 D-Link AirPremier DWL-AG660 Wireless Cardbus Adapter
+ 1186 3a93 Conceptronic C54I Wireless 801.11g PCI card
+ 1186 3a94 C54C Wireless 801.11g cardbus
+ 1186 3ab0 Allnet ALL0281 Wireless PCI Card
+ 1385 4d00 Netgear WG311T Wireless PCI Adapter
+ 1458 e911 Gigabyte GN-WIAG02
+ 14b7 0a60 8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
+ 168c 0013 AirPlus XtremeG DWL-G650 Wireless PCMCIA Adapter
+ 168c 1025 DWL-G650B2 Wireless CardBus Adapter
+ 168c 1027 Engenius NL-3054CB ARIES b/g CardBus Adapter
+ 168c 1042 Ubiquiti Networks SuperRange a/b/g Cardbus Adapter
+ 168c 2026 Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
+ 168c 2041 Engenius 5354MP Plus ARIES2 b/g MiniPCI Adapter
+ 168c 2042 Engenius 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
+ 16ab 7302 Trust Speedshare Turbo Pro Wireless PCI Adapter
+ 185f 2012 Wistron NeWeb WLAN a+b+g model CB9
+ 001a AR5005G 802.11abg NIC
+ 1113 ee20 SMC Wireless CardBus Adapter 802.11g (SMCWCB-G EU)
+ 1113 ee24 SMC Wireless PCI Card WPCI-G
+ 1186 3a15 D-Link AirPlus G DWL-G630 Wireless Cardbus Adapter(rev.D)
+ 1186 3a16 D-Link AirPlus G DWL-G510 Wireless PCI Adapter(rev.B)
+ 1186 3a23 D-Link AirPlus G DWL-G520+A Wireless PCI Adapter
+ 1186 3a24 D-Link AirPlus G DWL-G650+A Wireless Cardbus Adapter
+ 168c 001a Belkin FD7000
+ 168c 1052 TP-Link TL-WN510G Wireless CardBus Adapter
+ 001b AR5006X 802.11abg NIC
+ 1186 3a19 D-Link AirPremier AG DWL-AG660 Wireless Cardbus Adapter
+ 1186 3a22 D-Link AirPremier AG DWL-AG530 Wireless PCI Adapter
+ 168c 2062 EnGenius EMP-8602 (400mw) or Compex WLM54AG (SuperAG)
+ 168c 2063 EnGenius EMP-8602 (400mw) or Compex WLM54AG
+ 0020 AR5005VL 802.11bg Wireless NIC
+ 1014 AR5212 802.11abg NIC
+1695 EPoX Computer Co., Ltd.
+169c Netcell Corporation
+ 0044 Revolution Storage Processing Card
+16a5 Tekram Technology Co.,Ltd.
+16ab Global Sun Technology Inc
+ 1100 GL24110P
+ 1101 PLX9052 PCMCIA-to-PCI Wireless LAN
+ 1102 PCMCIA-to-PCI Wireless Network Bridge
+ 8501 WL-8305 Wireless LAN PCI Adapter
+16ae Safenet Inc
+ 1141 SafeXcel-1141
+16af SparkLAN Communications, Inc.
+16b4 Aspex Semiconductor Ltd
+16b8 Sonnet Technologies, Inc.
+16be Creatix Polymedia GmbH
+16c6 Micrel-Kendin
+ 8695 Centaur KS8695 ARM processor
+16c8 Octasic Inc.
+16c9 EONIC B.V. The Netherlands
+16ca CENATEK Inc
+ 0001 Rocket Drive DL
+16cd Densitron Technologies
+16ce Roland Corp.
+16d5 Acromag, Inc.
+ 4d4e PMC482, APC482, AcPC482 Counter Timer Board
+16df PIKA Technologies Inc.
+16e3 European Space Agency
+ 1e0f LEON2FT Processor
+16ec U.S. Robotics
+ 00ff USR997900 10/100 Mbps PCI Network Card
+ 0116 USR997902 10/100/1000 Mbps PCI Network Card
+ 3685 Wireless Access PCI Adapter Model 022415
+16ed Sycron N. V.
+ 1001 UMIO communication card
+16f3 Jetway Information Co., Ltd.
+16f4 Vweb Corp
+ 8000 VW2010
+16f6 VideoTele.com, Inc.
+1702 Internet Machines Corporation (IMC)
+1705 Digital First, Inc.
+170b NetOctave
+ 0100 NSP2000-SSL crypto accelerator
+170c YottaYotta Inc.
+# Seems to be a 2nd ID for Vitesse Semiconductor
+1725 Vitesse Semiconductor
+ 7174 VSC7174 PCI/PCI-X Serial ATA Host Bus Controller
+172a Accelerated Encryption
+ 13c8 AEP SureWare Runner 1000V3
+1734 Fujitsu Siemens Computer GmbH
+ 1078 Amilo Pro v2010
+1737 Linksys
+ 0013 WMP54G Wireless Pci Card
+ 0015 WMP54GS Wireless Pci Card
+ 1032 Gigabit Network Adapter
+ 1737 0015 EG1032 v2 Instant Gigabit Network Adapter
+ 1737 0024 EG1032 v3 Instant Gigabit Network Adapter
+ 1064 Gigabit Network Adapter
+ 1737 0016 EG1064 v2 Instant Gigabit Network Adapter
+ ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
+ ab09 21x4x DEC-Tulip compatible 10/100 Ethernet
+173b Altima (nee Broadcom)
+ 03e8 AC1000 Gigabit Ethernet
+ 03e9 AC1001 Gigabit Ethernet
+ 03ea AC9100 Gigabit Ethernet
+ 173b 0001 AC1002
+ 03eb AC1003 Gigabit Ethernet
+1743 Peppercon AG
+ 8139 ROL/F-100 Fast Ethernet Adapter with ROL
+1749 RLX Technologies
+174b PC Partner Limited
+174d WellX Telecom SA
+175c AudioScience Inc
+175e Sanera Systems, Inc.
+1775 SBS Technologies
+1787 Hightech Information System Ltd.
+# also used by Struck Innovative Systeme for joint developments
+1796 Research Centre Juelich
+ 0001 SIS1100 [Gigabit link]
+ 0002 HOTlink
+ 0003 Counter Timer
+ 0004 CAMAC Controller
+ 0005 PROFIBUS
+ 0006 AMCC HOTlink
+1797 JumpTec h, GMBH
+1799 Belkin
+ 6001 Wireless PCI Card - F5D6001
+ 6020 Wireless PCMCIA Card - F5D6020
+ 6060 Wireless PDA Card - F5D6060
+ 7000 Wireless PCI Card - F5D7000
+ 700a Wireless PCI Card - F5D7000UK
+ 7010 BCM4306 802.11b/g Wireless Lan Controller F5D7010
+179c Data Patterns
+ 0557 DP-PCI-557 [PCI 1553B]
+ 0566 DP-PCI-566 [Intelligent PCI 1553B]
+ 5031 DP-CPCI-5031-Synchro Module
+ 5121 DP-CPCI-5121-IP Carrier
+ 5211 DP-CPCI-5211-IP Carrier
+ 5679 AGE Display Module
+17a0 Genesys Logic, Inc
+ 8033 GL880S USB 1.1 controller
+ 8034 GL880S USB 2.0 controller
+17aa Lenovo
+17af Hightech Information System Ltd.
+17b3 Hawking Technologies
+ ab08 PN672TX 10/100 Ethernet
+17b4 Indra Networks, Inc.
+ 0011 WebEnhance 100 GZIP Compression Card
+17c0 Wistron Corp.
+17c2 Newisys, Inc.
+17cb Airgo Networks Inc
+ 0001 AGN100 802.11 a/b/g True MIMO Wireless Card
+ 0002 AGN300 802.11 a/b/g True MIMO Wireless Card
+17cc NetChip Technology, Inc
+ 2280 USB 2.0
+17cf Z-Com, Inc.
+17d3 Areca Technology Corp.
+ 1110 ARC-1110 4-Port PCI-X to SATA RAID Controller
+ 1120 ARC-1120 8-Port PCI-X to SATA RAID Controller
+ 1130 ARC-1130 12-Port PCI-X to SATA RAID Controller
+ 1160 ARC-1160 16-Port PCI-X to SATA RAID Controller
+ 1210 ARC-1210 4-Port PCI-Express to SATA RAID Controller
+ 1220 ARC-1220 8-Port PCI-Express to SATA RAID Controller
+ 1230 ARC-1230 12-Port PCI-Express to SATA RAID Controller
+ 1260 ARC-1260 16-Port PCI-Express to SATA RAID Controller
+17d5 S2io Inc.
+ 5831 Xframe 10 Gigabit Ethernet PCI-X
+ 103c 12d5 HP PCI-X 133MHz 10GbE SR Fiber
+ 10a9 8020 Single Port 10 Gigabit Ethernet (PCI-X, Fiber)
+ 10a9 8024 Single Port 10 Gigabit Ethernet (PCI-X, Fiber)
+ 5832 Xframe II 10Gbps Ethernet
+ 10a9 8021 Single Port 10 Gigabit Ethernet II (PCI-X, Fiber)
+17db Cray Inc
+17de KWorld Computer Co. Ltd.
+17ee Connect Components Ltd
+17f2 Albatron Corp.
+17fe Linksys, A Division of Cisco Systems
+ 2120 WMP11v4 802.11b PCI card
+ 2220 [AirConn] INPROCOMM IPN 2220 Wireless LAN Adapter (rev 01)
+ 17fe 2220 WPC54G ver. 4
+17ff Benq Corporation
+1809 Lumanate, Inc.
+1813 Ambient Technologies Inc
+ 4000 HaM controllerless modem
+ 16be 0001 V9x HAM Data Fax Modem
+ 4100 HaM plus Data Fax Modem
+ 16be 0002 V9x HAM 1394
+1814 RaLink
+ 0101 Wireless PCI Adapter RT2400 / RT2460
+ 1043 0127 WiFi-b add-on Card
+ 1462 6828 PC11B2 (MS-6828) Wireless 11b PCI Card
+ 0200 RT2500 802.11g PCI [PC54G2]
+ 0201 RT2500 802.11g Cardbus/mini-PCI
+ 1043 130f WL-130g
+ 1371 001e CWC-854 Wireless-G CardBus Adapter
+ 1371 001f CWM-854 Wireless-G Mini PCI Adapter
+ 1371 0020 CWP-854 Wireless-G PCI Adapter
+ 1458 e381 GN-WMKG 802.11b/g Wireless CardBus Adapter
+ 1458 e931 GN-WIKG 802.11b/g mini-PCI Adapter
+ 1462 6835 Wireless 11G CardBus CB54G2
+ 1737 0032 WMP54G 2.0 PCI Adapter
+ 1799 700a F5D7000 Wireless G Desktop Network Card
+ 1799 701a F5D7010 Wireless G Notebook Network Card
+ 185f 22a0 CN-WF513 Wireless Cardbus Adapter
+ 0301 RT2561/RT61 802.11g PCI
+ 1186 3c08 DWL-G630 Rev E
+ 1186 3c09 DWL-G510 Rev C
+ 1737 0055 WMP54G ver 4.1
+ 0302 RT2561/RT61 rev B 802.11g
+ 1186 3c08 DWL-G630 Rev E
+ 1186 3c09 DWL-G510 Rev C
+ 0401 Ralink RT2600 802.11 MIMO
+1820 InfiniCon Systems Inc.
+1822 Twinhan Technology Co. Ltd
+ 4e35 Mantis DTV PCI Bridge Controller [Ver 1.0]
+182d SiteCom Europe BV
+# HFC-based ISDN card
+ 3069 ISDN PCI DC-105V2
+ 9790 WL-121 Wireless Network Adapter 100g+ [Ver.3]
+182e Raza Microelectronics, Inc.
+ 0008 XLR516 Processor
+1830 Credence Systems Corporation
+183b MikroM GmbH
+ 08a7 MVC100 DVI
+ 08a8 MVC101 SDI
+ 08a9 MVC102 DVI+Audio
+ 08b0 MVC200-DC
+1849 ASRock Incorporation
+1851 Microtune, Inc.
+1852 Anritsu Corp.
+1853 SMSC Automotive Infotainment System Group
+1854 LG Electronics, Inc.
+185b Compro Technology, Inc.
+185f Wistron NeWeb Corp.
+1864 SilverBack
+ 2110 ISNAP 2110
+1867 Topspin Communications
+ 5a44 MT23108 InfiniHost HCA
+ 5a45 MT23108 InfiniHost HCA flash recovery
+ 5a46 MT23108 InfiniHost HCA bridge
+ 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
+ 6282 MT25208 InfiniHost III Ex
+187e ZyXEL Communication Corporation
+ 3403 ZyAir G-110 802.11g
+ 340e M-302 802.11g XtremeMIMO
+1888 Varisys Ltd
+ 0301 VMFX1 FPGA PMC module
+ 0601 VSM2 dual PMC carrier
+ 0710 VS14x series PowerPC PCI board
+ 0720 VS24x series PowerPC PCI board
+188a Ample Communications, Inc
+1890 Egenera, Inc.
+1894 KNC One
+1896 B&B Electronics Manufacturing Company, Inc.
+18a1 Astute Networks Inc.
+18ac DViCO Corporation
+ d500 FusionHDTV 5
+ d800 FusionHDTV 3 Gold
+ d810 FusionHDTV 3 Gold-Q
+ d820 FusionHDTV 3 Gold-T
+18b8 Ammasso
+ b001 AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor
+18bc Info-Tek Corp.
+18c3 Micronas Semiconductor Holding AG
+# Nee Octigabay System
+18c8 Cray Inc
+18c9 ARVOO Engineering BV
+18ca XGI - Xabre Graphics Inc
+ 0020 Volari Z7
+ 0040 Volari V3XT/V5/V8
+18d2 Sitecom
+# Sitecom HFC-S based ISDN controller card DC-105v2
+ 3069 DC-105v2 ISDN controller
+18dd Artimi Inc
+ 4c6f Artimi RTMI-100 UWB adapter
+18e6 MPL AG
+ 0001 OSCI [Octal Serial Communication Interface]
+18ec Cesnet, z.s.p.o.
+ c006 COMBO6
+ 18ec d001 COMBO-4MTX
+ 18ec d002 COMBO-4SFP
+ 18ec d003 COMBO-4SFPRO
+ 18ec d004 COMBO-2XFP
+ c045 COMBO6E
+ c050 COMBO-PTM
+ c058 COMBO6X
+ 18ec d001 COMBO-4MTX
+ 18ec d002 COMBO-4SFP
+ 18ec d003 COMBO-4SFPRO
+ 18ec d004 COMBO-2XFP
+18f6 NextIO
+ 1000 [Nexsis] Switch Virtual P2P PCIe Bridge
+ 1050 [Nexsis] Switch Virtual P2P PCI Bridge
+ 2000 [Nexsis] Switch Integrated Mgmt. Endpoint
+18f7 Commtech, Inc.
+ 0001 Fastcom ESCC-PCI-335
+ 0002 Fastcom 422/4-PCI-335
+ 0004 Fastcom 422/2-PCI-335
+ 0005 Fastcom IGESCC-PCI-ISO/1
+ 000a Fastcom 232/4-PCI-335
+18fb Resilience Corporation
+1904 Hangzhou Silan Microelectronics Co., Ltd.
+ 8139 RTL8139D [Realtek] PCI 10/100BaseTX ethernet adaptor
+1923 Sangoma Technologies Corp.
+ 0040 A200/Remora FXO/FXS Analog AFT card
+ 0100 A104d QUAD T1/E1 AFT card
+ 0300 A101 single-port T1/E1
+ 0400 A104u Quad T1/E1 AFT
+1924 Level 5 Networks Inc.
+192e TransDimension
+1931 Option N.V.
+ 000c Qualcomm MSM6275 UMTS chip
+1942 ClearSpeed Technology plc
+ e511 CSX600 Advance Accelerator Board
+1957 Freescale Semiconductor Inc
+ 0080 MPC8349E
+ 0081 MPC8349
+ 0082 MPC8347E TBGA
+ 0083 MPC8347 TBGA
+ 0084 MPC8347E PBGA
+ 0085 MPC8347 PBGA
+ 0086 MPC8343E
+ 0087 MPC8343
+1958 Faster Technology, LLC.
+1966 Orad Hi-Tec Systems
+ 1975 DVG64 family
+196a Sensory Networks Inc.
+ 0101 NodalCore C-1000 Content Classification Accelerator
+ 0102 NodalCore C-2000 Content Classification Accelerator
+196d Club-3D BV
+197b JMicron Technologies, Inc.
+ 2360 JMicron 20360/20363 AHCI Controller
+ 2361 JMB361 AHCI/IDE
+ 2363 JMicron 20360/20363 AHCI Controller
+ 2365 JMB365 AHCI/IDE
+ 2366 JMB366 AHCI/IDE
+1989 Montilio Inc.
+ 0001 RapidFile Bridge
+ 8001 RapidFile
+1993 Innominate Security Technologies AG
+199a Pulse-LINK, Inc.
+19a8 DAQDATA GmbH
+19ac Kasten Chase Applied Research
+ 0001 ACA2400 Crypto Accelerator
+19ae Progeny Systems Corporation
+ 0520 4135 HFT Interface Controller
+19d4 Quixant Limited
+19e2 Vector Informatik GmbH
+1a03 ASPEED Technology, Inc.
+ 2000 AST2000
+1a08 Sierra semiconductor
+ 0000 SC15064
+1a1d GFaI e.V.
+1a29 Fortinet, Inc.
+1b13 Jaton Corp
+1c1c Symphony
+ 0001 82C101
+1d44 DPT
+ a400 PM2x24/PM3224
+1de1 Tekram Technology Co.,Ltd.
+ 0391 TRM-S1040
+ 2020 DC-390
+ 690c 690c
+ dc29 DC290
+1fc0 Tumsan Oy
+ 0300 E2200 Dual E1/Rawpipe Card
+1fc1 PathScale, Inc
+ 000d InfiniPath HT-400
+ 0010 InfiniPath PE-800
+1fce Cognio Inc.
+ 0001 Spectrum Analyzer PC Card (SAgE)
+2000 Smart Link Ltd.
+2001 Temporal Research Ltd
+2003 Smart Link Ltd.
+2004 Smart Link Ltd.
+21c3 21st Century Computer Corp.
+# (Probably only the Mobile Phone Division)
+22b8 Motorola, Inc.
+2348 Racore
+ 2010 8142 100VG/AnyLAN
+2646 Kingston Technologies
+270b Xantel Corporation
+270f Chaintech Computer Co. Ltd
+2711 AVID Technology Inc.
+2a15 3D Vision(???)
+3000 Hansol Electronics Inc.
+3142 Post Impression Systems.
+3388 Hint Corp
+ 0013 HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
+ 0014 HiNT HC4 PCI to ISDN bridge, Network controller
+ 0020 HB6 Universal PCI-PCI bridge (transparent mode)
+ 0021 HB6 Universal PCI-PCI bridge (non-transparent mode)
+ 1775 ce90 CE9
+ 4c53 1050 CT7 mainboard
+ 4c53 1080 CT8 mainboard
+ 4c53 1090 Cx9 mainboard
+ 4c53 10a0 CA3/CR3 mainboard
+ 4c53 3010 PPCI mezzanine (32-bit PMC)
+ 4c53 3011 PPCI mezzanine (64-bit PMC)
+ 4c53 4000 PMCCARR1 carrier board
+ 0022 HiNT HB4 PCI-PCI Bridge (PCI6150)
+ 0026 HB2 PCI-PCI Bridge
+ 101a E.Band [AudioTrak Inca88]
+ 101b E.Band [AudioTrak Inca88]
+ 8011 VXPro II Chipset
+ 3388 8011 VXPro II Chipset CPU to PCI Bridge
+ 8012 VXPro II Chipset
+ 3388 8012 VXPro II Chipset PCI to ISA Bridge
+ 8013 VXPro II IDE
+ 3388 8013 VXPro II Chipset EIDE Controller
+3411 Quantum Designs (H.K.) Inc
+3513 ARCOM Control Systems Ltd
+3842 eVga.com. Corp.
+ c370 e-GeFORCE 6600 256 DDR PCI-e
+38ef 4Links
+3d3d 3DLabs
+ 0001 GLINT 300SX
+ 0002 GLINT 500TX
+ 0000 0000 GLoria L
+ 0003 GLINT Delta
+ 0000 0000 GLoria XL
+ 0004 Permedia
+ 0005 Permedia
+ 0006 GLINT MX
+ 0000 0000 GLoria XL
+ 1048 0a42 GLoria XXL
+ 0007 3D Extreme
+ 0008 GLINT Gamma G1
+ 1048 0a42 GLoria XXL
+ 0009 Permedia II 2D+3D
+ 1040 0011 AccelStar II
+ 1048 0a42 GLoria XXL
+ 13e9 1000 6221L-4U
+ 3d3d 0100 AccelStar II 3D Accelerator
+ 3d3d 0111 Permedia 3:16
+ 3d3d 0114 Santa Ana
+ 3d3d 0116 Oxygen GVX1
+ 3d3d 0119 Scirocco
+ 3d3d 0120 Santa Ana PCL
+ 3d3d 0125 Oxygen VX1
+ 3d3d 0127 Permedia3 Create!
+ 000a GLINT R3
+ 3d3d 0121 Oxygen VX1
+ 000c GLINT R3 [Oxygen VX1]
+ 3d3d 0144 Oxygen VX1-4X AGP [Permedia 4]
+ 000d GLint R4 rev A
+ 0011 GLint R4 rev B
+ 0012 GLint R5 rev A
+ 0013 GLint R5 rev B
+ 0020 VP10 visual processor
+ 0022 VP10 visual processor
+ 0024 VP9 visual processor
+ 0100 Permedia II 2D+3D
+ 07a1 Wildcat III 6210
+ 07a2 Sun XVR-500 Graphics Accelerator
+ 07a3 Wildcat IV 7210
+ 1004 Permedia
+ 3d04 Permedia
+ ffff Glint VGA
+4005 Avance Logic Inc.
+ 0300 ALS300 PCI Audio Device
+ 0308 ALS300+ PCI Audio Device
+ 0309 PCI Input Controller
+ 1064 ALG-2064
+ 2064 ALG-2064i
+ 2128 ALG-2364A GUI Accelerator
+ 2301 ALG-2301
+ 2302 ALG-2302
+ 2303 AVG-2302 GUI Accelerator
+ 2364 ALG-2364A
+ 2464 ALG-2464
+ 2501 ALG-2564A/25128A
+ 4000 ALS4000 Audio Chipset
+ 4005 4000 ALS4000 Audio Chipset
+ 4710 ALC200/200P
+4033 Addtron Technology Co, Inc.
+ 1360 RTL8139 Ethernet
+4143 Digital Equipment Corp
+4144 Alpha Data
+ 0044 ADM-XRCIIPro
+416c Aladdin Knowledge Systems
+ 0100 AladdinCARD
+ 0200 CPC
+4321 Tata Power Strategic Electronics Division
+4444 Internext Compression Inc
+ 0016 iTVC16 (CX23416) MPEG-2 Encoder
+ 0070 0003 WinTV PVR 250
+ 0070 0009 WinTV PVR 150
+ 0070 0801 WinTV PVR 150
+ 0070 0807 WinTV PVR 150
+ 0070 4001 WinTV PVR 250
+ 0070 4009 WinTV PVR 250
+ 0070 4801 WinTV PVR 250
+ 0070 4803 WinTV PVR 250
+ 0070 8003 WinTV PVR 150
+ 0070 8801 WinTV PVR 150
+ 0070 c801 WinTV PVR 150
+ 0070 e807 WinTV PVR 500 (1st unit)
+ 0070 e817 WinTV PVR 500 (2nd unit)
+ 0070 ff92 WiNTV PVR-550
+ 0270 0801 WinTV PVR 150
+ 12ab fff3 MPG600
+ 12ab ffff MPG600
+ 9005 0092 VideOh! AVC-2010
+ 9005 0093 VideOh! AVC-2410
+ ffab 0600 ZAP-TV1001 MCE
+ 0803 iTVC15 MPEG-2 Encoder
+ 0070 4000 WinTV PVR-350
+ 0070 4001 WinTV PVR-250
+ 0070 4800 WinTV PVR-350 (V1)
+ 12ab 0000 MPG160
+ 1461 a3ce M179
+# video capture card
+ 1461 a3cf M179
+4468 Bridgeport machines
+4594 Cogetec Informatique Inc
+45fb Baldor Electric Company
+4680 Umax Computer Corp
+4843 Hercules Computer Technology Inc
+4916 RedCreek Communications Inc
+ 1960 RedCreek PCI adapter
+4943 Growth Networks
+494f ACCES I/O Products, Inc.
+ 10e8 LPCI-COM-8SM
+4978 Axil Computer Inc
+4a14 NetVin
+ 5000 NV5000SC
+ 4a14 5000 RT8029-Based Ethernet Adapter
+4b10 Buslogic Inc.
+4c48 LUNG HWA Electronics
+4c53 SBS Technologies
+ 0000 PLUSTEST device
+ 4c53 3000 PLUSTEST card (PC104+)
+ 4c53 3001 PLUSTEST card (PMC)
+ 0001 PLUSTEST-MM device
+ 4c53 3002 PLUSTEST-MM card (PMC)
+4ca1 Seanix Technology Inc
+4d51 MediaQ Inc.
+ 0200 MQ-200
+4d54 Microtechnica Co Ltd
+4ddc ILC Data Device Corp
+ 0100 DD-42924I5-300 (ARINC 429 Data Bus)
+ 0801 BU-65570I1 MIL-STD-1553 Test and Simulation
+ 0802 BU-65570I2 MIL-STD-1553 Test and Simulation
+ 0811 BU-65572I1 MIL-STD-1553 Test and Simulation
+ 0812 BU-65572I2 MIL-STD-1553 Test and Simulation
+ 0881 BU-65570T1 MIL-STD-1553 Test and Simulation
+ 0882 BU-65570T2 MIL-STD-1553 Test and Simulation
+ 0891 BU-65572T1 MIL-STD-1553 Test and Simulation
+ 0892 BU-65572T2 MIL-STD-1553 Test and Simulation
+ 0901 BU-65565C1 MIL-STD-1553 Data Bus
+ 0902 BU-65565C2 MIL-STD-1553 Data Bus
+ 0903 BU-65565C3 MIL-STD-1553 Data Bus
+ 0904 BU-65565C4 MIL-STD-1553 Data Bus
+ 0b01 BU-65569I1 MIL-STD-1553 Data Bus
+ 0b02 BU-65569I2 MIL-STD-1553 Data Bus
+ 0b03 BU-65569I3 MIL-STD-1553 Data Bus
+ 0b04 BU-65569I4 MIL-STD-1553 Data Bus
+5046 GemTek Technology Corporation
+ 1001 PCI Radio
+5053 Voyetra Technologies
+ 2010 Daytona Audio Adapter
+5136 S S Technologies
+5143 Qualcomm Inc
+5145 Ensoniq (Old)
+ 3031 Concert AudioPCI
+5168 Animation Technologies Inc.
+ 0300 FlyDVB-S
+ 0301 FlyDVB-T
+5301 Alliance Semiconductor Corp.
+ 0001 ProMotion aT3D
+5333 S3 Inc.
+ 0551 Plato/PX (system)
+ 5631 86c325 [ViRGE]
+ 8800 86c866 [Vision 866]
+ 8801 86c964 [Vision 964]
+ 8810 86c764_0 [Trio 32 vers 0]
+ 8811 86c764/765 [Trio32/64/64V+]
+ 8812 86cM65 [Aurora64V+]
+ 8813 86c764_3 [Trio 32/64 vers 3]
+ 8814 86c767 [Trio 64UV+]
+ 8815 86cM65 [Aurora 128]
+ 883d 86c988 [ViRGE/VX]
+ 8870 FireGL
+ 8880 86c868 [Vision 868 VRAM] vers 0
+ 8881 86c868 [Vision 868 VRAM] vers 1
+ 8882 86c868 [Vision 868 VRAM] vers 2
+ 8883 86c868 [Vision 868 VRAM] vers 3
+ 88b0 86c928 [Vision 928 VRAM] vers 0
+ 88b1 86c928 [Vision 928 VRAM] vers 1
+ 88b2 86c928 [Vision 928 VRAM] vers 2
+ 88b3 86c928 [Vision 928 VRAM] vers 3
+ 88c0 86c864 [Vision 864 DRAM] vers 0
+ 88c1 86c864 [Vision 864 DRAM] vers 1
+ 88c2 86c864 [Vision 864-P DRAM] vers 2
+ 88c3 86c864 [Vision 864-P DRAM] vers 3
+ 88d0 86c964 [Vision 964 VRAM] vers 0
+ 88d1 86c964 [Vision 964 VRAM] vers 1
+ 88d2 86c964 [Vision 964-P VRAM] vers 2
+ 88d3 86c964 [Vision 964-P VRAM] vers 3
+ 88f0 86c968 [Vision 968 VRAM] rev 0
+ 88f1 86c968 [Vision 968 VRAM] rev 1
+ 88f2 86c968 [Vision 968 VRAM] rev 2
+ 88f3 86c968 [Vision 968 VRAM] rev 3
+ 8900 86c755 [Trio 64V2/DX]
+ 5333 8900 86C775 Trio64V2/DX
+ 8901 86c775/86c785 [Trio 64V2/DX or /GX]
+ 5333 8901 86C775 Trio64V2/DX, 86C785 Trio64V2/GX
+ 8902 Plato/PX
+ 8903 Trio 3D business multimedia
+ 8904 Trio 64 3D
+ 1014 00db Integrated Trio3D
+ 5333 8904 86C365 Trio3D AGP
+ 8905 Trio 64V+ family
+ 8906 Trio 64V+ family
+ 8907 Trio 64V+ family
+ 8908 Trio 64V+ family
+ 8909 Trio 64V+ family
+ 890a Trio 64V+ family
+ 890b Trio 64V+ family
+ 890c Trio 64V+ family
+ 890d Trio 64V+ family
+ 890e Trio 64V+ family
+ 890f Trio 64V+ family
+ 8a01 ViRGE/DX or /GX
+ 0e11 b032 ViRGE/GX
+ 10b4 1617 Nitro 3D
+ 10b4 1717 Nitro 3D
+ 5333 8a01 ViRGE/DX
+ 8a10 ViRGE/GX2
+ 1092 8a10 Stealth 3D 4000
+ 8a13 86c368 [Trio 3D/2X]
+ 5333 8a13 Trio3D/2X
+ 8a20 86c794 [Savage 3D]
+ 5333 8a20 86C391 Savage3D
+ 8a21 86c390 [Savage 3D/MV]
+ 5333 8a21 86C390 Savage3D/MV
+ 8a22 Savage 4
+ 1033 8068 Savage 4
+ 1033 8069 Savage 4
+ 1033 8110 Savage 4 LT
+ 105d 0018 SR9 8Mb SDRAM
+ 105d 002a SR9 Pro 16Mb SDRAM
+ 105d 003a SR9 Pro 32Mb SDRAM
+ 105d 092f SR9 Pro+ 16Mb SGRAM
+ 1092 4207 Stealth III S540
+ 1092 4800 Stealth III S540
+ 1092 4807 SpeedStar A90
+ 1092 4808 Stealth III S540
+ 1092 4809 Stealth III S540
+ 1092 480e Stealth III S540
+ 1092 4904 Stealth III S520
+ 1092 4905 SpeedStar A200
+ 1092 4a09 Stealth III S540
+ 1092 4a0b Stealth III S540 Xtreme
+ 1092 4a0f Stealth III S540
+ 1092 4e01 Stealth III S540
+ 1102 101d 3d Blaster Savage 4
+ 1102 101e 3d Blaster Savage 4
+ 5333 8100 86C394-397 Savage4 SDRAM 100
+ 5333 8110 86C394-397 Savage4 SDRAM 110
+ 5333 8125 86C394-397 Savage4 SDRAM 125
+ 5333 8143 86C394-397 Savage4 SDRAM 143
+ 5333 8a22 86C394-397 Savage4
+ 5333 8a2e 86C394-397 Savage4 32bit
+ 5333 9125 86C394-397 Savage4 SGRAM 125
+ 5333 9143 86C394-397 Savage4 SGRAM 143
+ 8a23 Savage 4
+ 8a25 ProSavage PM133
+ 8a26 ProSavage KM133
+ 8c00 ViRGE/M3
+ 8c01 ViRGE/MX
+ 1179 0001 ViRGE/MX
+ 8c02 ViRGE/MX+
+ 8c03 ViRGE/MX+MV
+ 8c10 86C270-294 Savage/MX-MV
+ 8c11 82C270-294 Savage/MX
+ 8c12 86C270-294 Savage/IX-MV
+ 1014 017f Thinkpad T20/T22
+ 1179 0001 86C584 SuperSavage/IXC Toshiba
+ 8c13 86C270-294 Savage/IX
+ 1179 0001 Magnia Z310
+ 8c22 SuperSavage MX/128
+ 8c24 SuperSavage MX/64
+ 8c26 SuperSavage MX/64C
+ 8c2a SuperSavage IX/128 SDR
+ 8c2b SuperSavage IX/128 DDR
+ 8c2c SuperSavage IX/64 SDR
+ 8c2d SuperSavage IX/64 DDR
+ 8c2e SuperSavage IX/C SDR
+ 1014 01fc ThinkPad T23 (2647-4MG)
+ 8c2f SuperSavage IX/C DDR
+ 8d01 86C380 [ProSavageDDR K4M266]
+ 8d02 VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
+ 8d03 VT8751 [ProSavageDDR P4M266]
+ 8d04 VT8375 [ProSavage8 KM266/KL266]
+ 9102 86C410 Savage 2000
+ 1092 5932 Viper II Z200
+ 1092 5934 Viper II Z200
+ 1092 5952 Viper II Z200
+ 1092 5954 Viper II Z200
+ 1092 5a35 Viper II Z200
+ 1092 5a37 Viper II Z200
+ 1092 5a55 Viper II Z200
+ 1092 5a57 Viper II Z200
+ ca00 SonicVibes
+544c Teralogic Inc
+ 0350 TL880-based HDTV/ATSC tuner
+5455 Technische University Berlin
+ 4458 S5933
+5519 Cnet Technologies, Inc.
+5544 Dunord Technologies
+ 0001 I-30xx Scanner Interface
+5555 Genroco, Inc
+ 0003 TURBOstor HFP-832 [HiPPI NIC]
+5654 VoiceTronix Pty Ltd
+ 3132 OpenSwitch12
+5700 Netpower
+5851 Exacq Technologies
+6356 UltraStor
+6374 c't Magazin fuer Computertechnik
+ 6773 GPPCI
+6409 Logitec Corp.
+6666 Decision Computer International Co.
+ 0001 PCCOM4
+ 0002 PCCOM8
+ 0004 PCCOM2
+ 0101 PCI 8255/8254 I/O Card
+7063 pcHDTV
+ 2000 HD-2000
+ 3000 HD-3000
+ 5500 HD5500 HDTV
+7604 O.N. Electronic Co Ltd.
+7bde MIDAC Corporation
+7fed PowerTV
+8008 Quancom Electronic GmbH
+ 0010 WDOG1 [PCI-Watchdog 1]
+ 0011 PWDOG2 [PCI-Watchdog 2]
+# Wrong ID used in subsystem ID of AsusTek PCI-USB2 PCI card.
+807d Asustek Computer, Inc.
+8086 Intel Corporation
+ 0007 82379AB
+ 0008 Extended Express System Support Controller
+ 0039 21145 Fast Ethernet
+ 0122 82437FX
+ 0309 80303 I/O Processor PCI-to-PCI Bridge
+ 030d 80312 I/O Companion Chip PCI-to-PCI Bridge
+ 0326 6700/6702PXH I/OxAPIC Interrupt Controller A
+ 0327 6700PXH I/OxAPIC Interrupt Controller B
+ 0329 6700PXH PCI Express-to-PCI Bridge A
+ 032a 6700PXH PCI Express-to-PCI Bridge B
+ 032c 6702PXH PCI Express-to-PCI Bridge A
+ 0330 80332 [Dobson] I/O processor (A-Segment Bridge)
+ 0331 80332 [Dobson] I/O processor (A-Segment IOAPIC)
+ 0332 80332 [Dobson] I/O processor (B-Segment Bridge)
+ 0333 80332 [Dobson] I/O processor (B-Segment IOAPIC)
+ 0334 80332 [Dobson] I/O processor (ATU)
+ 0335 80331 [Lindsay] I/O processor (PCI-X Bridge)
+ 0336 80331 [Lindsay] I/O processor (ATU)
+ 0340 41210 [Lanai] Serial to Parallel PCI Bridge (A-Segment Bridge)
+ 0341 41210 [Lanai] Serial to Parallel PCI Bridge (B-Segment Bridge)
+ 0370 80333 Segment-A PCI Express-to-PCI Express Bridge
+ 0371 80333 A-Bus IOAPIC
+ 0372 80333 Segment-B PCI Express-to-PCI Express Bridge
+ 0373 80333 B-Bus IOAPIC
+ 0374 80333 Address Translation Unit
+ 0482 82375EB/SB PCI to EISA Bridge
+ 0483 82424TX/ZX [Saturn] CPU to PCI bridge
+ 0484 82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge
+ 0486 82425EX/ZX [Aries] PCIset with ISA bridge
+ 04a3 82434LX/NX [Mercury/Neptune] Processor to PCI bridge
+ 04d0 82437FX [Triton FX]
+ 0500 E8870 Processor bus control
+ 0501 E8870 Memory controller
+# and registers common to both SPs
+ 0502 E8870 Scalability Port 0
+# and global performance monitoring
+ 0503 E8870 Scalability Port 1
+ 0510 E8870IO Hub Interface Port 0 registers (8-bit compatibility port)
+ 0511 E8870IO Hub Interface Port 1 registers
+ 0512 E8870IO Hub Interface Port 2 registers
+ 0513 E8870IO Hub Interface Port 3 registers
+ 0514 E8870IO Hub Interface Port 4 registers
+ 0515 E8870IO General SIOH registers
+ 0516 E8870IO RAS registers
+ 0530 E8870SP Scalability Port 0 registers
+ 0531 E8870SP Scalability Port 1 registers
+ 0532 E8870SP Scalability Port 2 registers
+ 0533 E8870SP Scalability Port 3 registers
+ 0534 E8870SP Scalability Port 4 registers
+ 0535 E8870SP Scalability Port 5 registers
+# (bi-interleave 0) and global registers that are neither per-port nor per-interleave
+ 0536 E8870SP Interleave registers 0 and 1
+# (bi-interleave 1)
+ 0537 E8870SP Interleave registers 2 and 3
+ 0600 RAID Controller
+ 8086 01af SRCZCR
+ 8086 01c1 ICP Vortex GDT8546RZ
+ 8086 01f7 SCRU32
+# uninitialized SRCU32 RAID Controller
+ 061f 80303 I/O Processor
+ 0960 80960RP [i960 RP Microprocessor/Bridge]
+ 0962 80960RM [i960RM Bridge]
+ 0964 80960RP [i960 RP Microprocessor/Bridge]
+ 1000 82542 Gigabit Ethernet Controller
+ 0e11 b0df NC1632 Gigabit Ethernet Adapter (1000-SX)
+ 0e11 b0e0 NC1633 Gigabit Ethernet Adapter (1000-LX)
+ 0e11 b123 NC1634 Gigabit Ethernet Adapter (1000-SX)
+ 1014 0119 Netfinity Gigabit Ethernet SX Adapter
+ 8086 1000 PRO/1000 Gigabit Server Adapter
+ 1001 82543GC Gigabit Ethernet Controller (Fiber)
+ 0e11 004a NC6136 Gigabit Server Adapter
+ 1014 01ea Netfinity Gigabit Ethernet SX Adapter
+ 8086 1002 PRO/1000 F Server Adapter
+ 8086 1003 PRO/1000 F Server Adapter
+ 1002 Pro 100 LAN+Modem 56 Cardbus II
+ 8086 200e Pro 100 LAN+Modem 56 Cardbus II
+ 8086 2013 Pro 100 SR Mobile Combo Adapter
+ 8086 2017 Pro 100 S Combo Mobile Adapter
+ 1004 82543GC Gigabit Ethernet Controller (Copper)
+ 0e11 0049 NC7132 Gigabit Upgrade Module
+ 0e11 b1a4 NC7131 Gigabit Server Adapter
+ 1014 10f2 Gigabit Ethernet Server Adapter
+ 8086 1004 PRO/1000 T Server Adapter
+ 8086 2004 PRO/1000 T Server Adapter
+ 1008 82544EI Gigabit Ethernet Controller (Copper)
+ 1014 0269 iSeries 1000/100/10 Ethernet Adapter
+ 1028 011c PRO/1000 XT Network Connection
+ 8086 1107 PRO/1000 XT Server Adapter
+ 8086 2107 PRO/1000 XT Server Adapter
+ 8086 2110 PRO/1000 XT Server Adapter
+ 8086 3108 PRO/1000 XT Network Connection
+ 1009 82544EI Gigabit Ethernet Controller (Fiber)
+ 1014 0268 iSeries Gigabit Ethernet Adapter
+ 8086 1109 PRO/1000 XF Server Adapter
+ 8086 2109 PRO/1000 XF Server Adapter
+ 100a 82540EM Gigabit Ethernet Controller
+ 100c 82544GC Gigabit Ethernet Controller (Copper)
+ 8086 1112 PRO/1000 T Desktop Adapter
+ 8086 2112 PRO/1000 T Desktop Adapter
+ 100d 82544GC Gigabit Ethernet Controller (LOM)
+ 1028 0123 PRO/1000 XT Network Connection
+ 1079 891f 82544GC Based Network Connection
+ 4c53 1080 CT8 mainboard
+ 8086 110d 82544GC Based Network Connection
+ 100e 82540EM Gigabit Ethernet Controller
+ 1014 0265 PRO/1000 MT Network Connection
+ 1014 0267 PRO/1000 MT Network Connection
+ 1014 026a PRO/1000 MT Network Connection
+ 1028 002e Optiplex GX260
+ 1028 0134 PowerEdge 600SC
+ 1028 0151 PRO/1000 MT Network Connection
+ 107b 8920 PRO/1000 MT Desktop Adapter
+ 8086 001e PRO/1000 MT Desktop Adapter
+ 8086 002e PRO/1000 MT Desktop Adapter
+ 8086 1376 PRO/1000 GT Desktop Adapter
+ 8086 1476 PRO/1000 GT Desktop Adapter
+ 100f 82545EM Gigabit Ethernet Controller (Copper)
+ 1014 0269 iSeries 1000/100/10 Ethernet Adapter
+ 1014 028e PRO/1000 MT Network Connection
+ 8086 1000 PRO/1000 MT Network Connection
+ 8086 1001 PRO/1000 MT Server Adapter
+ 1010 82546EB Gigabit Ethernet Controller (Copper)
+ 0e11 00db NC7170 Gigabit Server Adapter
+ 1014 027c PRO/1000 MT Dual Port Network Adapter
+ 18fb 7872 RESlink-X
+ 1fc1 0026 Niagara 2260 Bypass Card
+ 4c53 1080 CT8 mainboard
+ 4c53 10a0 CA3/CR3 mainboard
+ 8086 1011 PRO/1000 MT Dual Port Server Adapter
+ 8086 1012 PRO/1000 MT Dual Port Server Adapter
+ 8086 101a PRO/1000 MT Dual Port Network Connection
+ 8086 3424 SE7501HG2 Mainboard
+ 1011 82545EM Gigabit Ethernet Controller (Fiber)
+ 1014 0268 iSeries Gigabit Ethernet Adapter
+ 8086 1002 PRO/1000 MF Server Adapter
+ 8086 1003 PRO/1000 MF Server Adapter (LX)
+ 1012 82546EB Gigabit Ethernet Controller (Fiber)
+ 0e11 00dc NC6170 Gigabit Server Adapter
+ 8086 1012 PRO/1000 MF Dual Port Server Adapter
+ 1013 82541EI Gigabit Ethernet Controller (Copper)
+ 8086 0013 PRO/1000 MT Network Connection
+ 8086 1013 PRO/1000 MT Network Connection
+ 8086 1113 PRO/1000 MT Desktop Adapter
+ 1014 82541ER Gigabit Ethernet Controller
+ 8086 0014 PRO/1000 MT Desktop Connection
+ 8086 1014 PRO/1000 MT Network Connection
+ 1015 82540EM Gigabit Ethernet Controller (LOM)
+ 1016 82540EP Gigabit Ethernet Controller (LOM)
+ 1014 052c PRO/1000 MT Mobile Connection
+ 1179 0001 PRO/1000 MT Mobile Connection
+ 8086 1016 PRO/1000 MT Mobile Connection
+ 1017 82540EP Gigabit Ethernet Controller (LOM)
+ 8086 1017 PR0/1000 MT Desktop Connection
+ 1018 82541EI Gigabit Ethernet Controller
+ 8086 1018 PRO/1000 MT Desktop Adapter
+ 1019 82547EI Gigabit Ethernet Controller (LOM)
+ 1458 1019 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1458 e000 Intel Gigabit Ethernet (Kenai II)
+ 8086 1019 PRO/1000 CT Desktop Connection
+ 8086 301f D865PERL mainboard
+ 8086 302c Intel 82865G Mainboard (D865GBF)
+ 8086 3427 S875WP1-E mainboard
+ 101a 82547EI Gigabit Ethernet Controller (Mobile)
+ 101d 82546EB Gigabit Ethernet Controller
+ 8086 1000 PRO/1000 MT Quad Port Server Adapter
+ 101e 82540EP Gigabit Ethernet Controller (Mobile)
+ 1014 0549 PRO/1000 MT Mobile Connection
+ 1179 0001 PRO/1000 MT Mobile Connection
+ 8086 101e PRO/1000 MT Mobile Connection
+ 1026 82545GM Gigabit Ethernet Controller
+ 1028 0169 Precision 470
+ 8086 1000 PRO/1000 MT Server Connection
+ 8086 1001 PRO/1000 MT Server Adapter
+ 8086 1002 PRO/1000 MT Server Adapter
+ 8086 1026 PRO/1000 MT Server Connection
+ 1027 82545GM Gigabit Ethernet Controller
+ 103c 3103 NC310F PCI-X Gigabit Server Adapter
+ 8086 1001 PRO/1000 MF Server Adapter(LX)
+ 8086 1002 PRO/1000 MF Server Adapter(LX)
+ 8086 1003 PRO/1000 MF Server Adapter(LX)
+ 8086 1027 PRO/1000 MF Server Adapter
+ 1028 82545GM Gigabit Ethernet Controller
+ 8086 1028 PRO/1000 MB Server Connection
+ 1029 82559 Ethernet Controller
+ 1030 82559 InBusiness 10/100
+ 1031 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
+ 1014 0209 ThinkPad A/T/X Series
+ 104d 80e7 Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 104d 813c Vaio PCG-GRV616G
+ 107b 5350 EtherExpress PRO/100 VE
+ 1179 0001 EtherExpress PRO/100 VE
+ 144d c000 EtherExpress PRO/100 VE
+ 144d c001 EtherExpress PRO/100 VE
+ 144d c003 EtherExpress PRO/100 VE
+ 144d c006 vpr Matrix 170B4
+ 1032 82801CAM (ICH3) PRO/100 VE Ethernet Controller
+ 1033 82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
+ 1034 82801CAM (ICH3) PRO/100 VM Ethernet Controller
+ 1035 82801CAM (ICH3)/82562EH (LOM) Ethernet Controller
+ 1036 82801CAM (ICH3) 82562EH Ethernet Controller
+ 1037 82801CAM (ICH3) Chipset Ethernet Controller
+ 1038 82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
+ 0e11 0098 Evo N600c
+ 1039 82801DB PRO/100 VE (LOM) Ethernet Controller
+ 1014 0267 NetVista A30p
+ 103a 82801DB PRO/100 VE (CNR) Ethernet Controller
+ 103b 82801DB PRO/100 VM (LOM) Ethernet Controller
+ 103c 82801DB PRO/100 VM (CNR) Ethernet Controller
+ 103d 82801DB PRO/100 VE (MOB) Ethernet Controller
+ 103e 82801DB PRO/100 VM (MOB) Ethernet Controller
+ 1040 536EP Data Fax Modem
+ 16be 1040 V.9X DSP Data Fax Modem
+ 1043 PRO/Wireless LAN 2100 3B Mini PCI Adapter
+ 103c 08b0 tc1100 tablet
+ 8086 2527 MIM2000/Centrino
+ 1048 PRO/10GbE LR Server Adapter
+ 8086 a01f PRO/10GbE LR Server Adapter
+ 8086 a11f PRO/10GbE LR Server Adapter
+ 104a 82566DM Gigabit Network Connection
+ 104b 82566DC Gigabit Network Connection
+ 104c 82562V 10/100 Network Connection
+ 1050 82562EZ 10/100 Ethernet Controller
+ 1462 728c 865PE Neo2 (MS-6728)
+ 1462 758c MS-6758 (875P Neo)
+ 8086 3020 D865PERL mainboard
+ 8086 302f Desktop Board D865GBF
+ 8086 3427 S875WP1-E mainboard
+ 1051 82801EB/ER (ICH5/ICH5R) integrated LAN Controller
+ 1052 PRO/100 VM Network Connection
+ 1053 PRO/100 VM Network Connection
+ 1059 82551QM Ethernet Controller
+ 105e 82571EB Gigabit Ethernet Controller
+ 103c 7044 NC360T PCI Express Dual Port Gigabit Server Adapter
+ 1775 6003 Telum GE-QT
+ 8086 005e PRO/1000 PT Dual Port Server Connection
+ 8086 105e PRO/1000 PT Dual Port Network Connection
+ 8086 115e PRO/1000 PT Dual Port Server Adapter
+ 8086 116e PRO/1000 PT Dual Port Server Adapter
+ 8086 125e PRO/1000 PT Dual Port Server Adapter
+ 8086 135e PRO/1000 PT Dual Port Server Adapter
+ 105f 82571EB Gigabit Ethernet Controller
+ 8086 115f PRO/1000 PF Dual Port Server Adapter
+ 8086 116f PRO/1000 PF Dual Port Server Adapter
+ 8086 125f PRO/1000 PF Dual Port Server Adapter
+ 8086 135f PRO/1000 PF Dual Port Server Adapter
+ 1060 82571EB Gigabit Ethernet Controller
+ 8086 0060 PRO/1000 PB Dual Port Server Connection
+ 8086 1060 PRO/1000 PB Dual Port Server Connection
+ 1064 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
+ 1043 80f8 P5GD1-VW Mainboard
+ 1065 82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
+ 1066 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller
+ 1067 82562 EM/EX/GX - PRO/100 VM Ethernet Controller
+ 1068 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile
+ 1069 82562EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile
+ 106a 82562G - PRO/100 VE (LOM) Ethernet Controller
+ 106b 82562G - PRO/100 VE Ethernet Controller Mobile
+ 1075 82547GI Gigabit Ethernet Controller
+ 1028 0165 PowerEdge 750
+ 8086 0075 PRO/1000 CT Network Connection
+ 8086 1075 PRO/1000 CT Network Connection
+ 1076 82541GI/PI Gigabit Ethernet Controller
+ 1028 0165 PowerEdge 750
+ 1028 019a PowerEdge SC1425
+ 8086 0076 PRO/1000 MT Network Connection
+ 8086 1076 PRO/1000 MT Network Connection
+ 8086 1176 PRO/1000 MT Desktop Adapter
+ 8086 1276 PRO/1000 MT Network Adapter
+ 1077 82541GI Gigabit Ethernet Controller
+ 1179 0001 PRO/1000 MT Mobile Connection
+ 8086 0077 PRO/1000 MT Mobile Connection
+ 8086 1077 PRO/1000 MT Mobile Connection
+ 1078 82541EI Gigabit Ethernet Controller
+ 8086 1078 82541ER-based Network Connection
+ 1079 82546GB Gigabit Ethernet Controller
+ 103c 12a6 HP Dual Port 1000Base-T [A9900A]
+ 103c 12cf HP Core Dual Port 1000Base-T [AB352A]
+ 1775 10d0 V5D Single Board Computer Gigabit Ethernet
+ 1775 ce90 CE9
+ 1fc1 0027 Niagara 2261 Failover NIC
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 4c53 10b0 CL9 mainboard
+ 8086 0079 PRO/1000 MT Dual Port Network Connection
+ 8086 1079 PRO/1000 MT Dual Port Network Connection
+ 8086 1179 PRO/1000 MT Dual Port Network Connection
+ 8086 117a PRO/1000 MT Dual Port Server Adapter
+ 107a 82546GB Gigabit Ethernet Controller
+ 103c 12a8 HP Dual Port 1000base-SX [A9899A]
+ 8086 107a PRO/1000 MF Dual Port Server Adapter
+ 8086 127a PRO/1000 MF Dual Port Server Adapter
+ 107b 82546GB Gigabit Ethernet Controller
+ 8086 007b PRO/1000 MB Dual Port Server Connection
+ 8086 107b PRO/1000 MB Dual Port Server Connection
+ 107c 82541PI Gigabit Ethernet Controller
+ 8086 1376 PRO/1000 GT Desktop Adapter
+ 8086 1476 PRO/1000 GT Desktop Adapter
+ 107d 82572EI Gigabit Ethernet Controller
+ 8086 1082 PRO/1000 PT Server Adapter
+ 8086 1092 PRO/1000 PT Server Adapter
+ 107e 82572EI Gigabit Ethernet Controller
+ 8086 1084 PRO/1000 PF Server Adapter
+ 8086 1094 PRO/1000 PF Server Adapter
+ 107f 82572EI Gigabit Ethernet Controller
+ 1080 FA82537EP 56K V.92 Data/Fax Modem PCI
+ 1081 631xESB/632xESB LAN Controller Copper
+ 1082 631xESB/632xESB LAN Controller fiber
+ 1083 631xESB/632xESB LAN Controller SERDES
+ 1084 631xESB/632xESB IDE Redirection
+ 1085 631xESB/632xESB Serial Port Redirection
+ 1086 631xESB/632xESB IPMI/KCS0
+ 1087 631xESB/632xESB UHCI Redirection
+ 1089 631xESB/632xESB BT
+ 108a 82546EB Gigabit Ethernet Controller
+ 8086 108a PRO/1000 P Dual Port Server Adapter
+ 8086 118a PRO/1000 P Dual Port Server Adapter
+ 108b 82573V Gigabit Ethernet Controller (Copper)
+ 108c 82573E Gigabit Ethernet Controller (Copper)
+ 108e 82573E KCS (Active Management)
+ 108f Intel(R) Active Management Technology - SOL
+ 1092 Intel(R) PRO/100 VE Network Connection
+ 1096 631xESB/632xESB DPT LAN Controller Copper
+ 1097 631xESB/632xESB DPT LAN Controller fiber
+ 1098 631xESB/632xESB DPT LAN Controller SERDES
+ 1099 82546GB Quad Port Server Adapter
+ 8086 1099 PRO/1000 GT Quad Port Server Adapter
+ 109a 82573L Gigabit Ethernet Controller
+ 17aa 207e Thinkpad X60s
+ 8086 109a PRO/1000 PL Network Connection
+ 109b 82546GB PRO/1000 GF Quad Port Server Adapter
+ 10a0 82571EB PRO/1000 AT Quad Port Bypass Adapter
+ 10a1 82571EB PRO/1000 AF Quad Port Bypass Adapter
+ 10b0 82573L PRO/1000 PL Network Connection
+ 10b2 82573V PRO/1000 PM Network Connection
+ 10b3 82573E PRO/1000 PM Network Connection
+ 10b4 82573L PRO/1000 PL Network Connection
+ 10b5 82546GB PRO/1000 GT Quad Port Server Adapter
+ 103c 3109 NC340T PCI-X Quad-port Gigabit Server Adapter
+ 8086 1099 PRO/1000 GT Quad Port Server Adapter
+ 8086 1199 PRO/1000 GT Quad Port Server Adapter
+ 10b9 82572EI Gigabit Ethernet Controller (Copper)
+ 8086 1083 PRO/1000 PT Desktop Adapter
+ 8086 1093 PRO/1000 PT Desktop Adapter
+ 1107 PRO/1000 MF Server Adapter (LX)
+ 1130 82815 815 Chipset Host Bridge and Memory Controller Hub
+ 1025 1016 Travelmate 612 TX
+ 1043 8027 TUSL2-C Mainboard
+ 104d 80df Vaio PCG-FX403
+ 8086 4532 D815EEA2 mainboard
+ 8086 4557 D815EGEW Mainboard
+ 1131 82815 815 Chipset AGP Bridge
+ 1132 82815 CGC [Chipset Graphics Controller]
+ 1025 1016 Travelmate 612 TX
+ 104d 80df Vaio PCG-FX403
+ 8086 4532 D815EEA2 Mainboard
+ 8086 4541 D815EEA Motherboard
+ 8086 4557 D815EGEW Mainboard
+ 1161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller
+ 8086 1161 82806AA PCI64 Hub APIC
+ 1162 Xscale 80200 Big Endian Companion Chip
+ 1200 Intel IXP1200 Network Processor
+ 172a 0000 AEP SSL Accelerator
+ 1209 8255xER/82551IT Fast Ethernet Controller
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ 4c53 1070 PC6 mainboard
+ 1221 82092AA PCI to PCMCIA Bridge
+ 1222 82092AA IDE Controller
+ 1223 SAA7116
+ 1225 82452KX/GX [Orion]
+ 1226 82596 PRO/10 PCI
+ 1227 82865 EtherExpress PRO/100A
+ 1228 82556 EtherExpress PRO/100 Smart
+# the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER)
+ 1229 82557/8/9 [Ethernet Pro 100]
+ 0e11 3001 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 3002 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 3003 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 3004 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 3005 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 3006 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 3007 82559 Fast Ethernet LOM with Alert on LAN*
+ 0e11 b01e NC3120 Fast Ethernet NIC
+ 0e11 b01f NC3122 Fast Ethernet NIC (dual port)
+ 0e11 b02f NC1120 Ethernet NIC
+ 0e11 b04a Netelligent 10/100TX NIC with Wake on LAN
+ 0e11 b0c6 NC3161 Fast Ethernet NIC (embedded, WOL)
+ 0e11 b0c7 NC3160 Fast Ethernet NIC (embedded)
+ 0e11 b0d7 NC3121 Fast Ethernet NIC (WOL)
+ 0e11 b0dd NC3131 Fast Ethernet NIC (dual port)
+ 0e11 b0de NC3132 Fast Ethernet Module (dual port)
+ 0e11 b0e1 NC3133 Fast Ethernet Module (100-FX)
+ 0e11 b134 NC3163 Fast Ethernet NIC (embedded, WOL)
+ 0e11 b13c NC3162 Fast Ethernet NIC (embedded)
+ 0e11 b144 NC3123 Fast Ethernet NIC (WOL)
+ 0e11 b163 NC3134 Fast Ethernet NIC (dual port)
+ 0e11 b164 NC3135 Fast Ethernet Upgrade Module (dual port)
+ 0e11 b1a4 NC7131 Gigabit Server Adapter
+ 1014 005c 82558B Ethernet Pro 10/100
+ 1014 01bc 82559 Fast Ethernet LAN On Motherboard
+ 1014 01f1 10/100 Ethernet Server Adapter
+ 1014 01f2 10/100 Ethernet Server Adapter
+ 1014 0207 Ethernet Pro/100 S
+ 1014 0232 10/100 Dual Port Server Adapter
+ 1014 023a ThinkPad R30
+ 1014 105c Netfinity 10/100
+ 1014 2205 ThinkPad A22p
+ 1014 305c 10/100 EtherJet Management Adapter
+ 1014 405c 10/100 EtherJet Adapter with Alert on LAN
+ 1014 505c 10/100 EtherJet Secure Management Adapter
+ 1014 605c 10/100 EtherJet Secure Management Adapter
+ 1014 705c 10/100 Netfinity 10/100 Ethernet Security Adapter
+ 1014 805c 10/100 Netfinity 10/100 Ethernet Security Adapter
+ 1028 009b PowerEdge 2500/2550
+ 1028 00ce PowerEdge 1400
+ 1033 8000 PC-9821X-B06
+ 1033 8016 PK-UG-X006
+ 1033 801f PK-UG-X006
+ 1033 8026 PK-UG-X006
+ 1033 8063 82559-based Fast Ethernet Adapter
+ 1033 8064 82559-based Fast Ethernet Adapter
+ 103c 10c0 NetServer 10/100TX
+ 103c 10c3 NetServer 10/100TX
+ 103c 10ca NetServer 10/100TX
+ 103c 10cb NetServer 10/100TX
+ 103c 10e3 NetServer 10/100TX
+ 103c 10e4 NetServer 10/100TX
+ 103c 1200 NetServer 10/100TX
+ 108e 10cf EtherExpress PRO/100(B)
+ 10c3 1100 SmartEther100 SC1100
+ 10cf 1115 8255x-based Ethernet Adapter (10/100)
+ 10cf 1143 8255x-based Ethernet Adapter (10/100)
+ 110a 008b 82551QM Fast Ethernet Multifuction PCI/CardBus Controller
+ 1179 0001 8255x-based Ethernet Adapter (10/100)
+ 1179 0002 PCI FastEther LAN on Docker
+ 1179 0003 8255x-based Fast Ethernet
+ 1259 2560 AT-2560 100
+ 1259 2561 AT-2560 100 FX Ethernet Adapter
+ 1266 0001 NE10/100 Adapter
+ 13e9 1000 6221L-4U
+ 144d 2501 SEM-2000 MiniPCI LAN Adapter
+ 144d 2502 SEM-2100IL MiniPCI LAN Adapter
+ 1668 1100 EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
+ 1775 ce90 CE9
+ 4c53 1080 CT8 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 8086 0001 EtherExpress PRO/100B (TX)
+ 8086 0002 EtherExpress PRO/100B (T4)
+ 8086 0003 EtherExpress PRO/10+
+ 8086 0004 EtherExpress PRO/100 WfM
+ 8086 0005 82557 10/100
+ 8086 0006 82557 10/100 with Wake on LAN
+ 8086 0007 82558 10/100 Adapter
+ 8086 0008 82558 10/100 with Wake on LAN
+ 8086 000a EtherExpress PRO/100+ Management Adapter
+ 8086 000b EtherExpress PRO/100+
+ 8086 000c EtherExpress PRO/100+ Management Adapter
+ 8086 000d EtherExpress PRO/100+ Alert On LAN II* Adapter
+ 8086 000e EtherExpress PRO/100+ Management Adapter with Alert On LAN*
+ 8086 000f EtherExpress PRO/100 Desktop Adapter
+ 8086 0010 EtherExpress PRO/100 S Management Adapter
+ 8086 0011 EtherExpress PRO/100 S Management Adapter
+ 8086 0012 EtherExpress PRO/100 S Advanced Management Adapter (D)
+ 8086 0013 EtherExpress PRO/100 S Advanced Management Adapter (E)
+ 8086 0030 EtherExpress PRO/100 Management Adapter with Alert On LAN* GC
+ 8086 0031 EtherExpress PRO/100 Desktop Adapter
+ 8086 0040 EtherExpress PRO/100 S Desktop Adapter
+ 8086 0041 EtherExpress PRO/100 S Desktop Adapter
+ 8086 0042 EtherExpress PRO/100 Desktop Adapter
+ 8086 0050 EtherExpress PRO/100 S Desktop Adapter
+ 8086 1009 EtherExpress PRO/100+ Server Adapter
+ 8086 100c EtherExpress PRO/100+ Server Adapter (PILA8470B)
+ 8086 1012 EtherExpress PRO/100 S Server Adapter (D)
+ 8086 1013 EtherExpress PRO/100 S Server Adapter (E)
+ 8086 1015 EtherExpress PRO/100 S Dual Port Server Adapter
+ 8086 1017 EtherExpress PRO/100+ Dual Port Server Adapter
+ 8086 1030 EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
+ 8086 1040 EtherExpress PRO/100 S Server Adapter
+ 8086 1041 EtherExpress PRO/100 S Server Adapter
+ 8086 1042 EtherExpress PRO/100 Server Adapter
+ 8086 1050 EtherExpress PRO/100 S Server Adapter
+ 8086 1051 EtherExpress PRO/100 Server Adapter
+ 8086 1052 EtherExpress PRO/100 Server Adapter
+ 8086 10f0 EtherExpress PRO/100+ Dual Port Adapter
+ 8086 2009 EtherExpress PRO/100 S Mobile Adapter
+ 8086 200d EtherExpress PRO/100 Cardbus
+ 8086 200e EtherExpress PRO/100 LAN+V90 Cardbus Modem
+ 8086 200f EtherExpress PRO/100 SR Mobile Adapter
+ 8086 2010 EtherExpress PRO/100 S Mobile Combo Adapter
+ 8086 2013 EtherExpress PRO/100 SR Mobile Combo Adapter
+ 8086 2016 EtherExpress PRO/100 S Mobile Adapter
+ 8086 2017 EtherExpress PRO/100 S Combo Mobile Adapter
+ 8086 2018 EtherExpress PRO/100 SR Mobile Adapter
+ 8086 2019 EtherExpress PRO/100 SR Combo Mobile Adapter
+ 8086 2101 EtherExpress PRO/100 P Mobile Adapter
+ 8086 2102 EtherExpress PRO/100 SP Mobile Adapter
+ 8086 2103 EtherExpress PRO/100 SP Mobile Adapter
+ 8086 2104 EtherExpress PRO/100 SP Mobile Adapter
+ 8086 2105 EtherExpress PRO/100 SP Mobile Adapter
+ 8086 2106 EtherExpress PRO/100 P Mobile Adapter
+ 8086 2107 EtherExpress PRO/100 Network Connection
+ 8086 2108 EtherExpress PRO/100 Network Connection
+ 8086 2200 EtherExpress PRO/100 P Mobile Combo Adapter
+ 8086 2201 EtherExpress PRO/100 P Mobile Combo Adapter
+ 8086 2202 EtherExpress PRO/100 SP Mobile Combo Adapter
+ 8086 2203 EtherExpress PRO/100+ MiniPCI
+ 8086 2204 EtherExpress PRO/100+ MiniPCI
+ 8086 2205 EtherExpress PRO/100 SP Mobile Combo Adapter
+ 8086 2206 EtherExpress PRO/100 SP Mobile Combo Adapter
+ 8086 2207 EtherExpress PRO/100 SP Mobile Combo Adapter
+ 8086 2208 EtherExpress PRO/100 P Mobile Combo Adapter
+ 8086 2402 EtherExpress PRO/100+ MiniPCI
+ 8086 2407 EtherExpress PRO/100+ MiniPCI
+ 8086 2408 EtherExpress PRO/100+ MiniPCI
+ 8086 2409 EtherExpress PRO/100+ MiniPCI
+ 8086 240f EtherExpress PRO/100+ MiniPCI
+ 8086 2410 EtherExpress PRO/100+ MiniPCI
+ 8086 2411 EtherExpress PRO/100+ MiniPCI
+ 8086 2412 EtherExpress PRO/100+ MiniPCI
+ 8086 2413 EtherExpress PRO/100+ MiniPCI
+ 8086 3000 82559 Fast Ethernet LAN on Motherboard
+ 8086 3001 82559 Fast Ethernet LOM with Basic Alert on LAN*
+ 8086 3002 82559 Fast Ethernet LOM with Alert on LAN II*
+ 8086 3006 EtherExpress PRO/100 S Network Connection
+ 8086 3007 EtherExpress PRO/100 S Network Connection
+ 8086 3008 EtherExpress PRO/100 Network Connection
+ 8086 3010 EtherExpress PRO/100 S Network Connection
+ 8086 3011 EtherExpress PRO/100 S Network Connection
+ 8086 3012 EtherExpress PRO/100 Network Connection
+ 8086 3411 SDS2 Mainboard
+ 122d 430FX - 82437FX TSC [Triton I]
+ 122e 82371FB PIIX ISA [Triton I]
+ 1230 82371FB PIIX IDE [Triton I]
+ 1231 DSVD Modem
+ 1234 430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)
+ 1235 430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP)
+ 1237 440FX - 82441FX PMC [Natoma]
+ 1239 82371FB PIIX IDE Interface
+ 123b 82380PB PCI to PCI Docking Bridge
+ 123c 82380AB (MISA) Mobile PCI-to-ISA Bridge
+ 123d 683053 Programmable Interrupt Device
+# in" hidden" mode
+ 123e 82466GX (IHPC) Integrated Hot-Plug Controller
+ 123f 82466GX Integrated Hot-Plug Controller (IHPC)
+ 1240 82752 (752) AGP Graphics Accelerator
+ 124b 82380FB (MPCI2) Mobile Docking Controller
+ 1250 430HX - 82439HX TXC [Triton II]
+ 1360 82806AA PCI64 Hub PCI Bridge
+ 1361 82806AA PCI64 Hub Controller (HRes)
+ 8086 1361 82806AA PCI64 Hub Controller (HRes)
+ 8086 8000 82806AA PCI64 Hub Controller (HRes)
+ 1460 82870P2 P64H2 Hub PCI Bridge
+ 1461 82870P2 P64H2 I/OxAPIC
+ 15d9 3480 P4DP6
+ 4c53 1090 Cx9/Vx9 mainboard
+ 1462 82870P2 P64H2 Hot Plug Controller
+ 1960 80960RP [i960RP Microprocessor]
+ 101e 0431 MegaRAID 431 RAID Controller
+ 101e 0438 MegaRAID 438 Ultra2 LVD RAID Controller
+ 101e 0466 MegaRAID 466 Express Plus RAID Controller
+ 101e 0467 MegaRAID 467 Enterprise 1500 RAID Controller
+ 101e 0490 MegaRAID 490 Express 300 RAID Controller
+ 101e 0762 MegaRAID 762 Express RAID Controller
+ 101e 09a0 PowerEdge Expandable RAID Controller 2/SC
+ 1028 0467 PowerEdge Expandable RAID Controller 2/DC
+ 1028 1111 PowerEdge Expandable RAID Controller 2/SC
+ 103c 03a2 MegaRAID
+ 103c 10c6 MegaRAID 438, HP NetRAID-3Si
+ 103c 10c7 MegaRAID T5, Integrated HP NetRAID
+ 103c 10cc MegaRAID, Integrated HP NetRAID
+ 103c 10cd HP NetRAID-1Si
+ 105a 0000 SuperTrak
+ 105a 2168 SuperTrak Pro
+ 105a 5168 SuperTrak66/100
+ 1111 1111 MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
+ 1111 1112 PowerEdge Expandable RAID Controller 2/SC
+ 113c 03a2 MegaRAID
+ e4bf 1010 CG1-RADIO
+ e4bf 1020 CU2-QUARTET
+ e4bf 1040 CU1-CHORUS
+ e4bf 3100 CX1-BAND
+ 1962 80960RM [i960RM Microprocessor]
+ 105a 0000 SuperTrak SX6000 I2O CPU
+ 1a21 82840 840 (Carmel) Chipset Host Bridge (Hub A)
+ 1a23 82840 840 (Carmel) Chipset AGP Bridge
+ 1a24 82840 840 (Carmel) Chipset PCI Bridge (Hub B)
+ 1a30 82845 845 (Brookdale) Chipset Host Bridge
+ 1028 010e Optiplex GX240
+ 1a31 82845 845 (Brookdale) Chipset AGP Bridge
+ 1a38 5000 Series Chipset DMA Engine
+ 1a48 PRO/10GbE SR Server Adapter
+ 2410 82801AA ISA Bridge (LPC)
+ 2411 82801AA IDE
+ 2412 82801AA USB
+ 2413 82801AA SMBus
+ 2415 82801AA AC'97 Audio
+ 1028 0095 Precision Workstation 220 Integrated Digital Audio
+ 110a 0051 Activy 2xx
+ 11d4 0040 SoundMAX Integrated Digital Audio
+ 11d4 0048 SoundMAX Integrated Digital Audio
+ 11d4 5340 SoundMAX Integrated Digital Audio
+ 1734 1025 Activy 3xx
+ 2416 82801AA AC'97 Modem
+ 2418 82801AA PCI Bridge
+ 2420 82801AB ISA Bridge (LPC)
+ 2421 82801AB IDE
+ 2422 82801AB USB
+ 2423 82801AB SMBus
+ 2425 82801AB AC'97 Audio
+ 11d4 0040 SoundMAX Integrated Digital Audio
+ 11d4 0048 SoundMAX Integrated Digital Audio
+ 2426 82801AB AC'97 Modem
+ 2428 82801AB PCI Bridge
+ 2440 82801BA ISA Bridge (LPC)
+ 2442 82801BA/BAM USB (Hub #1)
+ 1014 01c6 Netvista A40/A40p
+ 1025 1016 Travelmate 612 TX
+ 1028 00c7 Dimension 8100
+ 1028 010e Optiplex GX240
+ 1043 8027 TUSL2-C Mainboard
+ 104d 80df Vaio PCG-FX403
+ 147b 0507 TH7II-RAID
+ 8086 4532 D815EEA2 mainboard
+ 8086 4557 D815EGEW Mainboard
+ 2443 82801BA/BAM SMBus
+ 1014 01c6 Netvista A40/A40p
+ 1025 1016 Travelmate 612 TX
+ 1028 00c7 Dimension 8100
+ 1028 010e Optiplex GX240
+ 1043 8027 TUSL2-C Mainboard
+ 104d 80df Vaio PCG-FX403
+ 147b 0507 TH7II-RAID
+ 8086 4532 D815EEA2 mainboard
+ 8086 4557 D815EGEW Mainboard
+ 2444 82801BA/BAM USB (Hub #2)
+ 1025 1016 Travelmate 612 TX
+ 1028 00c7 Dimension 8100
+ 1028 010e Optiplex GX240
+ 1043 8027 TUSL2-C Mainboard
+ 104d 80df Vaio PCG-FX403
+ 147b 0507 TH7II-RAID
+ 8086 4532 D815EEA2 mainboard
+ 2445 82801BA/BAM AC'97 Audio
+ 0e11 0088 Evo D500
+ 1014 01c6 Netvista A40/A40p
+ 1025 1016 Travelmate 612 TX
+ 104d 80df Vaio PCG-FX403
+ 1462 3370 STAC9721 AC
+ 147b 0507 TH7II-RAID
+ 8086 4557 D815EGEW Mainboard
+ 2446 82801BA/BAM AC'97 Modem
+ 1025 1016 Travelmate 612 TX
+ 104d 80df Vaio PCG-FX403
+ 2448 82801 Mobile PCI Bridge
+ 103c 099c NX6110/NC6120
+ 1734 1055 Amilo M1420
+ 2449 82801BA/BAM/CA/CAM Ethernet Controller
+ 0e11 0012 EtherExpress PRO/100 VM
+ 0e11 0091 EtherExpress PRO/100 VE
+ 1014 01ce EtherExpress PRO/100 VE
+ 1014 01dc EtherExpress PRO/100 VE
+ 1014 01eb EtherExpress PRO/100 VE
+ 1014 01ec EtherExpress PRO/100 VE
+ 1014 0202 EtherExpress PRO/100 VE
+ 1014 0205 EtherExpress PRO/100 VE
+ 1014 0217 EtherExpress PRO/100 VE
+ 1014 0234 EtherExpress PRO/100 VE
+ 1014 023d EtherExpress PRO/100 VE
+ 1014 0244 EtherExpress PRO/100 VE
+ 1014 0245 EtherExpress PRO/100 VE
+ 1014 0265 PRO/100 VE Desktop Connection
+ 1014 0267 PRO/100 VE Desktop Connection
+ 1014 026a PRO/100 VE Desktop Connection
+ 109f 315d EtherExpress PRO/100 VE
+ 109f 3181 EtherExpress PRO/100 VE
+ 1179 ff01 PRO/100 VE Network Connection
+ 1186 7801 EtherExpress PRO/100 VE
+ 144d 2602 HomePNA 1M CNR
+ 8086 3010 EtherExpress PRO/100 VE
+ 8086 3011 EtherExpress PRO/100 VM
+ 8086 3012 82562EH based Phoneline
+ 8086 3013 EtherExpress PRO/100 VE
+ 8086 3014 EtherExpress PRO/100 VM
+ 8086 3015 82562EH based Phoneline
+ 8086 3016 EtherExpress PRO/100 P Mobile Combo
+ 8086 3017 EtherExpress PRO/100 P Mobile
+ 8086 3018 EtherExpress PRO/100
+ 244a 82801BAM IDE U100
+ 1025 1016 Travelmate 612TX
+ 104d 80df Vaio PCG-FX403
+ 244b 82801BA IDE U100
+ 1014 01c6 Netvista A40/A40p
+ 1028 00c7 Dimension 8100
+ 1028 010e Optiplex GX240
+ 1043 8027 TUSL2-C Mainboard
+ 147b 0507 TH7II-RAID
+ 8086 4532 D815EEA2 mainboard
+ 8086 4557 D815EGEW Mainboard
+ 244c 82801BAM ISA Bridge (LPC)
+ 244e 82801 PCI Bridge
+ 1014 0267 NetVista A30p
+ 2450 82801E ISA Bridge (LPC)
+ 2452 82801E USB
+ 2453 82801E SMBus
+ 2459 82801E Ethernet Controller 0
+ 245b 82801E IDE U100
+ 245d 82801E Ethernet Controller 1
+ 245e 82801E PCI Bridge
+ 2480 82801CA LPC Interface Controller
+ 2482 82801CA/CAM USB (Hub #1)
+ 0e11 0030 Evo N600c
+ 1014 0220 ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 15d9 3480 P4DP6
+ 8086 1958 vpr Matrix 170B4
+ 8086 3424 SE7501HG2 Mainboard
+ 8086 4541 Latitude C640
+ 2483 82801CA/CAM SMBus Controller
+ 1014 0220 ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 15d9 3480 P4DP6
+ 8086 1958 vpr Matrix 170B4
+ 2484 82801CA/CAM USB (Hub #2)
+ 0e11 0030 Evo N600c
+ 1014 0220 ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 15d9 3480 P4DP6
+ 8086 1958 vpr Matrix 170B4
+ 2485 82801CA/CAM AC'97 Audio Controller
+ 1013 5959 Crystal WMD Audio Codec
+ 1014 0222 ThinkPad T23 (2647-4MG) or A30/A30p (2652/2653)
+ 1014 0508 ThinkPad T30
+ 1014 051c ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 144d c006 vpr Matrix 170B4
+ 2486 82801CA/CAM AC'97 Modem Controller
+ 1014 0223 ThinkPad A/T/X Series
+ 1014 0503 ThinkPad R31 2656BBG
+ 1014 051a ThinkPad A/T/X Series
+ 101f 1025 620 Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 134d 4c21 Dell Inspiron 2100 internal modem
+ 144d 2115 vpr Matrix 170B4 internal modem
+ 14f1 5421 MD56ORD V.92 MDC Modem
+ 2487 82801CA/CAM USB (Hub #3)
+ 0e11 0030 Evo N600c
+ 1014 0220 ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 15d9 3480 P4DP6
+ 8086 1958 vpr Matrix 170B4
+ 248a 82801CAM IDE U100
+ 0e11 0030 Evo N600c
+ 1014 0220 ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 8086 1958 vpr Matrix 170B4
+ 8086 4541 Latitude C640
+ 248b 82801CA Ultra ATA Storage Controller
+ 15d9 3480 P4DP6
+ 248c 82801CAM ISA Bridge (LPC)
+ 24c0 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
+ 1014 0267 NetVista A30p
+ 1462 5800 845PE Max (MS-6580)
+ 24c1 82801DBL (ICH4-L) IDE Controller
+ 24c2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
+ 1014 0267 NetVista A30p
+ 1025 005a TravelMate 290
+ 1028 0126 Optiplex GX260
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1462 5800 845PE Max (MS-6580)
+ 1509 2990 Averatec 5110H laptop
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 1734 1055 Amilo M1420
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 8086 4541 Latitude D400
+ 24c3 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
+ 1014 0267 NetVista A30p
+ 1025 005a TravelMate 290
+ 1028 0126 Optiplex GX260
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1458 24c2 GA-8PE667 Ultra
+ 1462 5800 845PE Max (MS-6580)
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 1734 1055 Amilo M1420
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 24c4 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
+ 1014 0267 NetVista A30p
+ 1025 005a TravelMate 290
+ 1028 0126 Optiplex GX260
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1462 5800 845PE Max (MS-6580)
+ 1509 2990 Averatec 5110H
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 8086 4541 Latitude D400
+ 24c5 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
+ 0e11 00b8 Analog Devices Inc. codec [SoundMAX]
+ 1014 0267 NetVista A30p
+ 1025 005a TravelMate 290
+ 1028 0139 Latitude D400
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1458 a002 GA-8PE667 Ultra
+ 1462 5800 845PE Max (MS-6580)
+ 1734 1005 D1451 (SCENIC N300, i845GV) Sigmatel STAC9750T
+ 1734 1055 Amilo M1420
+ 24c6 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
+ 1025 003c Aspire 2001WLCi (Compal CL50 motherboard) implementation
+ 1025 005a TravelMate 290
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 24c7 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
+ 1014 0267 NetVista A30p
+ 1025 005a TravelMate 290
+ 1028 0126 Optiplex GX260
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1462 5800 845PE Max (MS-6580)
+ 1509 2990 Averatec 5110H
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 8086 4541 Latitude D400
+ 24ca 82801DBM (ICH4-M) IDE Controller
+ 1025 005a TravelMate 290
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1734 1055 Amilo M1420
+ 8086 4541 Latitude D400
+ 24cb 82801DB (ICH4) IDE Controller
+ 1014 0267 NetVista A30p
+ 1028 0126 Optiplex GX260
+ 1458 24c2 GA-8PE667 Ultra
+ 1462 5800 845PE Max (MS-6580)
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 24cc 82801DBM (ICH4-M) LPC Interface Bridge
+ 1734 1055 Amilo M1420
+ 24cd 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
+ 1014 0267 NetVista A30p
+ 1025 005a TravelMate 290
+ 1028 011d Latitude D600
+ 1028 0126 Optiplex GX260
+ 1028 0139 Latitude D400
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 tc1100 tablet
+ 1071 8160 MIM2000
+ 1179 ff00 Satellite 2430
+ 1462 3981 845PE Max (MS-6580)
+ 1509 1968 Averatec 5110H
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 1734 1055 Amilo M1420
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 24d0 82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
+ 24d1 82801EB (ICH5) SATA Controller
+ 1028 0169 Precision 470
+ 1028 019a PowerEdge SC1425
+ 103c 12bc d530 CMT (DG746A)
+ 1043 80a6 P4P800 SE Mainboard
+ 1458 24d1 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 15d9 4580 P4SCE Mainboard
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24d2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
+ 1014 02ed xSeries server mainboard
+ 1028 0169 Precision 470
+ 1028 0183 PowerEdge 1800
+ 1028 019a PowerEdge SC1425
+ 103c 006a NX9500
+ 103c 12bc d530 CMT (DG746A)
+ 1043 80a6 P5P800-MX Mainboard
+ 1458 24d2 GA-8IPE1000/8KNXP motherboard
+ 1462 7280 865PE Neo2 (MS-6728)
+ 15d9 4580 P4SCE Mainboard
+ 1734 101c Primergy RX300 S2
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24d3 82801EB/ER (ICH5/ICH5R) SMBus Controller
+ 1014 02ed xSeries server mainboard
+ 1028 0156 Precision 360
+ 1028 0169 Precision 470
+ 1043 80a6 P4P800 Mainboard
+ 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 15d9 4580 P4SCE Mainboard
+ 1734 101c Primergy RX300 S2
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24d4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
+ 1014 02ed xSeries server mainboard
+ 1028 0169 Precision 470
+ 1028 0183 PowerEdge 1800
+ 1028 019a PowerEdge SC1425
+ 103c 006a NX9500
+ 103c 12bc d530 CMT (DG746A)
+ 1043 80a6 P5P800-MX Mainboard
+ 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 15d9 4580 P4SCE Mainboard
+ 1734 101c Primergy RX300 S2
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24d5 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
+ 1028 0169 Precision 470
+ 103c 006a NX9500
+ 103c 12bc d330 uT
+ 1043 80f3 P4P800 Mainboard
+ 1043 810f P5P800-MX Mainboard
+ 1458 a002 GA-8IPE1000/8KNXP motherboard
+ 1462 0080 65PE Neo2-V (MS-6788) mainboard
+ 1462 7280 865PE Neo2 (MS-6728)
+ 8086 a000 D865PERL mainboard
+ 8086 e000 D865PERL mainboard
+ 8086 e001 Desktop Board D865GBF
+# onboard Audio in Intel 865glc MoBo
+ 8086 e002 SoundMax Intergrated Digital Audio
+ 24d6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
+ 103c 006a NX9500
+ 24d7 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3
+ 1014 02ed xSeries server mainboard
+ 1028 0169 Precision 470
+ 1028 0183 PowerEdge 1800
+ 103c 006a NX9500
+ 103c 12bc d530 CMT (DG746A)
+ 1043 80a6 P5P800-MX Mainboard
+ 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 15d9 4580 P4SCE Mainboard
+ 1734 101c Primergy RX300 S2
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24db 82801EB/ER (ICH5/ICH5R) IDE Controller
+ 1014 02ed xSeries server mainboard
+ 1028 0169 Precision 470
+ 1028 019a PowerEdge SC1425
+ 103c 006a NX9500
+ 103c 12bc d530 CMT (DG746A)
+ 1043 80a6 P5P800-MX Mainboard
+ 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 1462 7580 MSI 875P
+ 15d9 4580 P4SCE Mainboard
+ 1734 101c Primergy RX300 S2
+ 8086 24db P4C800 Mainboard
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24dc 82801EB (ICH5) LPC Interface Bridge
+ 24dd 82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
+ 1014 02ed xSeries server mainboard
+ 1028 0169 Precision 470
+ 1028 0183 PowerEdge 1800
+ 1028 019a PowerEdge SC1425
+ 103c 006a NX9500
+ 103c 12bc d530 CMT (DG746A)
+ 1043 80a6 P5P800-MX Mainboard
+ 1458 5006 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24de 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
+ 1014 02ed xSeries server mainboard
+ 1028 0169 Precision 470
+ 1043 80a6 P5P800-MX Mainboard
+ 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
+ 1462 7280 865PE Neo2 (MS-6728)
+ 15d9 4580 P4SCE Mainboard
+ 1734 101c Primergy RX300 S2
+ 8086 3427 S875WP1-E mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 8086 524c D865PERL mainboard
+ 24df 82801ER (ICH5R) SATA Controller
+ 2500 82820 820 (Camino) Chipset Host Bridge (MCH)
+ 1028 0095 Precision Workstation 220 Chipset
+ 1043 801c P3C-2000 system chipset
+ 2501 82820 820 (Camino) Chipset Host Bridge (MCH)
+ 1043 801c P3C-2000 system chipset
+ 250b 82820 820 (Camino) Chipset Host Bridge
+ 250f 82820 820 (Camino) Chipset AGP Bridge
+ 2520 82805AA MTH Memory Translator Hub
+ 2521 82804AA MRH-S Memory Repeater Hub for SDRAM
+ 2530 82850 850 (Tehama) Chipset Host Bridge (MCH)
+ 1028 00c7 Dimension 8100
+ 147b 0507 TH7II-RAID
+ 2531 82860 860 (Wombat) Chipset Host Bridge (MCH)
+ 2532 82850 850 (Tehama) Chipset AGP Bridge
+ 2533 82860 860 (Wombat) Chipset AGP Bridge
+ 2534 82860 860 (Wombat) Chipset PCI Bridge
+ 2540 E7500 Memory Controller Hub
+ 15d9 3480 P4DP6
+ 2541 E7500/E7501 Host RASUM Controller
+ 15d9 3480 P4DP6
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 8086 3424 SE7501HG2 Mainboard
+ 2543 E7500/E7501 Hub Interface B PCI-to-PCI Bridge
+ 2544 E7500/E7501 Hub Interface B RASUM Controller
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 2545 E7500/E7501 Hub Interface C PCI-to-PCI Bridge
+ 2546 E7500/E7501 Hub Interface C RASUM Controller
+ 2547 E7500/E7501 Hub Interface D PCI-to-PCI Bridge
+ 2548 E7500/E7501 Hub Interface D RASUM Controller
+ 254c E7501 Memory Controller Hub
+ 4c53 1090 Cx9 / Vx9 mainboard
+ 8086 3424 SE7501HG2 Mainboard
+ 2550 E7505 Memory Controller Hub
+ 2551 E7505/E7205 Series RAS Controller
+ 2552 E7505/E7205 PCI-to-AGP Bridge
+ 2553 E7505 Hub Interface B PCI-to-PCI Bridge
+ 2554 E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller
+ 255d E7205 Memory Controller Hub
+ 2560 82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
+ 1028 0126 Optiplex GX260
+ 1458 2560 GA-8PE667 Ultra
+ 1462 5800 845PE Max (MS-6580)
+ 2561 82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
+ 2562 82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
+ 0e11 00b9 Evo D510 SFF
+ 1014 0267 NetVista A30p
+ 1734 1004 D1451 Mainboard (SCENIC N300, i845GV)
+ 2570 82865G/PE/P DRAM Controller/Host-Hub Interface
+ 103c 006a NX9500
+ 1043 80f2 P5P800-MX Mainboard
+ 1458 2570 GA-8IPE1000 Pro2 motherboard (865PE)
+ 2571 82865G/PE/P PCI to AGP Controller
+ 2572 82865G Integrated Graphics Controller
+ 1028 019d Dimension 3000
+ 103c 12bc D530 sff(dc578av)
+ 1043 80a5 P5P800-MX Mainboard
+ 8086 4246 Desktop Board D865GBF
+ 8086 4c43 Desktop Board D865GLC
+ 2573 82865G/PE/P PCI to CSA Bridge
+ 2576 82865G/PE/P Processor to I/O Memory Interface
+ 2578 82875P/E7210 Memory Controller Hub
+ 1458 2578 GA-8KNXP motherboard (875P)
+ 1462 7580 MS-6758 (875P Neo)
+ 15d9 4580 P4SCE Motherboard
+ 2579 82875P Processor to AGP Controller
+ 257b 82875P/E7210 Processor to PCI to CSA Bridge
+ 257e 82875P/E7210 Processor to I/O Memory Interface
+ 2580 915G/P/GV/GL/PL/910GL Express Memory Controller Hub
+ 1458 2580 GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105b Scenic W620
+ 2581 915G/P/GV/GL/PL/910GL Express PCI Express Root Port
+ 2582 82915G/GV/910GL Express Chipset Family Graphics Controller
+ 1028 1079 Optiplex GX280
+ 103c 3006 DC7100 SFF(DX878AV)
+ 1043 2582 P5GD1-VW Mainboard
+ 1458 2582 GA-8I915ME-G Mainboard
+ 1734 105b Scenic W620
+ 2584 925X/XE Express Memory Controller Hub
+ 2585 925X/XE Express PCI Express Root Port
+ 2588 E7220/E7221 Memory Controller Hub
+ 2589 E7220/E7221 PCI Express Root Port
+ 258a E7221 Integrated Graphics Controller
+ 2590 Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
+ 1028 0182 Dell Latidude C610
+ 103c 099c NX6110/NC6120
+ a304 81b7 Vaio VGN-S3XP
+ 2591 Mobile 915GM/PM Express PCI Express Root Port
+ 2592 Mobile 915GM/GMS/910GML Express Graphics Controller
+ 103c 099c NX6110/NC6120
+ 103c 308a NC6220
+ 1043 1881 GMA 900 915GM Integrated Graphics
+ 25a1 6300ESB LPC Interface Controller
+ 25a2 6300ESB PATA Storage Controller
+ 1775 10d0 V5D Single Board Computer IDE
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 25a3 6300ESB SATA Storage Controller
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25a4 6300ESB SMBus Controller
+ 1775 10d0 V5D Single Board Computer
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25a6 6300ESB AC'97 Audio Controller
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 25a7 6300ESB AC'97 Modem Controller
+ 25a9 6300ESB USB Universal Host Controller
+ 1775 10d0 V5D Single Board Computer USB
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25aa 6300ESB USB Universal Host Controller
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 25ab 6300ESB Watchdog Timer
+ 1775 10d0 V5D Single Board Computer
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25ac 6300ESB I/O Advanced Programmable Interrupt Controller
+ 1775 10d0 V5D Single Board Computer
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25ad 6300ESB USB2 Enhanced Host Controller
+ 1775 10d0 V5D Single Board Computer USB 2.0
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25ae 6300ESB 64-bit PCI-X Bridge
+ 25b0 6300ESB SATA RAID Controller
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 4c53 10e0 PSL09 PrPMC
+ 25c0 5000X Chipset Memory Controller Hub
+ 25d0 5000Z Chipset Memory Controller Hub
+ 25d4 5000V Chipset Memory Controller Hub
+ 25d8 5000P Chipset Memory Controller Hub
+ 25e2 5000 Series Chipset PCI Express x4 Port 2
+ 25e3 5000 Series Chipset PCI Express x4 Port 3
+ 25e4 5000 Series Chipset PCI Express x4 Port 4
+ 25e5 5000 Series Chipset PCI Express x4 Port 5
+ 25e6 5000 Series Chipset PCI Express x4 Port 6
+ 25e7 5000 Series Chipset PCI Express x4 Port 7
+ 25f0 5000 Series Chipset Error Reporting Registers
+ 25f1 5000 Series Chipset Reserved Registers
+ 25f3 5000 Series Chipset Reserved Registers
+ 25f5 5000 Series Chipset FBD Registers
+ 25f6 5000 Series Chipset FBD Registers
+ 25f7 5000 Series Chipset PCI Express x8 Port 2-3
+ 25f8 5000 Series Chipset PCI Express x8 Port 4-5
+ 25f9 5000 Series Chipset PCI Express x8 Port 6-7
+ 25fa 5000X Chipset PCI Express x16 Port 4-7
+ 2600 E8500/E8501 Hub Interface 1.5
+ 2601 E8500/E8501 PCI Express x4 Port D
+ 2602 E8500/E8501 PCI Express x4 Port C0
+ 2603 E8500/E8501 PCI Express x4 Port C1
+ 2604 E8500/E8501 PCI Express x4 Port B0
+ 2605 E8500/E8501 PCI Express x4 Port B1
+ 2606 E8500/E8501 PCI Express x4 Port A0
+ 2607 E8500/E8501 PCI Express x4 Port A1
+ 2608 E8500/E8501 PCI Express x8 Port C
+ 2609 E8500/E8501 PCI Express x8 Port B
+ 260a E8500/E8501 PCI Express x8 Port A
+ 260c E8500/E8501 IMI Registers
+ 2610 E8500/E8501 Front Side Bus, Boot, and Interrupt Registers
+ 2611 E8500/E8501 Address Mapping Registers
+ 2612 E8500/E8501 RAS Registers
+ 2613 E8500/E8501 Reserved Registers
+ 2614 E8500/E8501 Reserved Registers
+ 2615 E8500/E8501 Miscellaneous Registers
+ 2617 E8500/E8501 Reserved Registers
+ 2618 E8500/E8501 Reserved Registers
+ 2619 E8500/E8501 Reserved Registers
+ 261a E8500/E8501 Reserved Registers
+ 261b E8500/E8501 Reserved Registers
+ 261c E8500/E8501 Reserved Registers
+ 261d E8500/E8501 Reserved Registers
+ 261e E8500/E8501 Reserved Registers
+ 2620 E8500/E8501 eXternal Memory Bridge
+ 2621 E8500/E8501 XMB Miscellaneous Registers
+ 2622 E8500/E8501 XMB Memory Interleaving Registers
+ 2623 E8500/E8501 XMB DDR Initialization and Calibration
+ 2624 E8500/E8501 XMB Reserved Registers
+ 2625 E8500/E8501 XMB Reserved Registers
+ 2626 E8500/E8501 XMB Reserved Registers
+ 2627 E8500/E8501 XMB Reserved Registers
+ 2640 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 2641 82801FBM (ICH6M) LPC Interface Bridge
+ 103c 099c NX6110/NC6120
+ 2642 82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
+ 2651 82801FB/FW (ICH6/ICH6W) SATA Controller
+ 1028 0179 Optiplex GX280
+ 1043 2601 P5GD1-VW Mainboard
+ 1734 105c Scenic W620
+ 8086 4147 D915GAG Motherboard
+ 2652 82801FR/FRW (ICH6R/ICH6RW) SATA Controller
+ 1462 7028 915P/G Neo2
+ 2653 82801FBM (ICH6M) SATA Controller
+ 2658 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
+ 1028 0179 Optiplex GX280
+ 103c 099c NX6110/NC6120
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 2558 GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 2659 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
+ 1028 0179 Optiplex GX280
+ 103c 099c NX6110/NC6120
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 2659 GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 265a 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
+ 1028 0179 Optiplex GX280
+ 103c 099c NX6110/NC6120
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 265a GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 265b 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
+ 1028 0179 Optiplex GX280
+ 103c 099c NX6110/NC6120
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 265a GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 265c 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
+ 1028 0179 Optiplex GX280
+ 103c 099c NX6110/NC6120
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 5006 GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 8086 265c Dimension 3100
+ 2660 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
+ 103c 099c NX6110/NC6120
+ 2662 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
+ 2664 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
+ 2666 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
+ 2668 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
+# based on the PTGD1-LA motherboard
+ 103c 2a09 PufferM-UL8E
+ 1043 814e P5GD1-VW Mainboard
+ 266a 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
+ 1028 0179 Optiplex GX280
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 266a GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 266c 82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
+ 266d 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
+ 1025 006a Conexant AC'97 CoDec (in Acer TravelMate 2410 serie laptop)
+ 103c 099c NX6110/NC6120
+ 266e 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
+ 1025 006a Realtek ALC 655 codec (in Acer TravelMate 2410 serie laptop)
+ 1028 0179 Optiplex GX280
+ 1028 0182 Latitude D610 Laptop
+ 1028 0188 Inspiron 6000 laptop
+ 103c 0944 Compaq NC6220
+ 103c 099c NX6110/NC6120
+ 103c 3006 DC7100 SFF(DX878AV)
+ 1458 a002 GA-8I915ME-G Mainboard
+ 152d 0745 Packard Bell A8550 Laptop
+ 1734 105a Scenic W620
+ 266f 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
+ 103c 099c NX6110/NC6120
+ 1043 80a6 P5GD1-VW Mainboard
+ 1458 266f GA-8I915ME-G Mainboard
+ 1462 7028 915P/G Neo2
+ 1734 105c Scenic W620
+ 2670 631xESB/632xESB/3100 Chipset LPC Interface Controller
+ 2680 631xESB/632xESB/3100 Chipset SATA Storage Controller IDE
+ 2681 631xESB/632xESB SATA Storage Controller AHCI
+ 2682 631xESB/632xESB SATA Storage Controller RAID
+ 2683 631xESB/632xESB SATA Storage Controller RAID
+ 2688 631xESB/632xESB/3100 Chipset UHCI USB Controller #1
+ 2689 631xESB/632xESB/3100 Chipset UHCI USB Controller #2
+ 268a 631xESB/632xESB/3100 Chipset UHCI USB Controller #3
+ 268b 631xESB/632xESB/3100 Chipset UHCI USB Controller #4
+ 268c 631xESB/632xESB/3100 Chipset EHCI USB2 Controller
+ 2690 631xESB/632xESB/3100 Chipset PCI Express Root Port 1
+ 2692 631xESB/632xESB/3100 Chipset PCI Express Root Port 2
+ 2694 631xESB/632xESB/3100 Chipset PCI Express Root Port 3
+ 2696 631xESB/632xESB/3100 Chipset PCI Express Root Port 4
+ 2698 631xESB/632xESB AC '97 Audio Controller
+ 2699 631xESB/632xESB AC '97 Modem Controller
+ 269a 631xESB/632xESB High Definition Audio Controller
+ 269b 631xESB/632xESB/3100 Chipset SMBus Controller
+ 269e 631xESB/632xESB IDE Controller
+ 2770 945G/GZ/P/PL Express Memory Controller Hub
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 2771 945G/GZ/P/PL Express PCI Express Root Port
+ 2772 945G/GZ Express Integrated Graphics Controller
+ 8086 544e DeskTop Board D945GTP
+ 2774 955X Express Memory Controller Hub
+ 2775 955X Express PCI Express Root Port
+ 2776 945G/GZ Express Integrated Graphics Controller
+ 2778 E7230 Memory Controller Hub
+ 2779 E7230 PCI Express Root Port
+ 277a 975X Express PCI Express Root Port
+ 277c 975X Express Memory Controller Hub
+ 277d 975X Express PCI Express Root Port
+ 2782 82915G Express Chipset Family Graphics Controller
+ 1043 2582 P5GD1-VW Mainboard
+ 1734 105b Scenic W620
+ 2792 Mobile 915GM/GMS/910GML Express Graphics Controller
+ 103c 099c NX6110/NC6120
+ 1043 1881 GMA 900 915GM Integrated Graphics
+ 27a0 Mobile 945GM/PM/GMS/940GML and 945GT Express Memory Controller Hub
+ 27a1 Mobile 945GM/PM/GMS/940GML and 945GT Express PCI Express Root Port
+ 27a2 Mobile 945GM/GMS/940GML Express Integrated Graphics Controller
+ 27a6 Mobile 945GM/GMS/940GML Express Integrated Graphics Controller
+ 27b0 82801GH (ICH7DH) LPC Interface Bridge
+ 27b8 82801GB/GR (ICH7 Family) LPC Interface Bridge
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27b9 82801GBM (ICH7-M) LPC Interface Bridge
+ 27bd 82801GHM (ICH7-M DH) LPC Interface Bridge
+ 27c0 82801GB/GR/GH (ICH7 Family) Serial ATA Storage Controller IDE
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27c1 82801GR/GH (ICH7 Family) Serial ATA Storage Controller AHCI
+ 27c3 82801GR/GH (ICH7 Family) Serial ATA Storage Controller RAID
+ 27c4 82801GBM/GHM (ICH7 Family) Serial ATA Storage Controller IDE
+ 27c5 82801GBM/GHM (ICH7 Family) Serial ATA Storage Controller AHCI
+ 27c6 82801GHM (ICH7-M DH) Serial ATA Storage Controller RAID
+ 27c8 82801G (ICH7 Family) USB UHCI #1
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27c9 82801G (ICH7 Family) USB UHCI #2
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27ca 82801G (ICH7 Family) USB UHCI #3
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27cb 82801G (ICH7 Family) USB UHCI #4
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27cc 82801G (ICH7 Family) USB2 EHCI Controller
+ 8086 544e DeskTop Board D945GTP
+ 27d0 82801G (ICH7 Family) PCI Express Port 1
+ 27d2 82801G (ICH7 Family) PCI Express Port 2
+ 27d4 82801G (ICH7 Family) PCI Express Port 3
+ 27d6 82801G (ICH7 Family) PCI Express Port 4
+ 27d8 82801G (ICH7 Family) High Definition Audio Controller
+ 107b 5048 E4500
+ 27da 82801G (ICH7 Family) SMBus Controller
+ 8086 544e DeskTop Board D945GTP
+ 27dc 82801G (ICH7 Family) LAN Controller
+ 8086 308d DeskTop Board D945GTP
+ 27dd 82801G (ICH7 Family) AC'97 Modem Controller
+ 27de 82801G (ICH7 Family) AC'97 Audio Controller
+ 27df 82801G (ICH7 Family) IDE Controller
+ 107b 5048 E4500
+ 8086 544e DeskTop Board D945GTP
+ 27e0 82801GR/GH/GHM (ICH7 Family) PCI Express Port 5
+ 27e2 82801GR/GH/GHM (ICH7 Family) PCI Express Port 6
+ 2810 82801HB/HR (ICH8/R) LPC Interface Controller
+ 2811 Mobile LPC Interface Controller
+ 2812 82801HH (ICH8DH) LPC Interface Controller
+ 2814 82801HO (ICH8DO) LPC Interface Controller
+ 2815 Mobile LPC Interface Controller
+ 2820 82801H (ICH8 Family) 4 port SATA IDE Controller
+ 2821 82801HB (ICH8) SATA AHCI Controller
+ 2822 82801HR/HO/HH (ICH8R/DO/DH) SATA RAID Controller
+ 2824 82801HR/HO/HH (ICH8R/DO/DH) SATA AHCI Controller
+ 2825 82801H (ICH8 Family) 2 port SATA IDE Controller
+ 2828 Mobile SATA IDE Controller
+ 2829 Mobile SATA AHCI Controller
+ 282a Mobile SATA RAID Controller
+ 2830 82801H (ICH8 Family) USB UHCI #1
+ 2831 82801H (ICH8 Family) USB UHCI #2
+ 2832 82801H (ICH8 Family) USB UHCI #3
+ 2834 82801H (ICH8 Family) USB UHCI #4
+ 2835 82801H (ICH8 Family) USB UHCI #5
+ 2836 82801H (ICH8 Family) USB2 EHCI #1
+ 283a 82801H (ICH8 Family) USB2 EHCI #2
+ 283e 82801H (ICH8 Family) SMBus Controller
+ 283f 82801H (ICH8 Family) PCI Express Port 1
+ 2841 82801H (ICH8 Family) PCI Express Port 2
+ 2843 82801H (ICH8 Family) PCI Express Port 3
+ 2845 82801H (ICH8 Family) PCI Express Port 4
+ 2847 82801H (ICH8 Family) PCI Express Port 5
+ 2849 82801H (ICH8 Family) PCI Express Port 6
+ 284b 82801H (ICH8 Family) HD Audio Controller
+ 284f 82801H (ICH8 Family) Thermal Reporting Device
+ 2850 Mobile IDE Controller
+ 2970 946GZ/PL/GL Memory Controller Hub
+ 2971 946GZ/PL/GL PCI Express Root Port
+ 2972 946GZ/GL Integrated Graphics Controller
+ 2973 946GZ/GL Integrated Graphics Controller
+ 2974 946GZ/GL HECI Controller
+ 2975 946GZ/GL HECI Controller
+ 2976 946GZ/GL PT IDER Controller
+ 2977 946GZ/GL KT Controller
+ 2990 Q963/Q965 Memory Controller Hub
+ 2991 Q963/Q965 PCI Express Root Port
+ 2992 Q963/Q965 Integrated Graphics Controller
+ 2993 Q963/Q965 Integrated Graphics Controller
+ 2994 Q963/Q965 HECI Controller
+ 2995 Q963/Q965 HECI Controller
+ 2996 Q963/Q965 PT IDER Controller
+ 2997 Q963/Q965 KT Controller
+ 29a0 P965/G965 Memory Controller Hub
+ 29a1 P965/G965 PCI Express Root Port
+ 29a2 G965 Integrated Graphics Controller
+ 29a3 G965 Integrated Graphics Controller
+ 29a4 P965/G965 HECI Controller
+ 29a5 P965/G965 HECI Controller
+ 29a6 P965/G965 PT IDER Controller
+ 29a7 P965/G965 KT Controller
+ 2a00 Mobile Memory Controller Hub
+ 2a01 Mobile PCI Express Root Port
+ 2a02 Mobile Integrated Graphics Controller
+ 2a03 Mobile Integrated Graphics Controller
+ 3092 Integrated RAID
+ 3200 GD31244 PCI-X SATA HBA
+ 3340 82855PM Processor to I/O Controller
+ 1025 005a TravelMate 290
+ 103c 088c NC8000 laptop
+ 103c 0890 NC6000 laptop
+ 103c 08b0 HP tc1100 laptop
+ 3341 82855PM Processor to AGP Controller
+ 3500 6311ESB/6321ESB PCI Express Upstream Port
+ 3501 6310ESB PCI Express Upstream Port
+ 3504 6311ESB/6321ESB I/OxAPIC Interrupt Controller
+ 3505 6310ESB I/OxAPIC Interrupt Controller
+ 350c 6311ESB/6321ESB PCI Express to PCI-X Bridge
+ 350d 6310ESB PCI Express to PCI-X Bridge
+ 3510 6311ESB/6321ESB PCI Express Downstream Port E1
+ 3511 6310ESB PCI Express Downstream Port E1
+ 3514 6311ESB/6321ESB PCI Express Downstream Port E2
+ 3515 6310ESB PCI Express Downstream Port E2
+ 3518 6311ESB/6321ESB PCI Express Downstream Port E3
+ 3519 6310ESB PCI Express Downstream Port E3
+ 3575 82830 830 Chipset Host Bridge
+ 0e11 0030 Evo N600c
+ 1014 021d ThinkPad A/T/X Series
+ 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ 3576 82830 830 Chipset AGP Bridge
+ 3577 82830 CGC [Chipset Graphics Controller]
+ 1014 0513 ThinkPad A/T/X Series
+ 3578 82830 830 Chipset Host Bridge
+ 3580 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
+ 1028 0139 Latitude D400
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 1734 1055 Amilo M1420
+ 1775 10d0 V5D Single Board Computer
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 3581 82852/82855 GM/GME/PM/GMV Processor to AGP Controller
+ 1734 1055 Amilo M1420
+ 3582 82852/855GM Integrated Graphics Device
+ 1028 0139 Latitude D400
+ 1028 0163 Latitude D505
+ 1775 10d0 V5D Single Board Computer VGA
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 3584 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
+ 1028 0139 Latitude D400
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 1734 1055 Amilo M1420
+ 1775 10d0 V5D Single Board Computer
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 3585 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
+ 1028 0139 Latitude D400
+ 1028 0163 Latitude D505
+ 1028 0196 Inspiron 5160
+ 1734 1055 Amilo M1420
+ 1775 10d0 V5D Single Board Computer
+ 1775 ce90 CE9
+ 4c53 10b0 CL9 mainboard
+ 4c53 10e0 PSL09 PrPMC
+ 3590 E7520 Memory Controller Hub
+ 1028 019a PowerEdge SC1425
+ 1734 103e Primergy RX300 S2
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 3591 E7525/E7520 Error Reporting Registers
+ 1028 0169 Precision 470
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 3592 E7320 Memory Controller Hub
+ 3593 E7320 Error Reporting Registers
+ 3594 E7520 DMA Controller
+ 4c53 10d0 Telum ASLP10 Processor AMC
+ 3595 E7525/E7520/E7320 PCI Express Port A
+ 3596 E7525/E7520/E7320 PCI Express Port A1
+ 3597 E7525/E7520 PCI Express Port B
+ 3598 E7520 PCI Express Port B1
+ 3599 E7520 PCI Express Port C
+ 359a E7520 PCI Express Port C1
+ 359b E7525/E7520/E7320 Extended Configuration Registers
+ 359e E7525 Memory Controller Hub
+ 1028 0169 Precision 470
+ 35b0 3100 Chipset Memory I/O Controller Hub
+ 35b1 3100 DRAM Controller Error Reporting Registers
+ 35b5 3100 Chipset Enhanced DMA Controller
+ 35b6 3100 Chipset PCI Express Port A
+ 35b7 3100 Chipset PCI Express Port A1
+ 35c8 3100 Extended Configuration Test Overflow Registers
+ 4220 PRO/Wireless 2200BG Network Connection
+ 4222 PRO/Wireless 3945ABG Network Connection
+ 8086 1005 PRO/Wireless 3945BG Network Connection
+ 8086 1034 PRO/Wireless 3945BG Network Connection
+ 8086 1044 PRO/Wireless 3945BG Network Connection
+ 4223 PRO/Wireless 2915ABG Network Connection
+ 1351 103c Compaq NC6220
+ 4224 PRO/Wireless 2915ABG Network Connection
+ 4227 PRO/Wireless 3945ABG Network Connection
+ 8086 1011 Thinkpad X60s
+ 8086 1014 PRO/Wireless 3945BG Network Connection
+ 5200 EtherExpress PRO/100 Intelligent Server
+ 5201 EtherExpress PRO/100 Intelligent Server
+ 8086 0001 EtherExpress PRO/100 Server Ethernet Adapter
+ 530d 80310 IOP [IO Processor]
+ 7000 82371SB PIIX3 ISA [Natoma/Triton II]
+ 7010 82371SB PIIX3 IDE [Natoma/Triton II]
+ 7020 82371SB PIIX3 USB [Natoma/Triton II]
+ 7030 430VX - 82437VX TVX [Triton VX]
+ 7050 Intercast Video Capture Card
+ 7051 PB 642365-003 (Business Video Conferencing Card)
+ 7100 430TX - 82439TX MTXC
+ 7110 82371AB/EB/MB PIIX4 ISA
+ 15ad 1976 virtualHW v3
+ 7111 82371AB/EB/MB PIIX4 IDE
+ 15ad 1976 virtualHW v3
+ 7112 82371AB/EB/MB PIIX4 USB
+ 15ad 1976 virtualHW v3
+ 7113 82371AB/EB/MB PIIX4 ACPI
+ 15ad 1976 virtualHW v3
+ 7120 82810 GMCH [Graphics Memory Controller Hub]
+ 4c53 1040 CL7 mainboard
+ 4c53 1060 PC7 mainboard
+ 7121 82810 CGC [Chipset Graphics Controller]
+ 4c53 1040 CL7 mainboard
+ 4c53 1060 PC7 mainboard
+ 8086 4341 Cayman (CA810) Mainboard
+ 7122 82810 DC-100 GMCH [Graphics Memory Controller Hub]
+ 7123 82810 DC-100 CGC [Chipset Graphics Controller]
+ 7124 82810E DC-133 GMCH [Graphics Memory Controller Hub]
+ 7125 82810E DC-133 CGC [Chipset Graphics Controller]
+ 7126 82810 DC-133 System and Graphics Controller
+ 7128 82810-M DC-100 System and Graphics Controller
+ 712a 82810-M DC-133 System and Graphics Controller
+ 7180 440LX/EX - 82443LX/EX Host bridge
+ 7181 440LX/EX - 82443LX/EX AGP bridge
+ 7190 440BX/ZX/DX - 82443BX/ZX/DX Host bridge
+ 0e11 0500 Armada 1750 Laptop System Chipset
+ 0e11 b110 Armada M700/E500
+ 1028 008e PowerEdge 1300 mainboard
+ 1179 0001 Toshiba Tecra 8100 Laptop System Chipset
+ 15ad 1976 virtualHW v3
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ 7191 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
+ 1028 008e PowerEdge 1300 mainboard
+ 7192 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
+ 0e11 0460 Armada 1700 Laptop System Chipset
+ 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ 7194 82440MX Host Bridge
+ 1033 0000 Versa Note Vxi
+ 4c53 10a0 CA3/CR3 mainboard
+ 7195 82440MX AC'97 Audio Controller
+ 1033 80cc Versa Note VXi
+ 10cf 1099 QSound_SigmaTel Stac97 PCI Audio
+ 11d4 0040 SoundMAX Integrated Digital Audio
+ 11d4 0048 SoundMAX Integrated Digital Audio
+ 7196 82440MX AC'97 Modem Controller
+ 7198 82440MX ISA Bridge
+ 7199 82440MX EIDE Controller
+ 719a 82440MX USB Universal Host Controller
+ 719b 82440MX Power Management Controller
+ 71a0 440GX - 82443GX Host bridge
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ 71a1 440GX - 82443GX AGP bridge
+ 71a2 440GX - 82443GX Host bridge (AGP disabled)
+ 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ 7600 82372FB PIIX5 ISA
+ 7601 82372FB PIIX5 IDE
+ 7602 82372FB PIIX5 USB
+ 7603 82372FB PIIX5 SMBus
+ 7800 82740 (i740) AGP Graphics Accelerator
+ 003d 0008 Starfighter AGP
+ 003d 000b Starfighter AGP
+ 1092 0100 Stealth II G460
+ 10b4 201a Lightspeed 740
+ 10b4 202f Lightspeed 740
+ 8086 0000 Terminator 2x/i
+ 8086 0100 Intel740 Graphics Accelerator
+ 84c4 450KX/GX [Orion] - 82454KX/GX PCI bridge
+ 84c5 450KX/GX [Orion] - 82453KX/GX Memory controller
+ 84ca 450NX - 82451NX Memory & I/O Controller
+ 84cb 450NX - 82454NX/84460GX PCI Expander Bridge
+ 84e0 460GX - 84460GX System Address Controller (SAC)
+ 84e1 460GX - 84460GX System Data Controller (SDC)
+ 84e2 460GX - 84460GX AGP Bridge (GXB function 2)
+ 84e3 460GX - 84460GX Memory Address Controller (MAC)
+ 84e4 460GX - 84460GX Memory Data Controller (MDC)
+ 84e6 460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
+ 84ea 460GX - 84460GX AGP Bridge (GXB function 1)
+ 8500 IXP4XX Intel Network Processor (IXP420/421/422/425/IXC1100)
+ 1993 0ded mGuard-PCI AV#2
+ 1993 0dee mGuard-PCI AV#1
+ 1993 0def mGuard-PCI AV#0
+ 9000 IXP2000 Family Network Processor
+ 9001 IXP2400 Network Processor
+ 9002 IXP2300 Network Processor
+ 9004 IXP2800 Network Processor
+ 9621 Integrated RAID
+ 9622 Integrated RAID
+ 9641 Integrated RAID
+ 96a1 Integrated RAID
+ b152 21152 PCI-to-PCI Bridge
+# observed, and documented in Intel revision note; new mask of 1011:0026
+ b154 21154 PCI-to-PCI Bridge
+ b555 21555 Non transparent PCI-to-PCI Bridge
+ 12c7 5006 SS7HDC Adaptor Card
+ 12d9 000a PCI VoIP Gateway
+ 4c53 1050 CT7 mainboard
+ 4c53 1051 CE7 mainboard
+ e4bf 1000 CC8-1-BLUES
+8401 TRENDware International Inc.
+8800 Trigem Computer Inc.
+ 2008 Video assistent component
+8866 T-Square Design Inc.
+8888 Silicon Magic
+8912 TRX
+# 8c4a is not Winbond but there is a board misprogrammed
+8c4a Winbond
+ 1980 W89C940 misprogrammed [ne2k]
+8e0e Computone Corporation
+8e2e KTI
+ 3000 ET32P2
+9004 Adaptec
+ 0078 AHA-2940U_CN
+ 1078 AIC-7810
+ 1160 AIC-1160 [Family Fibre Channel Adapter]
+ 2178 AIC-7821
+ 3860 AHA-2930CU
+ 3b78 AHA-4844W/4844UW
+ 5075 AIC-755x
+ 5078 AHA-7850
+ 9004 7850 AHA-2904/Integrated AIC-7850
+ 5175 AIC-755x
+ 5178 AIC-7851
+ 5275 AIC-755x
+ 5278 AIC-7852
+ 5375 AIC-755x
+ 5378 AIC-7850
+ 5475 AIC-755x
+ 5478 AIC-7850
+ 5575 AVA-2930
+ 5578 AIC-7855
+ 5647 ANA-7711 TCP Offload Engine
+ 9004 7710 ANA-7711F TCP Offload Engine - Optical
+ 9004 7711 ANA-7711LP TCP Offload Engine - Copper
+ 5675 AIC-755x
+ 5678 AIC-7856
+ 5775 AIC-755x
+ 5778 AIC-7850
+ 5800 AIC-5800
+ 5900 ANA-5910/5930/5940 ATM155 & 25 LAN Adapter
+ 5905 ANA-5910A/5930A/5940A ATM Adapter
+ 6038 AIC-3860
+ 6075 AIC-1480 / APA-1480
+ 9004 7560 AIC-1480 / APA-1480 Cardbus
+ 6078 AIC-7860
+ 6178 AIC-7861
+ 9004 7861 AHA-2940AU Single
+ 6278 AIC-7860
+ 6378 AIC-7860
+ 6478 AIC-786x
+ 6578 AIC-786x
+ 6678 AIC-786x
+ 6778 AIC-786x
+ 6915 ANA620xx/ANA69011A
+ 9004 0008 ANA69011A/TX 10/100
+ 9004 0009 ANA69011A/TX 10/100
+ 9004 0010 ANA62022 2-port 10/100
+ 9004 0018 ANA62044 4-port 10/100
+ 9004 0019 ANA62044 4-port 10/100
+ 9004 0020 ANA62022 2-port 10/100
+ 9004 0028 ANA69011A/TX 10/100
+ 9004 8008 ANA69011A/TX 64 bit 10/100
+ 9004 8009 ANA69011A/TX 64 bit 10/100
+ 9004 8010 ANA62022 2-port 64 bit 10/100
+ 9004 8018 ANA62044 4-port 64 bit 10/100
+ 9004 8019 ANA62044 4-port 64 bit 10/100
+ 9004 8020 ANA62022 2-port 64 bit 10/100
+ 9004 8028 ANA69011A/TX 64 bit 10/100
+ 7078 AHA-294x / AIC-7870
+ 7178 AHA-2940/2940W / AIC-7871
+ 7278 AHA-3940/3940W / AIC-7872
+ 7378 AHA-3985 / AIC-7873
+ 7478 AHA-2944/2944W / AIC-7874
+ 7578 AHA-3944/3944W / AIC-7875
+ 7678 AHA-4944W/UW / AIC-7876
+ 7710 ANA-7711F Network Accelerator Card (NAC) - Optical
+ 7711 ANA-7711C Network Accelerator Card (NAC) - Copper
+ 7778 AIC-787x
+ 7810 AIC-7810
+ 7815 AIC-7815 RAID+Memory Controller IC
+ 9004 7815 ARO-1130U2 RAID Controller
+ 9004 7840 AIC-7815 RAID+Memory Controller IC
+ 7850 AIC-7850
+ 7855 AHA-2930
+ 7860 AIC-7860
+ 7870 AIC-7870
+ 7871 AHA-2940
+ 7872 AHA-3940
+ 7873 AHA-3980
+ 7874 AHA-2944
+ 7880 AIC-7880P
+ 7890 AIC-7890
+ 7891 AIC-789x
+ 7892 AIC-789x
+ 7893 AIC-789x
+ 7894 AIC-789x
+ 7895 AHA-2940U/UW / AHA-39xx / AIC-7895
+ 9004 7890 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ 9004 7891 AHA-2940U/2940UW Dual
+ 9004 7892 AHA-3940AU/AUW/AUWD/UWD
+ 9004 7894 AHA-3944AUWD
+ 9004 7895 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ 9004 7896 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ 9004 7897 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ 7896 AIC-789x
+ 7897 AIC-789x
+ 8078 AIC-7880U
+ 9004 7880 AIC-7880P Ultra/Ultra Wide SCSI Chipset
+ 8178 AHA-2940U/UW/D / AIC-7881U
+ 9004 7881 AHA-2940UW SCSI Host Adapter
+ 8278 AHA-3940U/UW/UWD / AIC-7882U
+ 8378 AHA-3940U/UW / AIC-7883U
+ 8478 AHA-2944UW / AIC-7884U
+ 8578 AHA-3944U/UWD / AIC-7885
+ 8678 AHA-4944UW / AIC-7886
+ 8778 AHA-2940UW Pro / AIC-788x
+ 9004 7887 2940UW Pro Ultra-Wide SCSI Controller
+ 8878 AHA-2930UW / AIC-7888
+ 9004 7888 AHA-2930UW SCSI Controller
+ 8b78 ABA-1030
+ ec78 AHA-4944W/UW
+9005 Adaptec
+ 0010 AHA-2940U2/U2W
+ 9005 2180 AHA-2940U2 SCSI Controller
+ 9005 8100 AHA-2940U2B SCSI Controller
+ 9005 a100 AHA-2940U2B SCSI Controller
+ 9005 a180 AHA-2940U2W SCSI Controller
+ 9005 e100 AHA-2950U2B SCSI Controller
+ 0011 AHA-2930U2
+ 0013 78902
+ 9005 0003 AAA-131U2 Array1000 1 Channel RAID Controller
+ 9005 000f AIC7890_ARO
+ 001f AHA-2940U2/U2W / 7890/7891
+ 9005 000f 2940U2W SCSI Controller
+ 9005 a180 2940U2W SCSI Controller
+ 0020 AIC-7890
+ 002f AIC-7890
+ 0030 AIC-7890
+ 003f AIC-7890
+ 0050 AHA-3940U2x/395U2x
+ 9005 f500 AHA-3950U2B
+ 9005 ffff AHA-3950U2B
+ 0051 AHA-3950U2D
+ 9005 b500 AHA-3950U2D
+ 0053 AIC-7896 SCSI Controller
+ 9005 ffff AIC-7896 SCSI Controller mainboard implementation
+ 005f AIC-7896U2/7897U2
+ 0080 AIC-7892A U160/m
+ 0e11 e2a0 Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
+ 9005 6220 AHA-29160C
+ 9005 62a0 29160N Ultra160 SCSI Controller
+ 9005 e220 29160LP Low Profile Ultra160 SCSI Controller
+ 9005 e2a0 29160 Ultra160 SCSI Controller
+ 0081 AIC-7892B U160/m
+ 9005 62a1 19160 Ultra160 SCSI Controller
+ 0083 AIC-7892D U160/m
+ 008f AIC-7892P U160/m
+ 1179 0001 Magnia Z310
+ 15d9 9005 Onboard SCSI Host Adapter
+ 00c0 AHA-3960D / AIC-7899A U160/m
+ 0e11 f620 Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
+ 9005 f620 AHA-3960D U160/m
+ 00c1 AIC-7899B U160/m
+ 00c3 AIC-7899D U160/m
+ 00c5 RAID subsystem HBA
+ 1028 00c5 PowerEdge 2400,2500,2550,4400
+ 00cf AIC-7899P U160/m
+ 1028 00ce PowerEdge 1400
+ 1028 00d1 PowerEdge 2550
+ 1028 00d9 PowerEdge 2500
+ 10f1 2462 Thunder K7 S2462
+ 15d9 9005 Onboard SCSI Host Adapter
+ 8086 3411 SDS2 Mainboard
+ 0241 Serial ATA II RAID 1420SA
+ 0250 ServeRAID Controller
+ 1014 0279 ServeRAID-xx
+ 1014 028c ServeRAID-xx
+ 0279 ServeRAID 6M
+ 0283 AAC-RAID
+ 9005 0283 Catapult
+ 0284 AAC-RAID
+ 9005 0284 Tomcat
+ 0285 AAC-RAID
+ 0e11 0295 SATA 6Ch (Bearcat)
+ 1014 02f2 ServeRAID 8i
+ 1028 0287 PowerEdge Expandable RAID Controller 320/DC
+ 1028 0291 CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
+ 103c 3227 AAR-2610SA
+ 17aa 0286 Legend S220 (Legend Crusader)
+ 17aa 0287 Legend S230 (Legend Vulcan)
+ 9005 0285 2200S (Vulcan)
+ 9005 0286 2120S (Crusader)
+ 9005 0287 2200S (Vulcan-2m)
+ 9005 0288 3230S (Harrier)
+ 9005 0289 3240S (Tornado)
+# Some early versions reported 2020S
+ 9005 028a ASR-2020ZCR
+# Some early versions reported 2025S
+ 9005 028b ASR-2025ZCR (Terminator)
+ 9005 028e ASR-2020SA (Skyhawk)
+ 9005 028f ASR-2025SA
+ 9005 0290 AAR-2410SA PCI SATA 4ch (Jaguar II)
+ 9005 0292 AAR-2810SA PCI SATA 8ch (Corsair-8)
+ 9005 0293 AAR-21610SA PCI SATA 16ch (Corsair-16)
+ 9005 0294 ESD SO-DIMM PCI-X SATA ZCR (Prowler)
+ 9005 0296 ASR-2240S
+ 9005 0297 ASR-4005SAS
+ 9005 0298 ASR-4000SAS
+ 9005 0299 ASR-4800SAS
+ 9005 029a 4805SAS
+ 0286 AAC-RAID (Rocket)
+ 1014 034d 8s
+ 1014 9540 ServeRAID 8k/8k-l4
+ 1014 9580 ServeRAID 8k/8k-l8
+ 9005 028c ASR-2230S + ASR-2230SLP PCI-X (Lancer)
+ 9005 028d ASR-2130S
+ 9005 029b ASR-2820SA
+ 9005 029c ASR-2620SA
+ 9005 029d ASR-2420SA
+ 9005 029e ICP ICP9024R0
+ 9005 029f ICP ICP9014R0
+ 9005 02a0 ICP ICP9047MA
+ 9005 02a1 ICP ICP9087MA
+ 9005 02a2 3800SAS
+ 9005 02a3 ICP ICP5445AU
+ 9005 02a4 ICP ICP5085LI
+ 9005 02a5 ICP ICP5085BR
+ 9005 02a6 ICP9067MA
+ 9005 02a7 AAR-2830SA
+ 9005 02a8 AAR-2430SA
+ 9005 02a9 ICP5087AU
+ 9005 02aa ICP5047AU
+ 9005 02b3 ASR-2400SAS
+ 9005 02b4 ICP ICP5045AU
+ 9005 0800 Callisto
+ 0410 AIC-9410W SAS (Razor HBA RAID)
+ 9005 0410 ASC-48300(Spirit RAID)
+ 9005 0411 ASC-58300 (Oakmont RAID) =20
+ 0412 AIC-9410W SAS (Razor HBA non-RAID)
+ 9005 0412 ASC-48300 (Spirit non-RAID)
+ 9005 0413 ASC-58300 (Oakmont non-RAID)
+ 041e AIC-9410W SAS (Razor ASIC non-RAID)
+ 041f AIC-9410W SAS (Razor ASIC RAID)=20
+ 9005 041f AIC-9410W SAS (Razor ASIC RAID)
+ 0430 AIC-9405W SAS (Razor-Lite HBA RAID)
+ 9005 0430 ASC-44300 (Spirit-Lite RAID)
+ 0432 AIC-9405W SAS (Razor-Lite HBA non-RAID)
+ 9005 0432 ASC-44300 (Spirit-Lite non-RAID)
+ 043e AIC-9405W SAS (Razor-Lite ASIC non-RAID)=20
+ 043f AIC-9405W SAS (Razor-Lite ASIC RAID)=20
+ 0500 Obsidian chipset SCSI controller
+ 1014 02c1 PCI-X DDR 3Gb SAS Adapter (572A/572C)
+ 1014 02c2 PCI-X DDR 3Gb SAS RAID Adapter (572B/572D)
+ 0503 Scamp chipset SCSI controller
+ 1014 02bf Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
+ 1014 02d5 Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571F)
+ 0910 AUA-3100B
+ 091e AUA-3100B
+ 8000 ASC-29320A U320
+ 800f AIC-7901 U320
+ 8010 ASC-39320 U320
+ 8011 ASC-39320D
+ 0e11 00ac ASC-39320D U320
+ 9005 0041 ASC-39320D U320
+ 8012 ASC-29320 U320
+ 8013 ASC-29320B U320
+ 8014 ASC-29320LP U320
+ 8015 ASC-39320B U320
+ 8016 ASC-39320A U320
+ 8017 ASC-29320ALP U320
+ 801c ASC-39320D U320
+ 801d AIC-7902B U320
+ 801e AIC-7901A U320
+ 801f AIC-7902 U320
+ 1734 1011 Primergy RX300
+ 8080 ASC-29320A U320 w/HostRAID
+ 808f AIC-7901 U320 w/HostRAID
+ 8090 ASC-39320 U320 w/HostRAID
+ 8091 ASC-39320D U320 w/HostRAID
+ 8092 ASC-29320 U320 w/HostRAID
+ 8093 ASC-29320B U320 w/HostRAID
+ 8094 ASC-29320LP U320 w/HostRAID
+ 8095 ASC-39320(B) U320 w/HostRAID
+ 8096 ASC-39320A U320 w/HostRAID
+ 8097 ASC-29320ALP U320 w/HostRAID
+ 809c ASC-39320D(B) U320 w/HostRAID
+ 809d AIC-7902(B) U320 w/HostRAID
+ 809e AIC-7901A U320 w/HostRAID
+ 809f AIC-7902 U320 w/HostRAID
+907f Atronics
+ 2015 IDE-2015PL
+919a Gigapixel Corp
+9412 Holtek
+ 6565 6565
+9699 Omni Media Technology Inc
+ 6565 6565
+9710 NetMos Technology
+ 7780 USB IRDA-port
+ 9805 PCI 1 port parallel adapter
+ 9815 PCI 9815 Multi-I/O Controller
+ 1000 0020 2P0S (2 port parallel adaptor)
+ 9835 PCI 9835 Multi-I/O Controller
+ 1000 0002 2S (16C550 UART)
+ 1000 0012 1P2S
+ 9845 PCI 9845 Multi-I/O Controller
+ 1000 0004 0P4S (4 port 16550A serial card)
+ 1000 0006 0P6S (6 port 16550a serial card)
+ 9855 PCI 9855 Multi-I/O Controller
+ 1000 0014 1P4S
+9902 Stargen Inc.
+ 0001 SG2010 PCI over Starfabric Bridge
+ 0002 SG2010 PCI to Starfabric Gateway
+ 0003 SG1010 Starfabric Switch and PCI Bridge
+a0a0 AOPEN Inc.
+a0f1 UNISYS Corporation
+a200 NEC Corporation
+a259 Hewlett Packard
+a25b Hewlett Packard GmbH PL24-MKT
+a304 Sony
+a727 3Com Corporation
+ 0013 3CRPAG175 Wireless PC Card
+aa42 Scitex Digital Video
+ac1e Digital Receiver Technology Inc
+ac3d Actuality Systems
+aecb Adrienne Electronics Corporation
+ 6250 VITC/LTC Timecode Reader card [PCI-VLTC/RDR]
+affe Sirrix AG security technologies
+ dead Sirrix.PCI4S0 4-port ISDN S0 interface
+b10b Uakron PCI Project
+b1b3 Shiva Europe Limited
+# Pinnacle should be 11bd, but they got it wrong several times --mj
+bd11 Pinnacle Systems, Inc. (Wrong ID)
+c001 TSI Telsys
+c0a9 Micron/Crucial Technology
+c0de Motorola
+c0fe Motion Engineering, Inc.
+ca50 Varian Australia Pty Ltd
+cafe Chrysalis-ITS
+ 0003 Luna K3 Hardware Security Module
+cccc Catapult Communications
+cddd Tyzx, Inc.
+ 0101 DeepSea 1 High Speed Stereo Vision Frame Grabber
+ 0200 DeepSea 2 High Speed Stereo Vision Frame Grabber
+d161 Digium, Inc.
+ 0205 Wildcard TE205P
+ 0210 Wildcard TE210P
+ 0405 Wildcard TE405P Quad-Span togglable E1/T1/J1 card 5.0v
+ 0406 Wildcard TE406P Quad-Span togglable E1/T1/J1 echo cancellation card 5.0v
+ 0410 Wildcard TE410P Quad-Span togglable E1/T1/J1 card 3.3v
+ 0411 Wildcard TE411P Quad-Span togglable E1/T1/J1 echo cancellation card 3.3v
+ 2400 Wildcard TDM2400P
+d4d4 Dy4 Systems Inc
+ 0601 PCI Mezzanine Card
+d531 I+ME ACTIA GmbH
+d84d Exsys
+dead Indigita Corporation
+deaf Middle Digital Inc.
+ 9050 PC Weasel Virtual VGA
+ 9051 PC Weasel Serial Port
+ 9052 PC Weasel Watchdog Timer
+e000 Winbond
+ e000 W89C940
+e159 Tiger Jet Network Inc.
+ 0001 Tiger3XX Modem/ISDN interface
+ 0059 0001 128k ISDN-S/T Adapter
+ 0059 0003 128k ISDN-U Adapter
+ 00a7 0001 TELES.S0/PCI 2.x ISDN Adapter
+ 8086 0003 Digium X100P/X101P analogue PSTN FXO interface
+ b1d9 0003 TDM400P/A400P analogue 4xPSTN FXO/FXS interface
+ 0002 Tiger100APC ISDN chipset
+e4bf EKF Elektronik GmbH
+# Innovative and scalable network IC vendor
+e55e Essence Technology, Inc.
+ea01 Eagle Technology
+ 000a PCI-773 Temperature Card
+ 0032 PCI-730 & PC104P-30 Card
+ 003e PCI-762 Opto-Isolator Card
+ 0041 PCI-763 Reed Relay Card
+ 0043 PCI-769 Opto-Isolator Reed Relay Combo Card
+ 0046 PCI-766 Analog Output Card
+ 0052 PCI-703 Analog I/O Card
+ 0800 PCI-800 Digital I/O Card
+# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID.
+ea60 RME
+ 9896 Digi32
+ 9897 Digi32 Pro
+ 9898 Digi32/8
+eabb Aashima Technology B.V.
+eace Endace Measurement Systems, Ltd
+ 3100 DAG 3.10 OC-3/OC-12
+ 3200 DAG 3.2x OC-3/OC-12
+ 320e DAG 3.2E Fast Ethernet
+ 340e DAG 3.4E Fast Ethernet
+ 341e DAG 3.41E Fast Ethernet
+ 3500 DAG 3.5 OC-3/OC-12
+ 351c DAG 3.5ECM Fast Ethernet
+ 4100 DAG 4.10 OC-48
+ 4110 DAG 4.11 OC-48
+ 4220 DAG 4.2 OC-48
+ 422e DAG 4.2E Dual Gigabit Ethernet
+ec80 Belkin Corporation
+ ec00 F5D6000
+ecc0 Echo Digital Audio Corporation
+edd8 ARK Logic Inc
+ a091 1000PV [Stingray]
+ a099 2000PV [Stingray]
+ a0a1 2000MT
+ a0a9 2000MI
+f1d0 AJA Video
+ c0fe Xena HS/HD-R
+ c0ff Kona/Xena 2
+ cafe Kona SD
+ cfee Xena LS/SD-22-DA/SD-DA
+ dcaf Kona HD
+ dfee Xena HD-DA
+ efac Xena SD-MM/SD-22-MM
+ facd Xena HD-MM
+fa57 Interagon AS
+ 0001 PMC [Pattern Matching Chip]
+fab7 Fabric7 Systems, Inc.
+febd Ultraview Corp.
+# Nee Epigram
+feda Broadcom Inc
+ a0fa BCM4210 iLine10 HomePNA 2.0
+ a10e BCM4230 iLine10 HomePNA 2.0
+fede Fedetec Inc.
+ 0003 TABIC PCI v3
+fffd XenSource, Inc.
+ 0101 PCI Event Channel Controller
+fffe VMWare Inc
+ 0405 Virtual SVGA 4.0
+ 0710 Virtual SVGA
+ffff Illegal Vendor ID
+
+
+# List of known device classes, subclasses and programming interfaces
+
+# Syntax:
+# C class class_name
+# subclass subclass_name <-- single tab
+# prog-if prog-if_name <-- two tabs
+
+C 00 Unclassified device
+ 00 Non-VGA unclassified device
+ 01 VGA compatible unclassified device
+C 01 Mass storage controller
+ 00 SCSI storage controller
+ 01 IDE interface
+ 02 Floppy disk controller
+ 03 IPI bus controller
+ 04 RAID bus controller
+ 05 ATA controller
+ 20 ADMA single stepping
+ 40 ADMA continuous operation
+ 06 SATA controller
+ 00 Vendor specific
+ 01 AHCI 1.0
+ 07 Serial Attached SCSI controller
+ 80 Mass storage controller
+C 02 Network controller
+ 00 Ethernet controller
+ 01 Token ring network controller
+ 02 FDDI network controller
+ 03 ATM network controller
+ 04 ISDN controller
+ 80 Network controller
+C 03 Display controller
+ 00 VGA compatible controller
+ 00 VGA
+ 01 8514
+ 01 XGA compatible controller
+ 02 3D controller
+ 80 Display controller
+C 04 Multimedia controller
+ 00 Multimedia video controller
+ 01 Multimedia audio controller
+ 02 Computer telephony device
+ 03 Audio device
+ 80 Multimedia controller
+C 05 Memory controller
+ 00 RAM memory
+ 01 FLASH memory
+ 80 Memory controller
+C 06 Bridge
+ 00 Host bridge
+ 01 ISA bridge
+ 02 EISA bridge
+ 03 MicroChannel bridge
+ 04 PCI bridge
+ 00 Normal decode
+ 01 Subtractive decode
+ 05 PCMCIA bridge
+ 06 NuBus bridge
+ 07 CardBus bridge
+ 08 RACEway bridge
+ 00 Transparent mode
+ 01 Endpoint mode
+ 09 Semi-transparent PCI-to-PCI bridge
+ 40 Primary bus towards host CPU
+ 80 Secondary bus towards host CPU
+ 0a InfiniBand to PCI host bridge
+ 80 Bridge
+C 07 Communication controller
+ 00 Serial controller
+ 00 8250
+ 01 16450
+ 02 16550
+ 03 16650
+ 04 16750
+ 05 16850
+ 06 16950
+ 01 Parallel controller
+ 00 SPP
+ 01 BiDir
+ 02 ECP
+ 03 IEEE1284
+ fe IEEE1284 Target
+ 02 Multiport serial controller
+ 03 Modem
+ 00 Generic
+ 01 Hayes/16450
+ 02 Hayes/16550
+ 03 Hayes/16650
+ 04 Hayes/16750
+ 80 Communication controller
+C 08 Generic system peripheral
+ 00 PIC
+ 00 8259
+ 01 ISA PIC
+ 02 EISA PIC
+ 10 IO-APIC
+ 20 IO(X)-APIC
+ 01 DMA controller
+ 00 8237
+ 01 ISA DMA
+ 02 EISA DMA
+ 02 Timer
+ 00 8254
+ 01 ISA Timer
+ 02 EISA Timers
+ 03 RTC
+ 00 Generic
+ 01 ISA RTC
+ 04 PCI Hot-plug controller
+ 80 System peripheral
+C 09 Input device controller
+ 00 Keyboard controller
+ 01 Digitizer Pen
+ 02 Mouse controller
+ 03 Scanner controller
+ 04 Gameport controller
+ 00 Generic
+ 10 Extended
+ 80 Input device controller
+C 0a Docking station
+ 00 Generic Docking Station
+ 80 Docking Station
+C 0b Processor
+ 00 386
+ 01 486
+ 02 Pentium
+ 10 Alpha
+ 20 Power PC
+ 30 MIPS
+ 40 Co-processor
+C 0c Serial bus controller
+ 00 FireWire (IEEE 1394)
+ 00 Generic
+ 10 OHCI
+ 01 ACCESS Bus
+ 02 SSA
+ 03 USB Controller
+ 00 UHCI
+ 10 OHCI
+ 20 EHCI
+ 80 Unspecified
+ fe USB Device
+ 04 Fibre Channel
+ 05 SMBus
+ 06 InfiniBand
+C 0d Wireless controller
+ 00 IRDA controller
+ 01 Consumer IR controller
+ 10 RF controller
+ 80 Wireless controller
+C 0e Intelligent controller
+ 00 I2O
+C 0f Satellite communications controller
+ 00 Satellite TV controller
+ 01 Satellite audio communication controller
+ 03 Satellite voice communication controller
+ 04 Satellite data communication controller
+C 10 Encryption controller
+ 00 Network and computing encryption device
+ 10 Entertainment encryption device
+ 80 Encryption controller
+C 11 Signal processing controller
+ 00 DPIO module
+ 01 Performance counters
+ 10 Communication synchronizer
+ 80 Signal processing controller
diff --git a/usr/src/cmd/hwdata/usb.ids b/usr/src/cmd/hwdata/usb.ids
new file mode 100644
index 0000000000..9d54790579
--- /dev/null
+++ b/usr/src/cmd/hwdata/usb.ids
@@ -0,0 +1,5959 @@
+#
+# List of USB ID's
+#
+# Maintained by Vojtech Pavlik <vojtech@suse.cz>
+# If you have any new entries, send them to the maintainer.
+# The latest version can be obtained from
+# http://www.linux-usb.org/usb.ids
+#
+# $Id: usb.ids,v 1.225 2006/07/13 04:18:02 dbrownell Exp $
+#
+
+# Vendors, devices and interfaces. Please keep sorted.
+
+# Syntax:
+# vendor vendor_name
+# device device_name <-- single tab
+# interface interface_name <-- two tabs
+
+0001 Fry's Electronics
+0002 Ingram
+0003 Club Mac
+0004 Nebraska Furniture Mart
+0386 LTS
+ 0001 PSX for USB Converter
+03e8 EndPoints, Inc.
+ 0004 SE401 WebCam
+ 0008 101 Ethernet [klsi]
+03e9 Thesys Microelectronics
+03ea Data Broadcasting Corp.
+03eb Atmel Corp.
+ 2002 Mass Storage Device
+ 2015 at90usbkey sample firmware (HID keyboard)
+ 2018 at90usbkey sample firmware (CDC ACM)
+ 2019 stk525 sample firmware (microphone)
+ 201c at90usbkey sample firmware (HID mouse)
+ 201d at90usbkey sample firmware (HID generic)
+ 2022 at90usbkey sample firmware (composite device)
+ 2103 JTAG ICE mkII
+ 2ffb at90usb AVR DFU bootloader
+ 2ffd at89c5130/c5131 DFU bootloader
+ 2fff at89c5132/c51snd1c DFU bootloader
+ 3301 at43301 4-port Hub
+ 3312 4-port Hub
+ 5601 at76c510 Prism-II 802.11b Access Point
+ 5603 Cisco 7920 WiFi IP Phone
+ 7603 at76c503a D-Link DWL-120 802.11b Adapter
+ 7605 at76c503a 802.11b Adapter
+ 7606 at76c505 802.11b Adapter
+ 7611 at76c510 rfmd2948 802.11b Access Point
+03ec Iwatsu America, Inc.
+03ed Mitel Corp.
+03ee Mitsumi
+ 0000 CD-R/RW Drive
+ 641f WIF-0402C Bluetooth Adapter
+ 6440 WML-C52APR Bluetooth Adapter
+ 6901 SmartDisk FDD
+03f0 Hewlett-Packard
+ 0004 DeskJet 895c
+ 0101 ScanJet 4100c
+ 0102 PhotoSmart S20
+ 0104 DeskJet 880c/970c
+ 0105 ScanJet 4200c
+ 0107 CD-Writer Plus
+ 010c Multimedia Keyboard Hub
+ 0111 G55xi Printer/Scanner/Copier
+ 011c hn210w 802.11b Adapter
+ 0121 HP49g+ Calculator
+ 0201 ScanJet 6200c
+ 0202 PhotoSmart S20
+ 0204 DeskJet 815c
+ 0205 ScanJet 3300c
+ 0207 CD-Writer Plus 8200e
+ 020c Multimedia Keyboard
+ 0304 DeskJet 810c/812c
+ 0305 ScanJet 4300c
+ 0311 OfficeJet G85xi
+ 0317 LaserJet 1200
+ 0401 ScanJet 5200c
+ 0404 DeskJet 830c/832c
+ 0405 ScanJet 3400cse
+ 0504 DeskJet 885c
+ 0505 ScanJet 2100c
+ 050c 5219 Wireless Keyboard
+ 0517 LaserJet 1000
+ 0601 ScanJet 6300c
+ 0604 DeskJet 840c
+ 0605 ScanJet 2200c
+ 0701 ScanJet 5300c/5370c
+ 0704 DeskJet 825c
+ 0705 ScanJet 4400c
+ 0712 DeskJet 1180c
+ 0801 ScanJet 7400c
+ 0804 DeskJet 816c
+ 0901 ScanJet 2300c
+ 0904 DeskJet 845c
+ 1004 DeskJet 970c/970cse
+ 1005 ScanJet 5400c
+ 1016 Jornada 548 / iPAQ HW6515 Pocket PC
+ 1104 DeskJet 959c
+ 1105 ScanJet 5470c
+ 1116 Jornada 568 Pocket PC
+ 1151 750xi Printer/Scanner/Copier
+ 1204 DeskJet 930c
+ 1305 ScanJet 4570c
+ 1317 LaserJet 1005
+ 1405 Scanjet 3670
+ 1504 DeskJet 920c
+ 1604 DeskJet 940c
+ 1904 DeskJet 3820
+ 1c17 Color LaserJet 2550l
+ 1e11 PSC-950
+ 2002 Hub
+ 2004 DeskJet 640c
+ 2005 ScanJet 3570c
+ 2104 DeskJet 630c
+ 2205 ScanJet 3500c
+ 2304 DeskJet 656c
+ 2305 ScanJet 3970c
+ 2811 PSC-2100
+ 2d11 OfficeJet 6110
+ 3102 PhotoSmart P1100 Printer w/ Card Reader
+ 3104 DeskJet 960c
+ 3304 DeskJet 990c
+ 3404 DeskJet 6122
+ 3504 DeskJet 6127c
+ 3c02 PhotoSmart 7350
+ 3d11 OfficeJet 4215
+ 3f11 PSC-1315/PSC-1317
+ 4002 PhotoSmart 720 / PhotoSmart 935 (storage)
+ 4102 PhotoSmart 618
+ 4202 PhotoSmart 812
+ 4302 PhotoSmart 850 (ptp)
+ 4402 PhotoSmart 935 (ptp)
+ 5004 DeskJet 995c
+ 6004 DeskJet 5550
+ 6104 DeskJet 5650c
+ 6202 PhotoSmart 215
+ 6204 DeskJet 5150c
+ 6302 PhotoSmart 318/612
+ 6402 PhotoSmart 715 (ptp)
+ 6502 PhotoSmart 120 (ptp)
+ 6602 PhotoSmart 320
+ 6702 PhotoSmart 720 (ptp)
+ 6802 PhotoSmart 620 (ptp)
+ 6a02 PhotoSmart 735 (ptp)
+ 7004 DeskJet 3320c
+ 7104 DeskJet 3420c
+ 7202 PhotoSmart 43x (ptp)
+ 7204 DeskJet 36xx
+ 7304 DeskJet 35xx
+ a004 DeskJet 5850c
+ bef4 NEC Picty760
+ efbe NEC Picty900
+ f0be NEC Picty920
+ f1be NEC Picty800
+03f1 Genoa Technology
+03f2 Oak Technology, Inc.
+03f3 Adaptec, Inc.
+03f4 Diebold, Inc.
+03f5 Siemens Electromechanical
+03f8 Epson Imaging Technology Center
+03f9 KeyTronic Corp.
+03fb OPTi, Inc.
+03fc Elitegroup Computer Systems
+03fd Xilinx, Inc.
+03fe Farallon Comunications
+0400 National Semiconductor Corp.
+ 0807 Bluetooth Dongle
+ 1000 Mustek BearPaw 1200 Scanner
+ 1001 Mustek BearPaw 2400 Scanner
+0401 National Registry, Inc.
+0402 ALi Corp.
+ 5462 M5462 IDE Controller
+ 5603 USB 2.0 Q-tec Webcam 300
+ 5621 USB 2.0 Storage Device
+ 5632 USB 2.0 Host-to-Host Link
+ 5637 M5637 IDE Controller
+0403 Future Technology Devices International, Ltd
+ 0000 H4SMK 7 Port Hub
+ 6001 8-bit FIFO
+ 8040 4 Port Hub
+ 8070 7 Port Hub
+ 8370 7 Port Hub
+ 8371 PS/2 Keyboard And Mouse
+ 8372 FT8U100AX Serial Port
+ ea90 Eclo 1-Wire Adapter
+ f208 Papenmeier Braille-Display
+ fd48 ShipModul MiniPlex-4xUSB NMEA Multiplexer
+ ff08 ToolHouse LoopBack Adapter
+0404 NCR Corp.
+ 0310 K590 Printer, Self-Service
+ 0311 7167 Printer, Receipt/Slip
+ 0312 7197 Printer Receipt
+ 0320 5932-USB Keyboard
+ 0321 5953-USB Dynakey
+ 0322 5932-USB Enhanced Keyboard
+ 0323 5932-USB Enhanced Keyboard, Flash-Recovery/Download
+ 0324 5953-USB Enhanced Dynakey
+ 0325 5953-USB Enhanced Dynakey Flash-Recovery/Download
+ 0328 K016: USB-MSR ISO 3-track MSR: POS Standard (See HID pages)
+ 0329 K018: USB-MSR JIS 2-Track MSR: POS Standard
+ 032a K016: USB-MSR ISO 3-Track MSR: HID Keyboard Mode
+ 032b K016/K018: USB-MSR Flash-Recovery/Download
+0405 Synopsys, Inc.
+0406 Fujitsu-ICL Computers
+0407 Fujitsu Personal Systems, Inc.
+0408 Quanta Computer, Inc.
+0409 NEC Corp.
+ 0012 ATerm IT75DSU ISDN TA
+ 0014 Japanese Keyboard
+ 0027 MultiSync Monitor
+ 0058 HighSpeed Hub
+ 0059 HighSpeed Hub
+ 006a Conceptronic USB Harddisk Box
+ 011d e228 Mobile Phone
+ 55aa Hub
+ 55ab Hub [iMac/iTouch kbd]
+ efbe P!cty 900 [HP DJ]
+ f0be P!cty 920 [HP DJ 812c]
+040a Kodak Co.
+ 0001 DVC-323
+ 0002 DVC-325
+ 0100 DC-220
+ 0110 DC-260
+ 0111 DC-265
+ 0112 DC-290
+ 0120 DC-240
+ 0121 DC-240 (PTP firmware)
+ 0130 DC-280
+ 0131 DC-5000
+ 0132 DC-3400
+ 0140 DC-4800
+ 0160 DC4800
+ 0170 DX3900
+ 0300 EZ-200
+ 0400 MC3
+ 0500 DX3500
+ 0510 DX3600
+ 0525 DX3215
+ 0530 DX3700
+ 0535 EasyShare CX4230 Camera
+ 0540 LS420
+ 0550 DX4900
+ 0555 DX4330
+ 0560 CX4200
+ 0565 CX4210
+ 0566 CX4300
+ 0568 LS443
+ 0569 LS663
+ 0570 DX6340
+ 0571 CX6330
+ 0572 DX6440
+ 0573 CX6230
+ 0574 CX6200
+ 0575 DX6490
+ 0576 DX4530
+ 057c CX7530
+ 057f DX7590
+ 5010 Wireless Adapter
+040b Weltrend Semiconductor
+ 6510 Weltrend Bar Code Reader
+ 6520 XBOX Xploder
+040c VTech Computers, Ltd
+040d VIA Technologies, Inc.
+040e MCCI
+040f Echo Speech Corp.
+0411 MelCo., Inc.
+ 0001 LUA-TX Ethernet [pegasus]
+ 0016 WLI-USB-S11 802.11b Adapter
+ 0027 WLI-USB-KS11G 802.11b Adapter
+0412 Award Software International
+0413 Leadtek Research, Inc.
+0414 Giga-Byte Technology Co., Ltd
+0416 Winbond Electronics Corp.
+ 0961 AVL Flash Card Reader
+ 5518 4-Port Hub
+ 551a PC Sync Keypad
+ 551b PC Async Keypad
+ 551c Sync Tenkey
+ 551d Async Tenkey
+ 551e Keyboard
+ 551f Keyboard w/ Sys and Media
+ 5521 Keyboard
+ 7723 SD Card Reader
+ 6481 16-bit Scanner
+0417 Symbios Logic
+0418 AST Research
+0419 Samsung Info. Systems America, Inc.
+ 0001 IrDA Remote Controller
+ 3001 Xerox P1202 Laser Printer
+ 8002 SyncMaster 757DFX HID Device
+041a Phoenix Technologies, Ltd
+041b d'TV
+041d S3, Inc.
+041e Creative Technology, Ltd
+ 1002 Nomad II
+ 1003 Blaster GamePad Cobra
+ 1050 GamePad Cobra
+ 3010 SoundBlaster MP3+
+ 3020 SoundBlaster Audigy 2 NX
+ 4003 VideoBlaster WebCam Go Plus [W9967CF]
+ 4004 Nomad II MG
+ 4005 WebCam Blaster Go ES
+ 400a PC-Cam 300
+ 400b PC-Cam 600
+ 400c WebCam 5 [pwc]
+ 400d WebCam PD1001
+ 4011 WebCam PRO eX
+ 4013 PC-Cam 750
+ 4015 CardCam Value
+ 4017 WebCam Mobile
+ 4018 WebCam Vista
+ 401c WebCam NX [PD1110]
+ 401d WebCam NX Ultra
+ 401e WebCam NX Pro
+ 401f Webcam Notebook
+ 4036 Webcam Live!/Live! Pro
+ 403a WebCam NX Pro 2
+ 403c WebCam Live! Ultra
+ 403d WebCam Notebook Ultra
+ 4100 Nomad Jukebox 2
+ 4101 Nomad Jukebox 3
+ 4106 Nomad MuVo
+ 4108 Nomad Jukebox Zen
+ 4109 Nomad Jukebox Zen NX
+ 410b Nomad Jukebox Zen USB 2.0
+ 410c Nomad MuVo NX
+ 4110 Nomad Jukebox Zen Xtra
+ 4111 Dell Digital Jukebox
+ 4116 MuVo^2
+ 4117 Nomad MuVo TX
+ 411b Zen Touch
+ 411d Zen
+ 411e Zen Micro
+ 4123 Zen Portable Media Center
+ 4126 Dell DJ (2nd gen)
+ 4127 Dell DJ
+ 412b MuVo N200 with FM radio
+ 4134 Zen Neeon
+ 4136 Zen Sleek
+ 4139 Zen Nano Plus
+ 413c Zen MicroPhoto
+041f LCS Telegraphics
+0420 Chips and Technologies
+0421 Nokia Mobile Phones
+ 0401 6650 GSM Phone
+ 0405 9500 GSM Communicator
+ 040b N-Gage GSM Phone
+ 040f 6230 GSM Phone
+ 0410 6630 Imaging Smartphone
+ 0415 9300 GSM Smartphone
+ 041a 9500 GSM Communicator (RNDIS)
+ 041b 9300 GSM Smartphone (RNDIS)
+ 0429 6230i Camera Phone
+ 0800 Connectivity Cable DKU-5
+0422 ADI Systems, Inc.
+0423 Computer Access Technology Corp.
+ 000a NetMate Ethernet
+ 000c NetMate2 Ethernet
+ 000d USB Chief Analyzer
+ 1237 Andromeda Hub
+0424 Standard Microsystems Corp.
+ 20fc 6-in-1 Card Reader
+ 223a 8-in-1 Card Reader
+0425 Motorola Semiconductors HK, Ltd
+ 0101 G-Tech Wireless Mouse & Keyboard
+0426 Integrated Device Technology, Inc.
+0427 Motorola Electronics Taiwan, Ltd
+0428 Advanced Gravis Computer Tech, Ltd
+ 4001 GamePad Pro
+0429 Cirrus Logic
+042a Ericsson Austrian, AG
+042b Intel Corp.
+042c Innovative Semiconductors, Inc.
+042d Micronics
+042e Acer, Inc.
+042f Molex, Inc.
+0430 Sun Microsystems, Inc.
+ 0005 Type 6 Keyboard
+ 0100 3-button Mouse
+0431 Itac Systems, Inc.
+0432 Unisys Corp.
+0433 Alps Electric, Inc.
+ 1101 IBM Game Controller
+0434 Samsung Info. Systems America, Inc.
+0435 Hyundai Electronics America
+0436 Taugagreining HF
+0437 Framatome Connectors USA
+0438 Advanced Micro Devices, Inc.
+0439 Voice Technologies Group
+043d Lexmark International, Inc.
+ 0002 Optra E310 Printer
+ 0009 Optra S2450 Printer
+ 000c Optra E312 Printer
+ 0017 Z32 printer
+ 0018 Z52 Printer
+ 001a Z65 Printer
+ 001c Kodak Personal Picture Maker 200 Printer
+ 001f Kodak Personal Picture Maker 200 Card Reader
+ 0020 Z51 Printer
+ 0021 Z33 Printer
+ 002d X70/X73 Scan/Print/Copy
+ 003d X83 Scan/Print/Copy
+ 0057 Z35 Printer
+ 0060 X74/X75 Scanner
+ 0061 X74 Hub
+ 0069 X74/X75 Printer
+ 0072 X6170 Printer
+043e LG Electronics USA, Inc.
+ 42bd Flatron 795FT Plus Monitor
+ 4a4d Flatron 915FT Plus Monitor
+ 7001 MF-PD100 Soul Digital MP3 Player
+ 8484 LPC-U30 Webcam II
+ 8585 LPC-UC35 Webcam
+043f RadiSys Corp.
+0440 Eizo Nanao Corp.
+0441 Winbond Systems Lab.
+ 1456 Hub
+0442 Ericsson, Inc.
+0443 Gateway, Inc.
+0445 Lucent Technologies, Inc.
+0446 NMB Technologies Corp.
+0447 Momentum Microsystems
+044a Shamrock Tech. Co., Ltd
+044b WSI
+044c CCL/ITRI
+044d Siemens Nixdorf AG
+044e Alps Electric Co., Ltd
+ 2002 MD-5500 Printer
+ 3001 UGTZ4 Bluetooth
+044f ThrustMaster, Inc.
+ 0400 HOTAS Cougar
+ a0a3 Fusion Digital GamePad
+ b203 360 Modena Pro Wheel
+ b300 Firestorm Dual Power
+ b304 Firestorm Dual Power
+0450 DFI, Inc.
+0451 Texas Instruments, Inc.
+ 1428 Hub
+ 1446 TUSB2040/2070 Hub
+ 2036 TUSB2036 Hub
+ 2046 TUSB2046 Hub
+ 2077 TUSB2077 Hub
+ 3410 TUSB3410 Microcontroller
+ 5409 Frontier Labs NEX IA+ Digital Audio Player
+ 6000 AU5 ADSL Modem (pre-reenum)
+ 6001 AU5 ADSL Modem
+ e001 GraphLink
+ e004 TI-89 Titanium Calculator
+ e008 TI-84 Plus Silver Calculator
+0452 Mitsubishi Electronics America, Inc.
+ 0050 Diamond Pro 900u CRT Monitor
+ 0051 Integrated Hub
+0453 CMD Technology
+0454 Vobis Microcomputer AG
+0455 Telematics International, Inc.
+0456 Analog Devices, Inc.
+0457 Silicon Integrated Systems Corp.
+ 0150 Super Talent 1GB Flash Drive
+ 0151 Super Flash 1GB Flash Drive
+0458 KYE Systems Corp. (Mouse Systems)
+ 0001 Mouse
+ 0002 Genius NetMouse Pro
+ 0003 Genius NetScroll+
+ 000e VideoCAM Web
+ 001a Genius WebScroll+
+ 004c Slimstar Pro Keyboard
+ 0100 EasyPen Tablet
+ 0101 CueCat
+ 1003 Genius VideoCam
+ 1004 Flight2000 F-23 Joystick
+ 100a Aashima Technology Trust Sight Fighter Vibration Feedback Joystick
+ 2001 ColorPage-Vivid Pro Scanner
+ 2007 ColorPage-HR6 V2 Scanner
+ 2008 ColorPage-HR6 V2 Scanner
+ 2009 ColorPage-HR6A Scanner
+ 2011 ColorPage-Vivid3x Scanner
+ 2013 ColorPage-HR7 Scanner
+ 2015 ColorPage-HR7LE Scanner
+ 2016 ColorPage-HR6X Scanner
+ 301d Genius MaxFire MiniPad
+ 7004 VideoCAM Express
+ 7007 VideoCAM Web
+ 7012 WebCAM USB2.0
+0459 Adobe Systems, Inc.
+045a SONICblue, Inc.
+ 0b4a SupraMax 2890 56K Modem [Lucent Atlas]
+ 0b68 SupraMax 56K Modem
+ 5210 Rio Karma Music Player
+ 5220 Rio Nitrus MP3 Player
+045b Hitachi, Ltd
+045d Nortel Networks, Ltd
+045e Microsoft Corp.
+ 0007 SideWinder Game Pad
+ 0008 SideWinder Precision Pro
+ 0009 IntelliMouse
+ 000b Natural Keyboard Elite
+ 0014 Digital Sound System 80
+ 001a SideWinder Precision Racing Wheel
+ 001b SideWinder Force Feedback 2 Joystick
+ 001d Natural Keyboard Pro
+ 001e IntelliMouse Explorer
+ 0023 Trackball Optical
+ 0024 Trackball Explorer
+ 0025 IntelliEye Mouse
+ 0026 SideWinder GamePad Pro
+ 0027 SideWinder PnP GamePad
+ 0028 SideWinder Dual Strike
+ 0029 IntelliMouse Optical
+ 002b Internet Keyboard Pro
+ 0033 Sidewinder Strategic Commander
+ 0034 SideWinder Force Feedback Wheel
+ 0038 SideWinder Precision 2
+ 0039 IntelliMouse Optical
+ 003b SideWinder Game Voice
+ 003c SideWinder Joystick
+ 0040 Wheel Mouse Optical
+ 0047 IntelliMouse Explorer 3.0
+ 0059 Wireless IntelliMouse Explorer
+ 006e MN510 802.11b Adapter
+ 007d Notebook Optical Mouse
+ 007e Wireless Transceiver for Bluetooth
+ 0083 Basic Optical Mouse
+ 008a Wireless Keyboard and Mouse
+ 008c Wireless Intellimouse Explorer 2.0
+ 00b9 Wireless Optical Mouse 3.0
+ 00bd Fingerprint Reader
+ 0284 Xbox DVD Playback Kit
+ 0288 Xbox Controller S Hub
+ 0289 Xbox Controller S
+0460 Ace Cad Enterprise Co., Ltd
+0461 Primax Electronics, Ltd
+ 0300 G2-300 Scanner
+ 0301 G2E-300 Scanner
+ 0302 G2-300 #2 Scanner
+ 0303 G2E-300 #2 Scanner
+ 0340 Colorado 9600 Scanner
+ 0341 Colorado 600u Scanner
+ 0345 Visioneer 6200 Scanner
+ 0346 Memorex Maxx 6136u Scanner
+ 0347 Primascan Colorado 2600u/Visioneer 4400 Scanner
+ 0360 Colorado 19200 Scanner
+ 0361 Colorado 1200u Scanner
+ 0364 LG Electronics Scanworks 600U Scanner
+ 0371 Visioneer Onetouch 8920 Scanner
+ 0377 Medion MD 5345 Scanner
+ 037b Medion MD 6190 Scanner
+ 0380 G2-600 Scanner
+ 0381 ReadyScan 636i Scanner
+ 0382 G2-600 #2 Scanner
+ 0383 G2E-600 Scanner
+ 0813 IBM UltraPort Camera
+ 0815 Micro Innovations WebCam
+ 0819 Fujifilm IX-30 Camera [webcam mode]
+ 081a Fujifilm IX-30 Camera [storage mode]
+ 081c Elitegroup ECS-C11 Camera
+ 081d Elitegroup ECS-C11 Storage
+ 4d01 Comfort Keyboard
+ 4d02 Mouse-in-a-Box
+ 4d03 Kensington Mouse-in-a-box
+ 4d04 Mouse
+0463 MGE UPS Systems
+ 0001 UPS
+ ffff UPS
+0464 AMP/Tycoelectronics Corp.
+0467 AT&T Paradyne
+0468 Wieson Technologies Co., Ltd
+046a Cherry GmbH
+ 0001 My3000 Keyboard
+ 0003 My3000 Hub
+ 0005 XX33 SmartCard Reader Keyboard
+ 0023 Cymotion Master Linux Keyboard
+046b American Megatrends, Inc.
+046c Toshiba Corp., Digital Media Equipment
+046d Logitech, Inc.
+ 0203 M2452 Keyboard
+ 0301 M4848 Mouse
+ 0401 HP PageScan
+ 0402 NEC PageScan
+ 040f Logitech/Storm PageScan
+ 0801 QuickCam Home
+ 0810 QuickCam Pro
+ 0840 QuickCam Express
+ 0850 QuickCam Web
+ 0870 QuickCam Express
+ 0890 QuickCam Traveler
+ 08a0 QuickCam IM
+ 08a2 Labtec WebCam Pro
+ 08b0 QuickCam 3000 Pro [pwc]
+ 08b1 QuickCam Notebook Pro
+ 08b2 QuickCam Pro 4000
+ 08b3 QuickCam Zoom
+ 08b4 QuickCam Zoom
+ 08f0 QuickCam Messenger
+ 0900 ClickSmart 310
+ 0901 ClickSmart 510
+ 0903 ClickSmart 820
+ 0905 ClickSmart 820
+ 0920 QuickCam Express
+ 0921 Labtec WebCam
+ 0928 Quickcam Express
+ 092a QuickCam for Notebooks
+ 0950 Pocket Camera
+ 0960 ClickSmart 420
+ 0970 Pocket750
+ c000 N43 [Pilot Mouse]
+ c001 N48/M-BB48 [FirstMouse Plus]
+ c002 M-BA47 [MouseMan Plus]
+ c004 WingMan Gaming Mouse
+ c00b MouseMan Wheel
+ c00c Optical Wheel Mouse
+ c00e M-BJ69 Optical Wheel Mouse
+ c012 Optical Mouse
+ c016 M-UV69a Optical Wheel Mouse
+ c01b MX310 Optical Mouse
+ c01e MX518 Optical Mouse
+ c025 MX500 Optical Mouse
+ c030 iFeel Mouse
+ c032 MouseMan iFeel
+ c03e Premium Optical Wheel Mouse
+ c202 WingMan Formula
+ c207 WingMan Extreme Digital 3D
+ c208 WingMan Gamepad Extreme
+ c209 WingMan Gamepad
+ c20a WingMan RumblePad
+ c20c WingMan Precision
+ c211 iTouch Cordless Reciever
+ c216 Dual Action Gamepad
+ c281 WingMan Force
+ c283 WingMan Force 3D
+ c285 WingMan Strike Force 3D
+ c291 WingMan Formula Force
+ c293 WingMan Formula Force GP
+ c295 Momo Force Steering Wheel
+ c2a0 Wingman Force Feedback Mouse
+ c303 iTouch Keyboard
+ c308 Internet Navigator Keyboard
+ c309 Internet Keyboard
+ c401 TrackMan Marble Wheel
+ c402 Marble Mouse (2-button)
+ c404 TrackMan Wheel
+ c408 Marble Mouse (4-button)
+ c501 Cordless Mouse Receiver
+ c503 Cordless Mouse+Keyboard Receiver
+ c504 Cordless Mouse+Keyboard Receiver
+ c505 Cordless Mouse+Keyboard Receiver
+ c506 MX-700 Cordless Mouse Receiver
+ c50b Cordless Desktop Optical
+ c50e MX-1000 Cordless Mouse Receiver
+ d001 QuickCam Pro
+046e Behavior Tech. Computer Corp.
+ 6782 BTC 7932 mouse+keyboard
+046f Crystal Semiconductor
+0471 Philips
+ 0101 DSS350 Digital Speaker System
+ 0104 DSS330 Digital Speaker System [uda1321]
+ 0201 Hub
+ 0222 Creative Nomad Jukebox
+ 0302 PCA645VC WebCam [pwc]
+ 0303 PCA646VC WebCam [pwc]
+ 0304 Askey VC010 WebCam [pwc]
+ 0307 PCVC675K WebCam [pwc]
+ 0308 PCVC680K WebCam [pwc]
+ 030c PCVC690K WebCam [pwc]
+ 0310 PCVC730K WebCam [pwc]
+ 0311 PCVC740K ToUcam Pro [pwc]
+ 0312 PCVC750K WebCam [pwc]
+ 0471 Digital Speaker System
+ 0601 OVU1020 IR Dongle (Kbd+Mouse)
+ 0701 150P1 TFT Display
+ 0811 JR24 CDRW
+ 1120 Creative Rhomba MP3 player
+ 1801 Diva MP3 player
+0472 Chicony Electronics Co., Ltd
+ 0065 PFU-65 Keyboard
+0473 Sanyo Information Business Co., Ltd
+0474 Sanyo Electric Co., Ltd
+ 0701 SCP-4900 Cellphone
+0475 Relisys/Teco Information System
+0476 AESP
+0477 Seagate Technology, Inc.
+0478 Connectix Corp.
+ 0001 QuickCam
+ 0002 QuickClip
+0479 Advanced Peripheral Laboratories
+047a Semtech Corp.
+047b Silitek Corp.
+ 0002 Keyboard and Mouse
+ 0101 BlueTooth Keyboard and Mouse
+ 020b SK-3105 SmartCard Reader
+ 1002 HP ScanJet 4300c Parallel Port
+047c Dell Computer Corp.
+047d Kensington
+ 1003 Orbit TrackBall
+ 1005 TurboBall
+ 1009 Orbit TrackBall for Mac
+ 101f PocketMouse Pro
+ 2010 Wireless Presentation Remote
+ 4005 Gravis Eliminator GamePad Pro
+ 4006 Gravis Eliminator AfterShock
+ 4008 Gravis Destroyer TiltPad
+ 5002 VideoCam CABO II
+ 5003 VideoCam
+047e Agere Systems, Inc. (Lucent)
+ 1001 USS720 Parallel Port
+ f101 Atlas Modem
+047f Plantronics, Inc.
+0480 Toshiba America Info. Systems, Inc.
+0481 Zenith Data Systems
+0482 Kyocera Corp.
+ 000e FS-1020D Printer
+0483 SGS Thomson Microelectronics
+ 1307 Cytronix 6in1 card reader
+ 163d Cool Icam Digi-MP3
+ 2016 Fingerprint Reader
+ 2017 Biometric Smart Card Reader
+ 7554 56k SoftModem
+0484 Specialix
+0485 Nokia Monitors
+0486 ASUS Computers, Inc.
+0487 Stewart Connector
+0488 Cirque Corp.
+0489 Foxconn / Hon Hai
+ 0502 SmartMedia Card Reader Firmware Loader
+ 0503 SmartMedia Card Reader
+048a S-MOS Systems, Inc.
+048c Alps Electric Ireland, Ltd
+048d Integrated Technology Express, Inc.
+048f Eicon Tech.
+0490 United Microelectronics Corp.
+0491 Capetronic
+0492 Samsung SemiConductor, Inc.
+0493 MAG Technology Co., Ltd
+0495 ESS Technology, Inc.
+0496 Micron Electronics
+0497 Smile International
+0498 Capetronic (Kaohsiung) Corp.
+0499 Yamaha Corp.
+ 6001 CRW2200UX Lightspeed 2 External CD-RW Drive
+049a Gandalf Technologies, Ltd
+049b Curtis Computer Products
+049c Acer Advanced Labs, Inc.
+ 0002 Keyboard (???)
+049d VLSI Technology
+049f Compaq Computer Corp.
+ 0003 iPAQ PocketPC
+ 000e Internet Keyboard
+ 0018 PA-1/PA-2 MP3 Player
+ 001a S4 100 Scanner
+ 0021 S200 Scanner
+ 0033 801.11b Adapter [orinoco]
+ 0051 KU-0133 Easy Access Interner Keyboard
+ 505a SA-11x0 based Linux Device, or Itsy (experimental)
+ 8511 iPAQ Networking 10/100 Ethernet [pegasus2]
+04a0 Digital Equipment Corp.
+04a1 SystemSoft Corp.
+04a2 FirePower Systems
+04a3 Trident Microsystems, Inc.
+04a4 Hitachi, Ltd
+04a5 Acer Peripherals Inc. (now BenQ Corp.)
+ 0001 Keyboard
+ 12a6 AcerScan C310U
+ 1a20 Prisa 310U
+ 1a2a Prisa 620U
+ 2022 Prisa 320U/340U
+ 2040 Prisa 620UT
+ 2060 Prisa 620U+/640U
+ 207e Prisa 640BU
+ 20b0 S2W 3300U/4300U
+ 20be Prisa 640BT
+ 20c0 Prisa 1240UT
+ 20de S2W 4300U+
+ 20fc Benq 5000
+ 20fe SW2 5300U
+ 3003 Benq WebCam
+ 3008 Benq 1500
+ 300a Benq 3410
+ 300c Benq 1016
+ 9213 Kbd Hub
+04a6 Nokia Display Products
+04a7 Visioneer
+ 0211 OneTouch 7600 Scanner
+ 0221 OneTouch 5300 Scanner
+ 0224 OneTouch 4800 USB/Microtek Scanport 3000
+ 0226 OneTouch 5300 USB
+ 0231 6100 Scanner
+ 0311 6200 EPP/USB Scanner
+ 0321 OneTouch 8100 EPP/USB Scanner
+ 0331 OneTouch 8600 EPP/USB Scanner
+04a8 Multivideo Labs, Inc.
+04a9 Canon, Inc.
+ 1051 BJC-3000 Color Printer
+ 1056 BJC-2110 Color Printer
+ 105b S600 Printer
+ 105d S450 Printer
+ 1062 S500 Printer
+ 1064 S300 Printer
+ 106b S520 Printer
+ 106d S750 Printer
+ 1072 I850 Printer
+ 1073 I550 Printer
+ 1074 S330 Printer
+ 1094 PIXMA iP3000x Printer
+ 2201 CanoScan FB320U
+ 2202 CanoScan FB620U
+ 2204 CanoScan FB630U
+ 2205 CanoScan FB1210U
+ 2206 CanoScan N650U/N656U
+ 2207 CanoScan 1220U
+ 2208 CanoScan D660U
+ 220a CanoScan D2400UF
+ 220b CanoScan D646U
+ 220c CanoScan D1250U2
+ 220d CanoScan N670U/N676U/LiDE 20
+ 220e CanoScan N1240U/LiDE 30
+ 220f CanoScan 8000F
+ 2210 CanoScan 9900F
+ 2212 CanoScan 5000F
+ 2213 LiDE 50/LiDE 35
+ 2215 CanoScan 3000/3000F/3000ex
+ 2216 CanoScan 3200F
+ 2217 CanoScan 5200F
+ 221e CanoScan 8400F
+ 2611 SmartBase MPC400
+ 262b LaserShot LBP-1120 Printer
+ 3041 PowerShot S10
+ 3042 CanoScan FS4000US Film Scanner
+ 3043 PowerShot S20
+ 3044 EOS D30
+ 3045 PowerShot S100
+ 3046 IXY Digital
+ 3047 Digital IXUS
+ 3048 PowerShot G1
+ 3049 PowerShot Pro90 IS
+ 304b IXY Digital 300
+ 304c PowerShot S300
+ 304d Digital IXUS 300
+ 304e PowerShot A20
+ 304f PowerShot A10
+ 3051 PowerShot S110
+ 3052 Digital IXUS V
+ 3055 PowerShot G2
+ 3056 PowerShot S40
+ 3057 PowerShot S30
+ 3058 PowerShot A40
+ 3059 PowerShot A30
+ 305b ZR45MC Digital Camcorder
+ 3060 EOS D60
+ 3061 PowerShot A100
+ 3062 PowerShot A200
+ 3065 PowerShot S200
+ 3066 Digital IXUS 330
+ 3067 MV550i Digital Video Camera
+ 3069 PowerShot G3
+ 306b MVX2i Digital Video Camera
+ 306c PowerShot S45
+ 306d PowerShot S45 PtP Mode
+ 306f PowerShot G3 (ptp)
+ 3070 PowerShot S230
+ 3071 PowerShot S230 (ptp)
+ 3072 PowerShot SD100 / Digital IXUS 2 (ptp)
+ 3073 PowerShot A70 (ptp)
+ 3074 PowerShot A60 (ptp)
+ 3075 IXUS 400 Camera
+ 3076 PowerShot A300
+ 3077 PowerShot S50
+ 3078 ZR70MC Digital Camcorder
+ 307b MV630i Difital Video Camera
+ 307f Optura 20
+ 3081 Optura 10
+ 3083 EOS 10D
+ 3084 EOS 300D / EOS Digital Rebel
+ 3085 PowerShot G5
+ 3099 EOS 300D (ptp)
+ 309a PowerShot A80
+ 309b Digital IXUS (ptp)
+ 309c PowerShot S1 IS
+ 30b4 PowerShot S500
+ 30b5 PowerShot A75
+ 30b9 Powershot A85
+ 30ba PowerShot S410 Digital Elph
+ 30bb PowerShot A95
+ 30bf Digital IXUS 40
+ 30eb EOS 20D
+ 30ec EOS 20D (ptp)
+ 30ee EOS 350D
+ 30ef EOS 350D (ptp)
+04aa DaeWoo Telecom, Ltd
+04ab Chromatic Research
+04ac Micro Audiometrics Corp.
+04ad Dooin Electronics
+04af Winnov L.P.
+04b0 Nikon Corp.
+ 0102 Coolpix 990
+ 0103 Coolpix 880
+ 0104 Coolpix 995
+ 0106 Coolpix 775
+ 0107 Coolpix 5000
+ 0108 Coolpix 2500
+ 0109 Coolpix 2500 (ptp)
+ 010a Coolpix 4500
+ 010b Coolpix 4500 (ptp)
+ 010d Coolpix 5700 (ptp)
+ 010e Coolpix 4300 (storage)
+ 010f Coolpix 4300 (ptp)
+ 0111 Coolpix 3500 (ptp)
+ 0112 Coolpix 885 (ptp)
+ 0113 Coolpix 5000 (ptp)
+ 0114 Coolpix 3100 (storage)
+ 0115 Coolpix 3100 (ptp)
+ 0117 Coolpix 2100 (ptp)
+ 0119 Coolpix 5400 (ptp)
+ 011d Coolpix 3700 (ptp)
+ 012c Coolpix 4100 (storage)
+ 0136 Coolpix 7900 (storage)
+ 0137 Coolpix 7900 (ptp)
+ 0202 Coolpix SQ (ptp)
+ 0205 Coolpix 5200 (storage)
+ 0206 Coolpix 5200 (ptp)
+ 0301 Coolpix 2000 (storage)
+ 0302 Coolpix 2000 (ptp)
+ 0402 DSC D100 (ptp)
+ 4000 Coolscan LS 40 ED
+04b1 Pan International
+04b3 IBM Corp.
+ 3004 Media Access Pro Keyboard
+ 3016 UltraNav Keyboard Hub
+ 3018 UltraNav Keyboard
+ 3100 NetVista Mouse
+ 3103 ScrollPoint Pro Mouse
+ 3107 ThinkPad 800dpi Optical Travel Mouse
+ 3108 800dpi Optical Mouse w/ Scroll Point
+ 3109 Optical ScrollPoint Pro Mouse
+ 310b Red Wheel Mouse
+ 4427 Portable CD ROM
+ 4525 Double sided CRT
+ 4550 NVRAM (128 KB)
+ 4554 Cash Drawer
+ 4580 Hub w/ NVRAM
+ 4581 4800-2xx Hub w/ Cash Drawer
+ 4604 Keyboard w/ Card Reader
+ 4671 4820 LCD w/ MSR/KB
+04b4 Cypress Semiconductor Corp.
+ 0000 Dacal DC-101 CD Library
+ 0001 Mouse
+ 0002 CY7C63x0x Thermometer
+ 1002 CY7C63001 R100 FM Radio
+ 5500 HID->COM RS232 Adapter
+ 6560 CY7C65640 USB-2.0 "TetraHub"
+ 6830 USB-2.0 IDE Adapter
+ 7417 Wireless PC Lock
+ 8613 CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
+ d5d5 CY7C63x0x Zoltrix Z-Boxer GamePad
+ f000 CY30700 Licorice evaluation board
+04b5 ROHM LSI Systems USA, LLC
+04b6 Hint Corp.
+04b7 Compal Electronics, Inc.
+04b8 Seiko Epson Corp.
+ 0001 Stylus Color 740 / Photo 750
+ 0002 ISD Smart Cable for Mac
+ 0003 ISD Smart Cable
+ 0005 Stylus Printer
+ 0101 Perfection 636
+ 0102 GT-2200
+ 0103 Perfection 610
+ 0104 Perfection 1200
+ 0105 StylusScan 2000
+ 0106 Stylus Scan 2500
+ 0107 Expression 1600U
+ 0109 Expression 1640 XL
+ 010a Perfection 1640SU
+ 010b Perfection 1240
+ 010c Perfection 640
+ 010e Perfection 1680
+ 010f Perfection 1250
+ 0110 Perfection 1650
+ 0112 Perfection 2450
+ 0114 Perfection 660
+ 011b Perfection 2400 Photo
+ 011c Perfection 3200
+ 011d Perfection 1260 Photo
+ 011e Perfection 1660 Photo
+ 011f Perfection 1670
+ 0202 Receipt Printer M129C
+ 0601 Stylus Photo 875DC Card Reader
+ 0602 Stylus Photo 895 Card Reader
+ 0801 Stylus CX5200
+ 0802 Stylus CX3200
+04b9 Rainbow Technologies, Inc.
+ 1000 iKey 1000 Token
+ 1001 iKey 1200 Token
+ 1200 iKey 2000 Token
+ 1202 iKey 2032 Token
+ 1300 iKey 3000 Token
+04ba Toucan Systems, Ltd
+04bb I-O Data Device, Inc.
+ 0904 ET/TX Ethernet [pegasus]
+ 0913 ET/TX-S Ethernet [pegasus2]
+ 0922 IOData AirPort WN-B11/USBS 802.11b
+04bd Toshiba Electronics Taiwan Corp.
+04be Telia Research AB
+04bf TDK Corp.
+ 0100 MediaReader CF
+04c1 U.S. Robotics (3Com)
+ 0082 OfficeConnect Analog Modem
+ 008f Pro ISDN TA
+ 009d HomeConnect WebCam [vicam]
+ 3021 56k Voice FaxModem Pro
+04c2 Methode Electronics Far East PTE, Ltd
+04c3 Maxi Switch, Inc.
+04c4 Lockheed Martin Energy Research
+04c5 Fujitsu, Ltd
+ 1029 fi-4010c Scanner
+ 1041 fi-4120c Scanner
+ 1042 fi-4220c Scanner
+04c6 Toshiba America Electronic Components
+04c7 Micro Macro Technologies
+04c8 Konica Corp.
+ 0720 Digital Color Camera
+ 0721 e-miniD Camera
+ 0723 KD-200Z Camera
+ 0726 KD-310Z Camera
+04ca Lite-On Technology Corp.
+04cb Fuji Photo Film Co., Ltd
+ 0100 FinePix 1300 / 1400 / 4700 Zoom digital camera
+ 0103 FinePix NX-700 printer
+ 0104 FinePix A101/2600 Zoom (PC-Cam Mode)
+ 0108 FinePix F601 Zoom (Disk mode)
+ 0109 FinePix F601 Zoom (PC-Cam mode)
+ 010a FinePix S602 Zoom (Disk mode)
+ 010b FinePix S602 Zoom (PC-Cam mode)
+ 0114 FinePix F401 Zoom (Disk mode)
+ 0115 FinePix F401 Zoom (PC-Cam mode)
+ 0116 FinePix A203 (Disk mode)
+ 0117 FinePix A203 (PC-Cam mode)
+ 011a FinePix S304/3800 (Disk mode)
+ 011b FinePix S304/3800 (PC-Cam mode)
+ 011c FinePix 2650 (Disk mode)
+ 012c FinePix S7000 Zoom (Disk mode)
+ 0130 Finepix S5000 Camera (Disk mode)
+ 0131 Finepix S5000 Camera (PC-Cam mode)
+ 0177 Finepix F10 Camera (Disk mode)
+ 0179 Finepix F10 Camera (PTP mode)
+04cc Philips Semiconductors
+ 1122 Hub
+ 1521 USB 2.0 Hub
+ 8116 Camera
+04cd Tatung Co. Of America
+04ce ScanLogic Corp.
+ 0002 SL11R-IDE IDE Bridge
+04cf Myson Century, Inc.
+ 8818 Fast 3.5" External Storage
+04d0 Digi International
+04d1 ITT Canon
+04d2 Altec Lansing Technologies
+ 0311 ADA-310 Speakers
+ ff05 ADA-305 Speakers
+04d3 VidUS, Inc.
+04d4 LSI Logic, Inc.
+04d5 Forte Technologies, Inc.
+04d6 Mentor Graphics
+04d7 Oki Semiconductor
+04d8 Microchip Technology, Inc.
+ 8000 In-Circuit Debugger
+04d9 Holtek Semiconductor, Inc.
+04da Panasonic (Matsushita)
+ 2372 Lumix DMC-FZ10 Camera
+04db Hypertec Pty, Ltd
+04dc Huan Hsin Holdings, Ltd
+04dd Sharp Corp.
+ 7004 VE-CG40U Digital Still Camera
+ 7005 VE-CG30 Digital Still Camera
+ 7007 VL-Z7S Digital Camcorder
+ 8004 Zaurus SL-5000D/SL-5500 PDA
+ 8005 Zaurus A-300
+ 8006 Zaurus SL-B500/SL-5600 PDA
+ 8007 Zaurus C-700 PDA
+ 9014 IM-DR80 Portable NetMD Player
+ 9031 Zaurus C-750/C-760/C-860/SL-C3000 PDA
+ 9032 Zaurus SL-6000
+ 9050 Zaurus C-860 PDA
+04de MindShare, Inc.
+04df Interlink Electronics
+04e1 Iiyama North America, Inc.
+ 0201 Monitor Hub
+04e2 Exar Corp.
+04e3 Zilog, Inc.
+04e4 ACC Microelectronics
+04e5 Promise Technology
+04e6 SCM Microsystems, Inc.
+ 0001 E-USB ATA Bridge
+ 0002 eUSCSI SCSI Bridge
+ 0003 eUSB SmartMedia Card Reader
+ 0005 eUSB SmartMedia/CompactFlash Card Reader
+ 0006 eUSB SmartMedia Card Reader
+ 0007 Hifd
+ 0101 eUSB ATA Bridge
+ 0325 eUSB ORCA Quad Reader
+ 0500 Veridicom 5thSense Fingerprint Sensor and eUSB SmartCard
+ 1010 USBAT-2 CompactFlash Card Reader
+ 5111 SCR331-DI SmartCard Reader
+ 5113 SCR333 SmartCard Reader
+ 5115 SCR335 SmartCard Reader
+ 5116 SCR331-LC1 SmartCard Reader
+ e001 SCR331 SmartCard Reader
+ e003 SPR532 PinPad SmartCard Reader
+04e7 Elo TouchSystems
+ 0001 TouchScreen
+04e8 Samsung Electronics Co., Ltd
+ 0110 Connect3D Flash Drive
+ 0111 Connect3D Flash Drive
+ 1003 MP3 Player and Recorder
+ 300c ML-1210 Printer
+ 324c ML-1740 Printer
+ 3260 CLP-510 Color Laser Printer
+ 5a03 Yepp MP3 Player
+ 6601 Z100 Mobile Phone
+04e9 PC-Tel, Inc.
+04ea Brooktree Corp.
+04eb Northstar Systems, Inc.
+04ec Tokyo Electron Device, Ltd
+04ed Annabooks
+04ef Pacific Electronic International, Inc.
+04f0 Daewoo Electronics Co., Ltd
+04f1 Victor Company of Japan, Ltd
+ 0001 GC-QX3 Digital Still Camera
+ 0004 GR-DVL815U Digital Video Camera
+ 0009 GR-DX25EK Digital Video Camera
+ 000a GR-D72 Digital Video Camera
+04f2 Chicony Electronics Co., Ltd
+ 0001 KU-8933 Keyboard
+ 0002 NT68P81 Keyboard
+ 0110 KU-2971 Keyboard
+ 0112 KU-8933 Keyboard with PS/2 Mouse port
+ 0116 KU-2971 German Keyboard
+04f3 Elan Microelectronics Corp.
+04f4 Harting Elektronik, Inc.
+04f5 Fujitsu-ICL Systems, Inc.
+04f6 Norand Corp.
+04f7 Newnex Technology Corp.
+04f8 FuturePlus Systems
+04f9 Brother Industries, Ltd
+ 0002 HL-1050 Laser Printer
+ 0006 HL-1240 Laser Printer
+ 0007 HL-1250 Laser Printer
+ 0008 HL-1270 Laser Printer
+ 000d HL-1440 Laser Printer
+ 010f MFC 5100C
+ 0111 MFC 6800
+ 2004 PT-2300/2310 p-Touch Laber Printer
+04fa Dallas Semiconductor
+ 2490 DS1490F 2-in-1 Fob, 1-Wire adapter
+ 4201 DS4201 Audio DAC
+04fb Biostar Microtech International Corp.
+04fc Sunplus Technology Co., Ltd
+ 0003 CM1092 Optical Scroller Mouse
+ 0561 Flexcam 100
+ 504a SPCA504a Digital Camera
+ 504b Aiptek, 1.3 mega PockerCam
+ 7333 Finet Technology Palmpix DC-85
+04fd Soliton Systems, K.K.
+04fe PFU, Ltd
+04ff E-CMOS Corp.
+0500 Siam United Hi-Tech
+0501 Fujikura DDK, Ltd
+0502 Acer, Inc.
+ d001 Divio NW801/DVC-V6+ Digital Camera
+0503 Hitachi America, Ltd
+0504 Hayes Microcomputer Products
+0506 3Com Corp.
+ 00a0 3CREB96 Bluetooth Adapter
+ 03e8 3C19250 Ethernet [klsi]
+ 0a11 3CRWE254G72 802.11g Adapter
+ 00df 3Com Home Connect lite
+ 4601 3C460B 10/100 Ethernet Adapter
+ f002 3CP4218 ADSL Modem (pre-init)
+ f003 3CP4218 ADSL Modem
+ f100 3CP4218 ADSL Modem (pre-init)
+0507 Hosiden Corp.
+ 0011 Konami ParaParaParadise Controller
+0508 Clarion Co., Ltd
+0509 Aztech Systems, Ltd
+050a Cinch Connectors
+050b Cable System International
+050c InnoMedia, Inc.
+050d Belkin Components
+ 0103 F5U103 Serial Adapter [etek]
+ 0108 F1DE108B KVM
+ 0109 F5U109/F5U409 PDA Adapter
+ 0115 SCSI Adapter
+ 0121 F5D5050 100Mbps Ethernet
+ 0208 USBView II Video Adapter [nt1004]
+ 0224 F5U224 USB 2.0 4-Port Hub
+ 0234 F5U234 USB 2.0 4-Port Hub
+ 0803 Nostromo 1745 GamePad
+ 0805 Nostromo N50 GamePad
+ 1203 F5U120-PC Serial Port
+ 7050 F5D7050 ver 1000 WiFi
+050e Neon Technology, Inc.
+050f KC Technology, Inc.
+ 0003 KC82C160S Hub
+ 0180 KC-180 IrDA Dongle
+ 0190 KC2190 USB Host-to-Host cable
+0510 Sejin Electron, Inc.
+0511 N'Able (DataBook) Technologies, Inc.
+0512 Hualon Microelectronics Corp.
+0513 digital-X, Inc.
+0514 FCI Electronics
+0515 ACTC
+0516 Longwell Electronics
+0517 Butterfly Communications
+0518 EzKEY Corp.
+0519 Star Micronics Co., Ltd
+ c002 Xlive Bluetooth XBM-100S MP3 Player
+051a WYSE Technology
+051b Silicon Graphics
+051c Shuttle, Inc.
+051d American Power Conversion
+ 0002 Back-UPS Pro 500/1000/1500
+051e Scientific Atlanta, Inc.
+051f IO Systems (Elite Electronics), Inc.
+0520 Taiwan Semiconductor Manufacturing Co.
+0521 Airborn Connectors
+0522 Advanced Connectek, Inc.
+0523 ATEN GmbH
+0524 Sola Electronics
+0525 Netchip Technology, Inc.
+ 1080 NET1080 USB-USB Bridge
+ a4a0 Linux-USB "Gadget Zero"
+ a4a1 Linux-USB Ethernet Gadget
+ a4a2 Linux-USB Ethernet/RNDIS Gadget
+ a4a3 Linux-USB user-mode isochronous source/sink
+ a4a4 Linux-USB user-mode bulk source/sink
+ a4a5 Linux-USB File Storage Gadget
+ a4a6 Linux-USB Serial Gadget
+ a4a7 Linux-USB Serial Gadget (CDC ACM mode)
+0526 Temic MHS S.A.
+0527 ALTRA
+0528 ATI Technologies, Inc.
+ 7561 TV Wonder
+0529 Aladdin Knowledge Systems
+ 0001 HASP v0.06
+ 030b eToken R1 v3.1.3.x
+ 0313 eToken R1 v3.2.3.x
+ 031b eToken R1 v3.3.3.x
+ 0323 eToken R1 v3.4.3.x
+ 0412 eToken R2 v2.2.4.x
+ 041a eToken R2 v2.2.4.x
+ 0422 eToken R2 v2.4.4.x
+ 042a eToken R2 v2.5.4.x
+ 050c eToken Pro v4.1.5.x
+ 0514 eToken Pro v4.2.5.4
+052a Crescent Heart Software
+052b Tekom Technologies, Inc.
+ 1513 Aosta CX100 WebCam
+ 1514 Aosta CX100 WebCam Storage
+052c Canon Information Systems, Inc.
+052d Avid Electronics Corp.
+052e Standard Microsystems Corp.
+052f Unicore Software, Inc.
+0530 American Microsystems, Inc.
+0531 Wacom Technology Corp.
+0532 Systech Corp.
+0533 Alcatel Mobile Phones
+0534 Motorola, Inc.
+0535 LIH TZU Electric Co., Ltd
+0536 Hand Held Products (Welch Allyn, Inc.)
+0537 Inventec Corp.
+0538 Caldera International, Inc. (SCO)
+0539 Shyh Shiun Terminals Co., Ltd
+053a Preh Werke GmbH & Co. KG
+053b Global Village Communication
+053c Institut of Microelectronic & Mechatronic Systems
+053d Silicon Architect
+053e Mobility Electronics
+053f Synopsys, Inc.
+0540 UniAccess AB
+ 0101 Panache Surf ISDN TA
+0541 Sirf Technology, Inc.
+0543 ViewSonic Corp.
+ 00fe G773 Monitor Hub
+ 00ff P815 Monitor Hub
+ 4153 ViewSonic G773 Control (?)
+0544 Cristie Electronics, Ltd
+0545 Xirlink, Inc.
+ 8002 IBM NetCamera
+ 800c Veo StingRay
+ 8080 IBM C-It WebCam
+ 810a Veo Advanced Connect WebCam
+0546 Polaroid Corp.
+ 1bed PDC 1320 Camera
+0547 Anchor Chips, Inc.
+ 2131 AN2131 EZUSB Microcontroller
+ 2235 AN2235 EZUSB-FX Microcontroller
+ 2720 AN2720 USB-USB Bridge
+ 2727 Xircom PGUNET USB-USB Bridge
+ 2810 Cypress USB ATAPI Bridge
+ 9999 AN2131 uninitialized (?)
+0548 Tyan Computer Corp.
+ 1005 EZ Cart II GameBoy Flash Programmer
+0549 Pixera Corp.
+054a Fujitsu Microelectronics, Inc.
+054b New Media Corp.
+054c Sony Corp.
+ 0010 DSC-S30/S70/S75/F505V/F505/FD92 Cybershot/Mavica Digital Camera
+ 0023 CD Writer
+ 0024 Mavica CD-1000 Camera
+ 0025 NW-MS7 Walkman MemoryStick Reader
+ 002d MSAC-US1 MemoryStick Reader
+ 002e Sony HandyCam MemoryStick Reader
+ 0032 MemoryStick MSC-U01 Reader
+ 0038 Clie PEG-S300/D PalmOS PDA
+ 004e DSC-xxx (ptp)
+ 0058 Clie PEG-N7x0C PalmOS PDA Mass Storage
+ 0066 Clie PEG-N7x0C/PEG-T425 PalmOS PDA Serial
+ 0069 Memorystick MSC-U03 Reader
+ 006d Clie PEG-T425 PDA Mass Storage
+ 008b Micro Vault 64M Mass Storage
+ 0099 Clie NR70 PDA Mass Storage
+ 009a Clie NR70 PDA Serial
+ 00c0 Handycam DCR-30
+ 00c8 MZ-N710 Minidisc Walkman
+ 00ca MZ-DN430 Minidisc Walkman
+ 00cb MSAC-US20 Memory Stick Reader
+ 0105 Micro Vault Hub
+ 0107 VCC-U01 Visual Communication Camera
+ 0144 Clie PEG-TH55 PDA
+ 014c Aiwa AM-NX9 Net MD Music Recorder MDLP
+ 014d Memory Stick Reader/Writer
+ 0169 Clie PEG-TJ35 PDA Serial
+ 016a Clie PEG-TJ35 PDA Mass Storage
+ 01c3 NW-E55 Network Walkman
+ 01d0 DVD+RW External Drive DRU-700A
+ 023b DVD+RW External Drive DRU-800UL
+054d Try Corp.
+054e Proside Corp.
+054f WYSE Technology Taiwan
+0550 Fuji Xerox Co., Ltd
+0551 CompuTrend Systems, Inc.
+0552 Philips Monitors
+0553 STMicroelectronics Imaging Division (VLSI Vision)
+ 0002 CPiA WebCam
+ 0151 Digital Blue QX5 Microscope
+ 0202 Aiptek PenCam 1
+0554 Dictaphone Corp.
+0555 ANAM S&T Co., Ltd
+0556 Asahi Kasei Microsystems Co., Ltd
+ 0001 AK5370 I/F A/D Converter
+0557 ATEN International Co., Ltd
+ 2001 UC-1284 Printer Port
+ 2002 10Mbps Ethernet [klsi]
+ 2004 UC-100KM PS/2 Mouse and Keyboard adapter
+ 2006 UC-1284B Printer Port
+ 2007 UC-110T 100Mbps Ethernet [pegasus]
+ 2008 UC-232A Serial Port [pl2303]
+ 2202 CS124U Miniview II KVM Switch
+ 2600 IDE Bridge
+ 4000 DSB-650 10Mbps Ethernet [klsi]
+0558 Truevision, Inc.
+0559 Cadence Design Systems, Inc.
+055a Kenwood USA
+055b KnowledgeTek, Inc.
+055c Proton Electronic Ind.
+055d Samsung Electro-Mechanics Co.
+ 9000 AnyCam [pwc]
+ 9001 MPC-C30 AnyCam Premium for Notebooks [pwc]
+055e CTX Opto-Electronics Corp.
+055f Mustek Systems, Inc.
+ 0001 ScanExpress 1200 CU
+ 0002 ScanExpress 600 CU
+ 0003 ScanExpress 1200 USB
+ 0006 ScanExpress 1200 UB
+ 0007 ScanExpress 1200 USB Plus
+ 0008 ScanExpress 1200 CU Plus
+ 0010 BearPaw 1200F
+ 0210 ScanExpress A3 USB
+ 0218 BearPaw 2400 TA
+ 0219 BearPaw 2400 TA Plus
+ 021a BearPaw 2448 TA Plus
+ 021c BearPaw 1200 CU Plus
+ 021d BearPaw 2400 CU Plus
+ 021e BearPaw 1200 TA/CS
+ 0400 BearPaw 2400 TA Pro
+ 0401 P 3600 A3 Pro
+ 0873 ScanExpress 600 USB
+ 1000 BearPaw 4800 TA Pro
+ a350 gSmart 350
+ a800 MDC 800 Camera
+ b500 MDC 3000 Camera
+ c200 gSmart 300
+ c220 gSmart mini
+ c360 Mustek DV 4000
+ c420 gSmart mini 2
+ c440 Mustek DV 3000
+ c520 gSmart mini 3
+ c530 Mustek Gsmart LCD 2
+ c650 Mustek MDC5500Z
+ d001 WCam 300
+0560 Interface Corp.
+0561 Oasis Design, Inc.
+0562 Telex Communications, Inc.
+ 0001 Enhanced Microphone
+0563 Immersion Corp.
+0564 Chinon Industries, Inc.
+0565 Peracom Networks, Inc.
+ 0001 Serial Port [etek]
+ 0002 Enet Ethernet [klsi]
+ 0003 @Home Networks Ethernet [klsi]
+ 0005 Enet2 Ethernet [klsi]
+0566 Monterey International Corp.
+0567 Xyratex International, Ltd
+0568 Quartz Ingenierie
+0569 SegaSoft
+056a Wacom Co., Ltd
+ 0000 PenPartner
+ 0010 Graphire
+ 0011 Graphire 2
+ 0020 Intuos 4x5
+ 0021 Intuos 6x8
+ 0022 Intuos 9x12
+ 0023 Intuos 12x12
+ 0024 Intuos 12x18
+ 0031 PL500
+ 0042 Intuos 2 6x8
+ 0043 Intuos 2
+056b Decicon, Inc.
+056c eTEK Labs
+ 8007 Kwik232 Serial Port
+ 8101 KwikLink USB-USB Bridge
+056d EIZO Corp.
+ 0000 Hub
+ 0001 Monitor
+056e Elecom Co., Ltd
+ 0002 29UO Mouse
+ 4002 Laneed 100Mbps Ethernet LD-USB/TX [pegasus]
+056f Korea Data Systems Co., Ltd
+0570 Epson America
+0571 Interex, Inc.
+ 0002 echoFX InterView Lite
+0572 Conexant Systems (Rockwell), Inc.
+ 0001 Ezcam II WebCam
+ 0002 Ezcam II WebCam
+ 0040 Wondereye CP-115 WebCam
+ 1232 V.90 modem
+ cafe AccessRunner ADSL Modem
+ cb00 E-Tech ADSL Modem v2
+ cb01 GeekADSL Promax Q31 ADSL Modem
+0573 Zoran Co. Personal Media Division (Nogatech)
+ 0003 USBGear USBG-V1
+ 0400 D-Link V100
+ 2000 X10 va10a Wireless Camera
+ 2101 Zoran Co. PMD (Nogatech) AV-grabber Manhattan
+ 2d00 Osprey 50
+ 2d01 Hauppauge USB-Live Model 600
+ 4100 USB-TV FM (NTSC)
+ 4110 PNY USB-TV (NTSC) FM
+ 4450 PixelView PlayTv-USB PRO (PAL) FM
+ 4550 ZTV ZT-721 2.4GHz USB A/V Receiver
+ 4d00 Hauppauge WinTV-USB USA
+ 4d01 Hauppauge WinTV-USB
+ 4d02 Hauppauge WinTV-USB UK
+ 4d03 Hauppauge WinTV-USB France
+ 4d10 Hauppauge WinTV-USB with FM USA radio
+ 4d11 Hauppauge WinTV-USB (PAL) with FM radio
+ 4d12 Hauppauge WinTV-USB UK with FM Radio
+ 4d20 Hauppauge WinTV-USB II (PAL) with FM radio
+ 4d21 Hauppauge WinTV-USB II (PAL)
+ 4d22 Hauppauge WinTV-USB II (PAL) Model 566
+ 4d23 Hauppauge WinTV-USB France 4D23
+ 4d25 Hauppauge WinTV-USB Model 40209 rev B234
+ 4d26 Hauppauge WinTV-USB Model 40209 rev B243
+ 4d27 Hauppauge WinTV-USB Model 40204 Rev B281
+ 4d28 Hauppauge WinTV-USB Model 40204 rev B283
+ 4d29 Hauppauge WinTV-USB Model 40205 rev B298
+ 4d2a Hauppague WinTV-USB Model 602 Rev B285
+ 4d2b Hauppague WinTV-USB Model 602 Rev B282
+ 4d30 Hauppauge WinTV-USB FM Model 40211 Rev B123
+ 4d31 Hauppauge WinTV-USB III (PAL) with FM radio Model 568
+ 4d32 Hauppauge WinTV-USB III (PAL) FM Model 573
+ 4d35 Hauppauge WinTV-USB III (PAL) FM Model 597
+ 4d37 Hauppauge WinTV-USB Model 40219 rev E189
+0574 City University of Hong Kong
+0575 Philips Creative Display Solutions
+0576 BAFO/Quality Computer Accessories
+0577 ELSA
+0578 Intrinsix Corp.
+0579 GVC Corp.
+057a Samsung Electronics America
+057b Y-E Data, Inc.
+ 0000 FlashBuster-U Floppy
+ 0001 Tri-Media Reader Floppy
+ 0006 Tri-Media Reader Card Reader
+ 0010 Memory Stick Reader Writer
+ 0020 HEXA Media Drive 6-in-1 Card Reader Writer
+ 0030 Memory Card Viewer (TV)
+057c AVM GmbH
+ 2800 ISDN-Connector TA
+ 3800 BlueFRITZ! Bluetooth Stick
+ 3d00 Fritz!Box
+057d Shark Multimedia, Inc.
+057e Nintendo Co., Ltd
+057f QuickShot, Ltd
+0580 Denron, Inc.
+0581 Racal Data Group
+0582 Roland Corp.
+ 0002 MPU64 Midi Interface
+ 0003 Sound Canvas SC-8850
+ 0005 Edirol UM-2 MIDI Adapter
+ 0011 Edirol UA-5 Sound Capture
+ 002d VX-2020 Synthesizer
+0583 Padix Co., Ltd (Rockfire)
+ 2030 RM-203 USB Nest [mode 1]
+ 2031 RM-203 USB Nest [mode 2]
+ 2032 RM-203 USB Nest [mode 3]
+ 2033 RM-203 USB Nest [mode 4]
+ 2050 PX-205 PSX Bridge
+ 3050 QF-305u Gamepad
+ 688f QF-688uv Windstorm Pro Joystick
+ 7070 QF-707u Bazooka Joystick
+0584 RATOC System, Inc.
+0585 FlashPoint Technology, Inc.
+0586 ZyXEL Communications Corp.
+ 1000 Omni NET Modem / ISDN TA
+0587 America Kotobuki Electronics Industries, Inc.
+0588 Sapien Design
+0589 Victron
+058a Nohau Corp.
+058b Infineon Technologies
+058c In Focus Systems
+058d Micrel Semiconductor
+058e Tripath Technology, Inc.
+058f Alcor Micro Corp.
+ 2802 Monterey Keyboard
+ 5492 Hub
+ 6232 Hi-Speed 16-in-1 Flash Card Reader/Writer
+ 9213 MacAlly Kbd Hub
+ 9215 AU9814 Hub
+ 9254 Hub
+ 9330 SD Reader
+ 9380 Flash drive
+ 9382 Acer/Sweex Flash drive
+ 9410 Keyboard
+ 9472 Keyboard Hub
+0590 Omron Corp.
+ 0004 Cable Modem
+0591 Questra Consulting
+0592 Powerware Corp.
+0593 Incite
+0594 Princeton Graphic Systems
+0595 Zoran Microelectronics, Ltd
+0596 MicroTouch Systems, Inc.
+ 0001 Touchscreen
+0597 Trisignal Communications
+0598 Niigata Canotec Co., Inc.
+0599 Brilliance Semiconductor, Inc.
+059a Spectrum Signal Processing, Inc.
+059b Iomega Corp.
+ 0001 Zip 100 (Type 1)
+ 000b Zip 100 (Type 2)
+ 0030 Zip 250 (Ver 1)
+ 0031 Zip 100 (Type 3)
+ 0032 Zip 250 (Ver 2)
+ 0040 SCSI Bridge
+ 0050 Zip CD 650 Writer
+ 0053 CDRW55292EXT CD-RW External Drive
+ 006d HipZip MP3 Player
+ 015d Super DVD Writer
+ 1052 DVD+RW External Drive
+059c A-Trend Technology Co., Ltd
+059d Advanced Input Devices
+059e Intelligent Instrumentation
+059f LaCie, Ltd
+ 0211 PocketDrive
+ 0212 PocketDrive
+ a601 HardDrive
+05a0 Vetronix Corp.
+05a1 USC Corp.
+05a2 Fuji Film Microdevices Co., Ltd
+05a3 ARC International
+05a4 Ortek Technology, Inc.
+ 9731 MCK-600W Keyboard
+05a5 Sampo Technology Corp.
+05a6 Cisco Systems, Inc.
+05a7 Bose Corp.
+05a8 Spacetec IMC Corp.
+05a9 OmniVision Technologies, Inc.
+ 0511 OV511 WebCam
+ 0518 OV518 WebCam
+ a511 OV511+ WebCam
+05aa Utilux South China, Ltd
+05ab In-System Design
+ 0002 Parallel Port
+ 0031 ATA Bridge
+ 0060 USB 2.0 ATA Bridge
+ 0200 USS725 ATA Bridge
+ 0202 ATA Bridge
+ 081a ATA Bridge
+ 0cda ATA Bridge for CD-R/RW
+05ac Apple Computer, Inc.
+ 0201 iMac Keyboard [ALPS M2452]
+ 0202 Apple Keyboard [ALPS]
+ 0205 Apple Extended Keyboard [Mitsumi]
+ 0206 Apple Extended Keyboard [Mitsumi]
+ 020e Apple Internal Keyboard/Trackpad
+ 020f Apple Internal Keyboard/Trackpad
+ 0301 iMac Mouse [Mitsumi/Logitech]
+ 0302 Apple Optical Mouse [Fujitsu]
+ 1001 Apple Keyboard Hub [ALPS]
+ 1002 Apple Extended Keyboard Hub [Mitsumi]
+ 1101 Speakers
+ 1201 3G iPod
+ 1300 iPod Shuffle
+ 8202 HCF V.90 Data/Fax Modem
+ 8203 Bluetooth HCI
+05ad Y.C. Cable U.S.A., Inc.
+05ae Synopsys, Inc.
+05af Jing-Mold Enterprise Co., Ltd
+05b0 Fountain Technologies, Inc.
+05b1 First International Computer, Inc.
+05b4 LG Semicon Co., Ltd
+ 4857 M-Any DAH-210
+ 6001 Digisette DUO-MP3 AR-100
+05b5 Dialogic Corp.
+05b6 Proxima Corp.
+05b7 Medianix Semiconductor, Inc.
+05b8 Agiler, Inc.
+ 3002 Scroll Mouse
+05b9 Philips Research Laboratories
+05ba DigitalPersona, Inc.
+05bb Grey Cell Systems
+05bc 3G Green Green Globe Co., Ltd
+ 0004 Trackball
+05bd RAFI GmbH & Co. KG
+05be Tyco Electronics (Raychem)
+05bf S & S Research
+05c0 Keil Software
+05c1 Kawasaki Microelectronics, Inc.
+05c2 Media Phonics (Suisse) S.A.
+05c5 Digi International, Inc.
+05c6 Qualcomm, Inc.
+ 3100 CDMA Wireless Modem/Phone
+ 3196 CDMA Wireless Modem
+ 3197 CDMA Wireless Modem/Phone
+05c7 Qtronix Corp.
+ 1001 Lynx Mouse
+ 2011 SCorpius Keyboard
+05c8 Cheng Uei Precision Industry Co., Ltd (Foxlink)
+05c9 Semtech Corp.
+05ca Ricoh Co., Ltd
+ 0101 RDC-5300 Camera
+ 2201 RDC-7 Camera
+ 2205 Caplio RR30 / Medion MD 6126 Camera
+ 2212 Caplio R1v Camera
+05cb PowerVision Technologies, Inc.
+ 1483 PV8630 interface (scanners, webcams)
+05cc ELSA AG
+ 2100 MicroLink ISDN Office
+ 2219 MicroLink ISDN
+ 2265 MicroLink 56k
+ 2267 MicroLink 56k (V.250)
+ 2280 MicroLink 56k Fun
+ 3000 Micolink USB2Ethernet [pegasus]
+ 3363 MicroLink ADSL Fun
+05cd Silicom, Ltd
+05ce sci-worx GmbH
+05cf Sung Forn Co., Ltd
+05d0 GE Medical Systems Lunar
+05d1 Brainboxes, Ltd
+05d2 Wave Systems Corp.
+05d3 Tohoku Ricoh Co., Ltd
+05d5 Super Gate Technology Co., Ltd
+05d6 Philips Semiconductors, CICT
+05d7 Thomas & Betts Corp.
+ 0099 10Mbps Ethernet [klsi]
+05d8 Ultima Electronics Corp.
+ 4001 Artec Ultima 2000
+ 4002 Artec Ultima 2000 (GT6801 based)/Lifetec LT9385 Scanner
+ 4003 Artec E+ 48U
+ 4004 Artec E+ Pro
+ 4008 Trust Easy Webscan 19200
+ 4009 Umax Astraslim
+ 8105 Artec T1 USB TVBOX (cold)
+ 8106 Artec T1 USB TVBOX (warm)
+ 8107 Artec T1 USB TVBOX with AN2235 (cold)
+ 8108 Artec T1 USB TVBOX with AN2235 (warm)
+ 8109 Artec T1 USB2.0 TVBOX (cold
+05d9 Axiohm Transaction Solutions
+05da Microtek International, Inc.
+ 0093 ScanMaker V6USL
+ 0094 Phantom 336CX/C3
+ 0099 ScanMaker X6/X6U
+ 009a Phantom C6
+ 00a0 Phantom 336CX/C3 (#2)
+ 00b6 ScanMaker V6UPL
+ 1011 NHJ Che-ez! Kiss Digital Camera
+ 1018 Digital Dream Enigma 1.3
+ 30ce ScanMaker 3800
+ 30cf ScanMaker 4800
+ 30e6 ScanMaker i320
+ 40ca ScanMaker 3600
+ 80a3 ScanMaker V6USL (#2)
+ 80ac ScanMaker V6UL/SpicyU
+05db Sun Corp. (Suntac?)
+05dc Lexar Media, Inc.
+ 0080 Jumpdrive Secure 64MB
+ 0200 JumpDrive 2.0 Pro
+ 0300 Jumpdrive Geysr
+ b018 Multi-Card Reader
+05dd Delta Electronics, Inc.
+05df Silicon Vision, Inc.
+05e0 Symbol Technologies
+05e1 Syntek Semiconductor Co., Ltd
+05e2 ElecVision, Inc.
+05e3 Genesys Logic, Inc.
+ 000a Keyboard with PS/2 Port
+ 000b Mouse
+ 0100 Nintendo Game Boy Advance SP
+ 0120 Pacific Image Electronics PrimeFilm 1800u slide/negative scanner
+ 0300 GLUSB98PT Parallel Port
+ 0406 Hub
+ 0502 GL620USB GeneLink USB-USB Bridge
+ 0604 USB 1.1 Hub
+ 0605 USB 2.0 Hub [ednet]
+ 0660 USB 2.0 Hub
+ 0700 SIIG US2256 CompactFlash Card Reader
+ 0701 USB 2.0 IDE Adapter
+ 0702 USB 2.0 IDE Adapter
+ 0703 Card Reader
+ 0710 USB 2.0 33-in-1 Card Reader
+ 0760 Card Reader
+ 07A0 Pen Flash
+ 1205 Afilias Optical Mouse H3003
+05e4 Red Wing Corp.
+05e5 Fuji Electric Co., Ltd
+05e6 Keithley Instruments
+05e8 ICC, Inc.
+05e9 Kawasaki LSI
+ 0008 KL5KUSB101B Ethernet [klsi]
+ 0009 Sony 10Mbps Ethernet [pegasus]
+05eb FFC, Ltd
+05ec COM21, Inc.
+05ee Cytechinfo Inc.
+05ef AVB, Inc. [anko?]
+ 020a Top Shot Pegasus Joystick
+ 8884 Mag Turbo Force Wheel
+ 8888 Top Shot Force Feedback Racing Wheel
+05f0 Canopus Co., Ltd
+ 0101 DA-Port DAC
+05f1 Compass Communications
+05f2 Dexin Corp., Ltd
+05f3 PI Engineering, Inc.
+ 0007 Kinesis Advantage PRO MPC/USB Keyboard
+ 0081 Kinesis Integrated Hub
+ 020b PS2 Adapter
+ 0232 X-Keys Switch Interface, Programming Mode
+ 0261 X-Keys Switch Interface, SPLAT Mode
+ 0264 X-Keys Switch Interface, Composite Mode
+05f5 Unixtar Technology, Inc.
+05f6 AOC International
+05f7 RFC Distribution(s) PTE, Ltd
+05f9 PSC Scanning, Inc.
+05fa Siemens Telecommunications Systems, Ltd
+05fc Harman Multimedia
+05fd InterAct, Inc.
+ 0251 Raider Pro
+ 0253 ProPad 8 Digital
+ 262a 3dfx HammerHead FX
+ daae Game Shark
+05fe Chic Technology Corp.
+ 0001 Mouse
+ 0005 Viewmaster 4D Browser Mouse
+ 0007 Twinhead Mouse
+ 0009 Inland Pro 4500/5000 Mouse
+ 0011 Browser Mouse
+05ff LeCroy Corp.
+0600 Barco Display Systems
+0601 Jazz Hipster Corp.
+0602 Vista Imaging, Inc.
+ 1001 ViCam WebCam
+0603 Novatek Microelectronics Corp.
+ 00f1 Keyboard
+ 6871 Mouse
+0604 Jean Co., Ltd
+0605 Anchor C&C Co., Ltd
+0606 Royal Information Electronics Co., Ltd
+0607 Bridge Information Co., Ltd
+0608 Genrad Ads
+0609 SMK Manufacturing, Inc.
+060a Worthington Data Solutions, Inc.
+060b Solid Year
+ 0001 MacAlly Keyboard
+ 2101 Keyboard
+ 5811 ACK-571U Wireless Keyboard
+ a001 Maxwell Compact Pc PM3
+060c EEH Datalink GmbH
+060d Auctor Corp.
+060e Transmonde Technologies, Inc.
+060f Joinsoon Electronics Mfg. Co., Ltd
+0610 Costar Electronics, Inc.
+0611 Totoku Electric Co., Ltd
+0613 TransAct Technologies, Inc.
+0614 Bio-Rad Laboratories
+0615 Quabbin Wire & Cable Co., Inc.
+0616 Future Techno Designs PVT, Ltd
+0617 Swiss Federal Insitute of Technology
+0618 MacAlly
+ 0101 Mouse
+0619 Seiko Instruments, Inc.
+061a Veridicom International, Inc.
+ 0110 5thSense Fingerprint Sensor
+ 0200 FPS200 Fingerprint Sensor
+ 8200 VKI-A Fingerprint Sensor/Flash Storage (dumb)
+ 9200 VKI-B Fingerprint Sensor/Flash Storage (smart)
+061b Promptus Communications, Inc.
+061c Act Labs, Ltd
+061d Quatech, Inc.
+061e Nissei Electric Co.
+0620 Alaris, Inc.
+0621 ODU-Steckverbindungssysteme GmbH & Co. KG
+0622 Iotech, Inc.
+0623 Littelfuse, Inc.
+0624 Avocent Corp.
+0625 TiMedia Technology Co., Ltd
+0626 Nippon Systems Development Co., Ltd
+0627 Adomax Technology Co., Ltd
+0628 Tasking Software, Inc.
+0629 Zida Technologies, Ltd
+062a Creative Labs
+ 0001 Notebook Optical Mouse
+062b Greatlink Electronics Taiwan, Ltd
+062c Institute for Information Industry
+062d Taiwan Tai-Hao Enterprises Co., Ltd
+062e Mainsuper Enterprises Co., Ltd
+062f Sin Sheng Terminal & Machine, Inc.
+0631 JUJO Electronics Corp.
+0633 Cyrix Corp.
+0634 Micron Technology, Inc.
+0635 Methode Electronics, Inc.
+0636 Sierra Imaging, Inc.
+0638 Avision, Inc.
+ 0268 iVina 1200U Scanner
+ 026a Minolta Dimage Scan Dual II
+ 0a10 iVina FB1600/UMAX Astra 4500
+ 4004 Minolta Dimage Scan Elite II
+0639 Chrontel, Inc.
+063a Techwin Corp.
+063b Taugagreining HF
+063c Yamaichi Electronics Co., Ltd (Sakura)
+063d Fong Kai Industrial Co., Ltd
+063e RealMedia Technology, Inc.
+063f New Technology Cable, Ltd
+0640 Hitex Development Tools
+0641 Woods Industries, Inc.
+0642 VIA Medical Corp.
+0644 TEAC Corp.
+ 0000 Floppy
+ 800D TASCAM Portastudio DP-01FX
+0645 Who? Vision Systems, Inc.
+0646 UMAX
+0647 Acton Research Corp.
+ 0100 ARC SpectraPro UV/VIS/IR Monochromator/Spectrograph
+ 0101 ARC AM-VM Mono Airpath/Vacuum Monochromator/Spectrograph
+ 0102 ARC Inspectrum Mono
+ 0103 ARC Filterwheel
+ 03e9 Inspectrum 128x1024 F VIS Spectrograph
+ 03ea Inspectrum 256x1024 F VIS Spectrograph
+ 03eb Inspectrum 128x1024 B VIS Spectrograph
+ 03ec Inspectrum 256x1024 B VIS Spectrograph
+0648 Inside Out Networks
+0649 Weli Science Co., Ltd
+064b White Mountain DSP, Inc.
+064c Ji-Haw Industrial Co., Ltd
+064d TriTech Microelectronics, Ltd
+064e Suyin Corp.
+064f WIBU-Systems AG
+0650 Dynapro Systems
+0651 Likom Technology Sdn. Bhd.
+0652 Stargate Solutions, Inc.
+0653 CNF, Inc.
+0654 Granite Microsystems, Inc.
+0655 Space Shuttle Hi-Tech Co., Ltd
+0656 Glory Mark Electronic, Ltd
+0657 Tekcon Electronics Corp.
+0658 Sigma Designs, Inc.
+0659 Aethra
+065a Optoelectronics Co., Ltd
+ 0001 Barcode scanner
+065b Tracewell Systems
+065e Silicon Graphics
+065f Good Way Technology Co., Ltd & GWC technology Inc.
+0660 TSAY-E (BVI) International, Inc.
+0661 Hamamatsu Photonics K.K.
+0662 Kansai Electric Co., Ltd
+0663 Topmax Electronic Co., Ltd
+ 0103 CobraPad
+0667 Aiwa Co., Ltd
+ 0fa1 TD-U8000 Tape Drive
+0668 WordWand
+0669 Oce' Printing Systems GmbH
+066a Total Technologies, Ltd
+066b Linksys, Inc.
+ 0105 SCM eUSB SmartMedia Card Reader
+ 010a Melco MCR-U2 SmartMedia / CompactFlash Reader
+ 2202 USB10TX Ethernet [pegasus]
+ 2203 USB100TX Ethernet [pegasus]
+ 2204 USB100TX HomePNA Ethernet [pegasus]
+ 2206 USB Ethernet [pegasus]
+ 2211 WUSB11 802.11b Adapter
+ 2212 WUSB11v2.5 802.11b Adapter
+ 2213 WUSB12v1.1 802.11b Adapter
+066d Entrega, Inc.
+066e Acer Semiconductor America, Inc.
+066f SigmaTel, Inc.
+ 004b A-Max PA11 MP3 Player
+ 3400 STMP3400 D-Major MP3 Player
+ 3410 STMP3410 D-Major MP3 Player
+ 4200 STIr4200 IrDA Bridge
+ 4210 STIr4210 IrDA Bridge
+ 8004 MSCNMMC MP3 Player
+ 8202 Jens of Sweden / I-BEAD 150M/150H MP3 player
+0672 Labtec, Inc.
+ 1041 LCS1040 Speaker System
+ 5000 SpaceBall 4000 FLX
+0673 HCL
+ 5000 Keyboard
+0674 Key Mouse Electronic Enterprise Co., Ltd
+0675 Draytech
+ 0110 Vigor 128 ISDN TA
+0676 Teles AG
+0677 Aiwa Co., Ltd
+ 0fa1 TD-U8000 Tape Drive
+0678 ACard Technology Corp.
+067b Prolific Technology, Inc.
+ 0000 PL2301 USB-USB Bridge
+ 0001 PL2302 USB-USB Bridge
+ 2303 PL2303 Serial Port
+ 2305 PL2305 Parallel Port
+ 2307 PL2307 USB-ATAPI4 Bridge
+ 2315 Flash Disk Embedded Hub
+ 2316 Flash Disk Security Device
+ 2317 Mass Storage Device
+ 2501 PL2501 USB-USB Bridge (USB 2.0)
+ 2515 Flash Disk Embedded Hub
+ 2517 Flash Disk Mass Storage Device
+ 3507 PL3507 ATAPI6 Bridge
+067c Efficient Networks, Inc.
+ 1001 Siemens SpeedStream 100MBps Ethernet
+ 1022 Siemens SpeedStream 1022 802.11b Adapter
+ 4060 Alcatel Speedstream 4060 ADSL Modem
+067d Hohner Corp.
+067e Intermec
+067f Virata, Ltd
+0680 Realtek Semiconductor Corp., CPP Div. (Avance Logic)
+ 0002 Arowana Optical Wheel Mouse MSOP-01
+0681 Siemens Information and Communication Products
+ 0002 Gigaset 3075 Passive ISDN
+ 0005 Mouse with Fingerprint Reader
+ 0012 I-Gate 802.11b Adapter
+ 002b A-100-I ADSL Modem
+0682 Victor Company of Japan, Ltd
+0684 Actiontec Electronics, Inc.
+0686 Minolta Co., Ltd
+ 4003 Dimage 2330 Zoom Camera
+ 4004 Scan Elite II
+ 4006 Dimage 7 Camera
+ 4007 Dimage S304 Camera
+ 4008 Dimage 5 Camera
+ 4009 Dimage X Camera
+ 400a Dimage S404 Camera
+ 400b Dimage 7i Camera
+ 400c Dimage F100 Camera
+ 400d Scan Dual III
+ 400f Dimage 7Hi Camera
+ 4010 Dimage Xi Camera
+ 4011 Dimage F300 Camera
+ 4012 Dimage F200 Camera
+ 4014 Dimage S414 Camera
+ 4015 Dimage XT Camera [storage]
+ 4016 Dimage XT Camera [remote mode]
+ 4018 Dimage Z1 Camera
+ 401a Dimage A1 Camera
+ 401c Dimage X20 Camera
+ 401e Dimage E323 Camera
+068a Pertech, Inc.
+068b Potrans International, Inc.
+068e CH Products, Inc.
+ 00e2 HFX OEM Joystick
+ 00f2 Flight Sim Pedals
+ 00ff Flight Sim Yoke
+ 0500 GameStick 3D
+ 0501 CH Pro Pedals
+ 0504 F-16 Combat Stick
+0690 Golden Bridge Electech, Inc.
+0693 Hagiwara Sys-Com Co., Ltd
+ 0002 FlashGate SmartMedia Card Reader
+ 0003 FlashGate CompactFlash Card Reader
+ 0005 FlashGate
+0694 Lego Group
+ 0001 Mindstorms Tower
+0698 Chuntex (CTX)
+ 1786 1300ex Monitor
+ 9999 VLxxxx Monitor+Hub
+0699 Tektronix, Inc.
+069a Askey Computer Corp.
+ 0001 VC010 WebCam [pwc]
+ 0303 Cable Modem
+ 0321 Dynalink WLL013 / Compex WLU11A 802.11b Adapter
+ 0821 BT Voyager 1010 802.11b Adapter
+069b Thomson, Inc.
+ 0704 DCM245 Cable Modem
+ 2220 RCA Kazoo RD1000 MP3 Player
+ 300a RCA Lyra MP3 Player
+069d Hughes Network Systems (HNS)
+ 0002 Satellite Device
+069e Marx
+ 0005 CryptoBox v1.2
+069f Allied Data Technologies BV
+ 0010 Tornado Speakerphone FaxModem 56.0
+ 0011 Tornado Speakerphone FaxModem 56.0
+06a2 Topro Technology, Inc.
+06a3 Saitek PLC
+ 0006 Cyborg Gold Joystick
+ 0200 Xbox Adrenalin Hub
+ 0241 Xbox Adrenalin Gamepad
+ 0422 ST90 Joystick
+ 052d P750 Gamepad
+ 053f X36F Flightstick
+ 100a SP550 Pad and Joystick Combo
+ 100b SP550 Pad
+ 3509 P3000 RF GamePad
+06a4 Xiamen Doowell Electron Co., Ltd
+06a5 Divio
+ 0000 Typhoon Webcam 100k [nw8000]
+ d001 ProLink DS3303u WebCam
+ d800 Chicony TwinkleCam
+06a7 MicroStore, Inc.
+06a8 Topaz Systems, Inc.
+ 0042 SignatureGem 1X5 Pad
+ 0043 SignatureGem 1X5-HID Pad
+06a9 Westell
+06aa Sysgration, Ltd
+06ac Fujitsu Laboratories of America, Inc.
+06ad Greatland Electronics Taiwan, Ltd
+06ae Professional Multimedia Testing Centre
+06af Harting, Inc. of North America
+06b8 Pixela Corp.
+06b9 Alcatel Telecom
+ 0121 SpeedTouch 121g Wireless Dongle
+ 4061 SpeedTouch ISDN or ADSL Modem
+ a5a5 DynaMiTe Modem
+06ba Smooth Cord & Connector Co., Ltd
+06bb EDA, Inc.
+06bc Oki Data Corp.
+06bd AGFA-Gevaert NV
+ 0001 SnapScan 1212U
+ 0002 SnapScan 1236U
+ 0100 SnapScan Touch
+ 0403 ePhoto CL18 Camera
+ 0404 ePhoto CL20 Camera
+ 2061 SnapScan 1212U (?)
+ 208d Snapscan e40
+ 208f SnapScan e50
+ 2091 SnapScan e20
+ 2093 SnapScan e10
+ 2095 SnapScan e25
+ 2097 SnapScan e26
+ 20fd SnapScan e52
+ 20ff SnapScan e42
+06be AME Optimedia Technology Co., Ltd
+06bf Leoco Corp.
+06c2 Phidgets Inc. (formerly GLAB)
+ 0030 PhidgetRFID
+ 0038 4-Motor PhidgetServo v3.0
+ 0039 1-Motor PhidgetServo v3.0
+ 003a 8-Motor PhidgetAvancedServo
+ 0040 PhidgetInterface Kit 0-0-4
+ 0044 PhidgetInterface Kit 0-16-16
+ 0045 PhidgetInterface Kit 8-8-8
+ 0048 PhidgetStepper (Under Development)
+ 0049 PhidgetTextLED Ver 1.0
+ 004a PhidgetLED Ver 1.0
+ 004b PhidgetEncoder Ver 1.0
+ 0051 PhidgetInterface Kit 0-5-7 (Custom)
+ 0052 PhidgetTextLCD
+ 0053 PhidgetInterfaceKit 0-8-8
+ 0058 PhidgetMotorControl Ver 1.0
+ 0070 PhidgetTemperatureSensor Ver 1.0
+ 0071 PhidgetAccelerometer Ver 1.0
+ 0072 PhidgetWeightSensor Ver 1.0
+ 0073 PhidgetHumiditySensor
+ 0074 PhidgetPHSensor
+ 0075 PhidgetGyroscope
+06c4 Bizlink International Corp.
+06c5 Hagenuk, GmbH
+06c6 Infowave Software, Inc.
+06c8 SIIG, Inc.
+06c9 Taxan (Europe), Ltd
+06ca Newer Technology, Inc.
+06cb Synaptics, Inc.
+ 0009 Composite TouchPad and TrackPoint
+06cc Terayon Communication Systems
+06cd Keyspan
+ 0101 USA-28 PDA [preenum]
+ 0102 USA-28X PDA [preenum]
+ 0103 USA-19 PDA [preenum]
+ 0104 PDA [prerenum]
+ 0105 USA-18X PDA [preenum]
+ 0106 USA-19W PDA [preenum]
+ 0107 USA-19 PDA
+ 0108 USA-19W PDA
+ 010b USA-19Q PDA
+ 010f USA-28 PDA
+ 0110 USA-28X PDA
+ 0112 USA-18X PDA
+ 0114 USA-28X PDA
+ 0118 USA-19QW PDA
+ 0201 Digital Media Remote
+06cf SpheronVR AG
+ 1010 PanoCam 10
+ 1012 PanoCam 12/12X
+06d0 LapLink, Inc.
+ 0622 LapLink Gold USB-USB Bridge [net1080]
+06d1 Daewoo Electronics Co., Ltd
+06d3 Mitsubishi Electric Corp.
+06d4 Cisco Systems
+06d5 Toshiba
+ 4000 Japanese Keyboard
+06d6 Aashima Technology B.V.
+06d7 Network Computing Devices (NCD)
+06d8 Technical Marketing Research, Inc.
+06da Phoenixtec Power Co., Ltd
+06db Paradyne
+06dc Foxlink Image Technology Co., Ltd
+ 0014 Prolink Winscan Pro 2448U
+06de Heisei Electronics Co., Ltd
+06e0 Multi-Tech Systems, Inc.
+ f101 MT5634ZBA-USB MultiModemUSB (old firmware)
+ f103 MT5634MU MultiMobileUSB
+ f104 MT5634ZBA-USB MultiModemUSB (new firmware)
+ f107 MT5634ZBA-USB-V92 MultiModemUSB
+06e1 ADS Technologies, Inc.
+ 0008 UBS-10BT Ethernet [klsi]
+ a190 Instand VCD Usb Capture
+06e4 Alcatel Microelectronics
+06e6 Tiger Jet Network, Inc.
+06ea Sirius Technologies
+ 0001 NetCom Roadster II 56k
+ 0002 Roadster II 56k
+06eb PC Expert Tech. Co., Ltd
+06ef I.A.C. Geometrische Ingenieurs B.V.
+06f0 T.N.C Industrial Co., Ltd
+06f1 Opcode Systems, Inc.
+06f2 Emine Technology Co.
+06f6 Wintrend Technology Co., Ltd
+06f8 Guillemot Corp.
+ a300 Dual Analog Leader GamePad
+06fa HSD S.r.L
+06fc Motorola Semiconductor Products Sector
+06fd Boston Acoustics
+06fe Gallant Computer, Inc.
+0701 Supercomal Wire & Cable SDN. BHD.
+0703 Bvtech Industry, Inc.
+0705 NKK Corp.
+0706 Ariel Corp.
+0707 Standard Microsystems Corp.
+ 0100 2202 Ethernet [klsi]
+ 0200 2202 Ethernet [pegasus]
+ ee06 EZ-Connect 802.11g Adapter
+ ee13 EZ-Connect 802.11g Adapter
+0708 Putercom Co., Ltd
+0709 Silicon Systems, Ltd (SSL)
+070a Oki Electric Industry Co., Ltd
+070d Comoss Electronic Co., Ltd
+070e Excel Cell Electronic Co., Ltd
+0710 Connect Tech, Inc.
+ 0001 WhiteHeat (fake ID)
+ 8001 WhiteHeat
+0711 Magic Control Technology Corp.
+ 0100 Hub
+ 0200 BAY-3U1S1P Serial Port
+ 0210 MCT1S Serial Port
+ 0230 MCT-232 Serial Port
+ 0231 PS/2 Mouse Port
+ 0240 PS/2 to USB Converter
+ 0300 BAY-3U1S1P Parallel Port
+ 0302 Parallel Port
+ 0900 SVGA Adapter
+0713 Interval Research Corp.
+0714 NewMotion, Inc.
+ 0003 ADB to USB convertor
+0717 ZNK Corp.
+0718 Imation Corp.
+0719 Tremon Enterprises Co., Ltd
+071b Domain Technologies, Inc.
+ 0002 DTI-56362-USB Digital Interface Unit
+ 0101 Audio4-USB DSP Data Acquisition Unit
+ 0201 Audio4-5410 DSP Data Acquisition Unit
+ 0301 SB-USB JTAG Emulator
+071c Xionics Document Technologies, Inc.
+071d Eicon Networks Corp.
+ 1000 Diva ISDN TA
+071e Ariston Technologies
+0723 Centillium Communications Corp.
+0726 Vanguard International Semiconductor-America
+0729 Amitm
+ 1000 USC-1000 Serial Port
+072e Sunix Co., Ltd
+072f Advanced Card Systems, Ltd
+ 0001 AC1030-based SmartCard Reader
+ 9000 ACR38 AC1038-based Smart Card Reader
+ 90cc ACR38 SmartCard Reader
+0731 Susteen, Inc.
+ 0528 SonyEricsson DCU-11 Cable
+0732 Goldfull Electronics & Telecommunications Corp.
+0733 ViewQuest Technologies, Inc.
+ 0110 VQ110
+ 1311 Digital Dream Epsilon 1.3
+ 2211 Jenoptik
+ 0401 CS330 WebCam
+ 0402 M-318B WebCam
+ 0430 Intel Pro Share WebCam
+0734 Lasat Communications A/S
+ 0001 560V Modem
+0735 Asuscom Network
+ c541 ISDN TA 280
+0736 Lorom Industrial Co., Ltd
+0738 Mad Catz, Inc.
+073b Suncom Technologies
+073a Chaplet Systems, Inc.
+073d Eutron S.p.a.
+ 0005 Crypto Token
+073e NEC, Inc.
+ 0301 Game Pad
+0745 Syntech Information Co., Ltd
+0746 Onkyo Corp.
+0747 Labway Corp.
+0748 Strong Man Enterprise Co., Ltd
+0749 EVer Electronics Corp.
+074a Ming Fortune Industry Co., Ltd
+074b Polestar Tech. Corp.
+074c C-C-C Group PLC
+074d Micronas GmbH
+074e Digital Stream Corp.
+ 0001 PS/2 Adapter
+ 0002 PS/2 Adapter
+0755 Aureal Semiconductor
+0757 Network Technologies, Inc.
+075b Sophisticated Circuits, Inc.
+ 0001 Kick-off! Watchdog
+0763 Midiman
+ 1001 Midisport 2x2
+ 1010 Midisport 1x1
+ 1020 Midisport 4x4
+ 1030 Midisport 8x8
+0764 Cyber Power System, Inc.
+ 0005 Cyber Power UPS
+0765 X-Rite, Inc.
+0766 Jess-Link Products Co., Ltd
+0767 Tokheim Corp.
+0768 Camtel Technology Corp.
+ 0006 Camtel Technology USB TV Genie Pro FM Model TVB330
+0769 Surecom Technology Corp.
+076a Smart Technology Enablers, Inc.
+076b OmniKey AG
+ 0596 CardMan 2020
+ 1784 CardMan 6020
+ 3021 CardMan 3121
+076c Partner Tech
+076d Denso Corp.
+076e Kuan Tech Enterprise Co., Ltd
+076f Jhen Vei Electronic Co., Ltd
+0774 AmTRAN Technology Co., Ltd
+0775 Longshine Electronics Corp.
+0776 Inalways Corp.
+0777 Comda Enterprise Corp.
+0778 Volex, Inc.
+0779 Fairchild Semiconductor
+077a Sankyo Seiki Mfg. Co., Ltd
+077b Linksys
+ 2219 WUSB11 V2.6 802.11b Adapter
+ 2226 USB200M 100baseTX Adapter
+077c Forward Electronics Co., Ltd
+ 0005 NEC Keyboard
+077d Griffin Technology
+ 0410 PowerMate
+ 041a PowerWave
+ 0223 IMic Audio In/Out
+077f Well Excellent & Most Corp.
+0781 SanDisk Corp.
+ 0001 SDDR-05a ImageMate CompactFlash Reader
+ 0002 SDDR-31 ImageMate II CompactFlash Reader
+ 0005 SDDR-05b (CF II) ImageMate CompactFlash Reader
+ 0200 SDDR-09 (SSFDC) ImageMate SmartMedia Reader [eusb]
+ 0400 SecureMate SD/MMC Reader
+ 0621 SDDR-86 Imagemate 6-in-1 Reader
+ 0810 SDDR-75 ImageMate CF-SM Reader
+ 0830 ImageMate CF/MMC/SD Reader
+ 5150 SDCZ2 Cruzer Mini Flash Drive (thin)
+ 5151 Cruzer Micro 256/512MB Flash Drive
+ 7104 Cruzer Micro Mini 256MB Flash Drive
+ 7112 Cruzer Micro 128MB Flash Drive
+ 7113 Cruzer Micro 256MB Flash Drive
+ 8185 SDCZ2 Cruzer Mini Flash Drive (older, thick)
+ 8889 SDDR-88 Imagemate 8-in-1 Reader
+0782 Trackerball
+0783 C3PO
+ 0003 LTC31 SmartCard Reader
+0784 Vivitar, Inc.
+ 0100 Vivicam 2655
+ 1310 Vivicam 3305
+ 1688 Vivicam 3665
+ 2888 Polaroid DC700
+ 3330 Nytec ND-3200 Camera
+ 5260 Werlisa Sport PX 100 / JVC GC-A33 Camera
+ 5300 Pretec dc530
+0785 NTT-ME
+ 0001 MN128mini-V ISDN TA
+ 0003 MN128mini-J ISDN TA
+0789 Logitec Corp.
+078b Happ Controls, Inc.
+ 0010 Driving UGCI
+ 0020 Flying UGCI
+ 0030 Fighting UGCI
+078e Brincom, Inc.
+0790 Pro-Image Manufacturing Co., Ltd
+0791 Copartner Wire and Cable Mfg. Corp.
+0792 Axis Communications AB
+0793 Wha Yu Industrial Co., Ltd
+0794 ABL Electronics Corp.
+0795 RealChip, Inc.
+0796 Certicom Corp.
+0797 Grandtech Semiconductor Corp.
+ 8001 SmartCam
+ 801c Meade Binoculars/Camera
+079b Sagem
+079d Alfadata Computer Corp.
+ 0201 GamePort Adapter
+07a1 Digicom S.p.A.
+ d952 Palladio USB V.92 Modem
+07a2 National Technical Systems
+07a3 Onnto Corp.
+07a4 Be, Inc.
+07a6 ADMtek, Inc.
+ 0986 AN986 Pegasus Ethernet
+ 8511 ADM8511 Pegasus II Ethernet
+07aa Corega K.K.
+ 0001 Ether USB-T Ethernet [klsi]
+ 0004 FEther USB-TX Ethernet [pegasus]
+ 0012 Stick-11 802.11b Adapter
+ 7613 Stick-11 V2 802.11b Adapter
+07ab Freecom Technologies
+ fc01 IDE bridge
+ fc03 USB2-IDE IDE bridge
+07af Microtech
+ 0004 SCSI-DB25 SCSI Bridge [shuttle]
+ 0005 SCSI-HD50 SCSI Bridge [shuttle]
+ 0006 CameraMate SmartMedia and CompactFlash Card Reader [eusb/shuttle]
+07b0 Trust Technologies
+ 0001 ISDN TA
+07b1 IMP, Inc.
+07b2 Motorola BCS, Inc.
+ 4100 SurfBoard SB4100 Cable Modem
+ 4200 SurfBoard SB4200 Cable Modem
+ 5100 SurfBoard SB5100 Cable Modem
+ 5120 Surfboard SB5120 Cable Modem (RNDIS)
+07b3 Plustek, Inc.
+ 0001 OpticPro 1212U Scanner
+ 0010 OpticPro U12 Scanner
+ 0011 OpticPro U24 Scanner
+ 0013 OpticPro UT12 Scanner
+ 0015 OpticPro U24 Scanner
+ 0017 OpticPro UT12/16/24 Scanner
+ 0400 OpticPro 1248U Scanner
+ 0401 OpticPro 1248U Scanner #2
+ 0403 OpticPro U16B Scanner
+07b4 Olympus Optical Co., Ltd
+ 0100 Camedia C-2100/C-3000 Ultra Zoom Camera
+ 0102 Camedia E-10/C-220/C-50 Camera
+ 0105 Camedia C-310Z/C-700/C-750UZ/C-755/C-765UZ/C-3040/C-4000/C-5050Z/D-560 Zoom Camera
+ 0112 MAUSB-100 xD Card Reader
+ 0114 C-350Z Camera
+ 0203 Digital Voice Recorder DW-90
+ 0206 Digital Voice Recorder DS-330
+ 0207 Digital Voice Recorder & Camera W-10
+ 020d Digital Voice Recorder VN-240PC
+07b5 Mega World International, Ltd
+ 9902 GamePad
+07b6 Marubun Corp.
+07b7 TIME Interconnect, Ltd
+07b8 D-Link Corp.
+ 4000 DU-E10 Ethernet [klsi]
+ 4002 DU-E100 Ethernet [pegasus]
+ abc1 DU-E10 Ethernet [pegasus]
+ f101 DSB-560 Modem [atlas]
+07bc Canon Computer Systems, Inc.
+07bd Webgear, Inc.
+07be Veridicom
+07c0 Code Mercenaries Hard- und Software GmbH
+ 1121 The Claw
+ 1500 IO-Warrior 40
+ 1501 IO-Warrior 24
+ 1502 IO-Warrior 48
+ 1503 IO-Warrior 28
+07c4 Datafab Systems, Inc.
+ a000 CompactFlash Card Reader
+ a001 CompactFlash & SmartMedia Card Reader [eusb]
+ a002 Disk Drive
+ a005 CompactFlash & SmartMedia Card Reader
+ a006 SmartMedia Card Reader
+ a109 LC1 CompactFlash & SmartMedia Card Reader
+ a200 DF-UT-06 Hama MMC/SD Reader
+ a400 CompactFlash & Microdrive Reader
+ b004 MMC/SD Reader
+07c5 APG Cash Drawer
+07c6 ShareWave, Inc.
+07c7 Powertech Industrial Co., Ltd
+07c8 B.U.G., Inc.
+07c9 Allied Telesyn International
+07ca AVerMedia Technologies, Inc.
+07cb Kingmax Technology, Inc.
+07cc Carry Computer Eng., Co., Ltd
+ 0000 CF Card Reader
+ 0003 SM Card Reader
+ 0004 SM/CF/PCMCIA Card Reader
+ 0006 SM/CF/PCMCIA Card Reader
+ 000c SM/CF Card Reader
+ 000d SM/CF Card Reader
+ 0200 6-in-1 Card Reader
+ 0301 6-in-1 Card Reader
+07cd Elektor
+ 0001 USBuart Serial Port
+07cf Casio Computer Co., Ltd
+ 1001 QV-8000SX/5700/3000EX Digicam
+ 2002 E-125 Cassiopeia Pocket PC
+ 3801 WMP-1 MP3-Watch
+ 4001 Label Printer KL-P1000
+ 4500 LV-20 Digital Camera
+07d0 Dazzle
+ 0001 Digital Video Creator I
+ 0002 Global Village VideoFX Grabber
+ 0003 Fusion Model DVC-50 Rev 1 (NTSC)
+ 0004 DVC-800 (PAL) Grabber
+07d1 D-Link System
+07d2 Aptio Products, Inc.
+07d3 Cyberdata Corp.
+07d7 GCC Technologies, Inc.
+07da Arasan Chip Systems
+07df David Electronics Co., Ltd
+07e1 Ambient Technologies, Inc.
+ 5201 V.90 Modem
+07e2 Elmeg GmbH & Co., Ltd
+07e3 Planex Communications, Inc.
+07e4 Movado Enterprise Co., Ltd
+07e5 QPS, Inc.
+ 5c01 Que! CDRW
+07e6 Allied Cable Corp.
+07e7 Mirvo Toys, Inc.
+07e8 Labsystems
+07ea Iwatsu Electric Co., Ltd
+07eb Double-H Technology Co., Ltd
+07ec Taiyo Electric Wire & Cable Co., Ltd
+07ee Torex Retail (formerly Logware)
+ 0002 Cash Drawer I/F
+07f6 Circuit Assembly Corp.
+07f7 Century Corp.
+07f9 Dotop Technology, Inc.
+07fa Draytek
+ 0778 miniVigor 128 ISDN TA
+07fd Mark of the Unicorn
+ 0000 FastLane MIDI Interface
+0801 Mag-Tek
+0802 Mako Technologies, LLC
+0803 Zoom Telephonics, Inc.
+ 9700 2986L FaxModem
+0809 Genicom Technology, Inc.
+080a Evermuch Technology Co., Ltd
+080c Datalogic S.p.A.
+ 0300 Gryphon D120 Barcode Scanner
+ 0400 Gryphon D120 Barcode Scanner
+ 0500 Gryphon D120 Barcode Scanner
+ 0600 Gryphon M100 Barcode Scanner
+080d Teco Image Systems Co., Ltd
+ 0102 Hercules Scan@home 48
+0810 Personal Communication Systems, Inc.
+0813 Mattel, Inc.
+ 0001 Intel Play QX3 Microscope
+081a MG Logic
+ 1000 Duo Pen Tablet
+081b Indigita Corp.
+081c Mipsys
+081e AlphaSmart, Inc.
+0822 Reudo Corp.
+0825 GC Protronics
+0826 Data Transit
+0827 BroadLogic, Inc.
+0828 Sato Corp.
+0829 DirecTV Broadband, Inc. (Telocity)
+082d Handspring
+ 0100 Visor
+ 0300 Treo 600
+0830 Palm, Inc.
+ 0002 Palm M505
+ 0003 Palm M515
+ 0020 Palm I705
+ 0040 Palm M125
+ 0050 Palm M130
+ 0060 Palm Tungsten T / Zire 71
+ 0080 Palm
+0832 Kouwell Electronics Corp.
+0833 Sourcenext Corp.
+0835 Action Star Enterprise Co., Ltd
+0839 Samsung Techwin Co., Ltd
+ 0005 Digimax Camera
+ 0008 Digimax 230 Camera
+ 1003 Digimax 210SE
+ 1012 6500 Document Camera
+ 1542 Digimax 50 Duo
+083a Accton Technology Corp.
+ 1046 10/100 Ethernet [pegasus]
+ 5046 SpeedStream 10/100 Ethernet [pegasus]
+083f Global Village
+ b100 TelePort V.90 Fax/Modem
+0840 Argosy Research, Inc.
+0841 Rioport.com, Inc.
+ 0001 Rio 500
+0844 Welland Industrial Co., Ltd
+0846 NetGear, Inc.
+ 1001 EA101 Ethernet [klsi]
+ 4110 MA111 WiFi (v1)
+ 4200 WG121 WiFi (v1)
+ 4210 WG121 WiFi (v2)
+ 4220 WG111 WiFi (v1)
+ 4230 MA111 WiFi
+ 4240 WG111 WiFi (v2)
+ 6a00 WG111 WiFi (v2)
+084d Minton Optic Industry Co., Inc.
+ 0003 S-Cam F5 Digital Camera
+ 0011 Argus DC3500 Digital Camera
+084e KB Gear
+ 1002 Pablo Tablet
+084f Empeg
+ 0001 Empeg-Car Mark I/II Player
+0850 Fast Point Technologies, Inc.
+0851 Macronix International Co., Ltd
+ 1543 Maxell WS30 Slim Digital Camera
+0852 CSEM
+0854 ActiveWire, Inc.
+ 0100 I/O Board
+ 0101 I/O Board, rev1
+0856 B&B Electronics
+ AC01 uLinks USOTL4 RS422/485 Adapter
+0858 Hitachi Maxell, Ltd
+0859 Minolta Systems Laboratory, Inc.
+085a Xircom
+ 0001 Portstation Dual Serial Port
+ 0003 Portstation Paraller Port
+ 000b Portstation Dual PS/2 Port
+ 0299 Colorvision, Inc. Monitor Spyder
+ 8027 PGSDB9 Serial Port
+085c ColorVision, Inc.
+ 0200 Monitor Spyder
+0862 Teletrol Systems, Inc.
+0863 Filanet Corp.
+0864 NetGear, Inc.
+ 4100 MA101 802.11b Adapter
+ 4102 MA101 802.11b Adapter
+0867 Data Translation, Inc.
+ 9812 ECON Data acquisition unit
+086a Emagic Soft-und Hardware GmbH
+086c DeTeWe - Deutsche Telephonwerke AG & Co.
+ 1001 Eumex 504PC ISDN TA
+ 1003 TA33 ISDN TA
+ 1055 Eumex 220 ISDN TA
+086e System TALKS, Inc.
+086f MEC IMEX, Inc.
+0870 Metricom
+0871 SanDisk, Inc.
+ 0001 SDDR-01 Compact Flash Reader
+ 0002 SDDR-31 Compact Flash Reader
+ 0005 SDDR-05 Compact Flash Reader
+0873 Xpeed, Inc.
+0874 A-Tec Subsystem, Inc.
+0879 Comtrol Corp.
+087c Adesso/Kbtek America, Inc.
+087d Jaton Corp.
+087e Fujitsu Computer Products of America
+087f Virtual IP Group, Inc.
+0880 APT Technologies, Inc.
+0883 Recording Industry Association of America (RIAA)
+0885 Boca Research, Inc.
+0886 XAC Automation Corp.
+0887 Hannstar Electronics Corp.
+088b MassWorks, Inc.
+ 4944 MassWorks ID-75 TouchScreen
+0892 DioGraphy, Inc.
+089c United Technologies Research Cntr.
+089d Icron Technologies Corp.
+089e NST Co., Ltd
+089f Primex Aerospace Co.
+08a5 e9, Inc.
+08a8 Andrea Electronics
+08ae Macally (Mace Group, Inc.)
+08b4 Sorenson Vision, Inc.
+08b8 J. Gordon Electronic Design, Inc.
+ 01f4 USBSIMM1
+08b9 RadioShack Corp. (Tandy)
+08bb Texas Instruments Japan
+08bd Citizen Watch Co., Ltd
+08c3 Precise Biometrics
+ 0101 Precise 100 MC FingerPrint and SmartCard Reader
+08c4 Proxim, Inc.
+08c7 Key Nice Enterprise Co., Ltd
+08c8 2Wire, Inc.
+08c9 Nippon Telegraph and Telephone Corp.
+08ca Aiptek International, Inc.
+ 0010 Tablet
+ 0020 APT-6000U Tablet
+ 0021 APT-2 Tablet
+ 0022 Tablet
+ 0023 Tablet
+ 0024 Tablet
+ 0102 DualCam
+ 0103 Pocket DV Digital Camera
+ 0104 Pocket DVII
+ 0106 Pocket DV3100+
+ 0111 PenCam VGA Plus
+ 2008 Mini PenCam 2
+ 2010 Pocket CAM 3 Mega (webcam)
+ 2011 Pocket CAM 3 Mega (storage)
+ 2018 Pencam SD 2
+ 2024 Pocket DV3500
+08cd Jue Hsun Ind. Corp.
+08ce Long Well Electronics Corp.
+08cf Productivity Enhancement Products
+08d1 smartBridges, Inc.
+ 0001 smartNIC Ethernet [catc]
+08d3 Virtual Ink
+08d4 Fujitsu Siemens Computers
+ 0009 SCR SmartCard Reader
+08d9 Increment P Corp.
+08dd Billionton Systems, Inc.
+ 0986 USB-100N Ethernet [pegasus]
+ 0987 USBLP-100 HomePNA Ethernet [pegasus]
+ 0988 USBEL-100 Ethernet [pegasus]
+ 8511 USBE-100 Ethernet [pegasus2]
+08de ???
+ 7a01 802.11b Adapter
+08df Spyrus, Inc.
+08e3 Olitec, Inc.
+ 0002 USB-RS232 Bridge
+08e4 Pioneer Corp.
+08e5 Litronic
+08e6 Gemplus
+ 0430 GemPC430 SmartCard Reader
+ 0432 GemPC432 SmartCard Reader
+ 0435 GemPC435 SmartCard Reader
+ 0437 GemPC433 SL SmartCard Reader
+ 3437 GemPC Twin SmartCard Reader
+ 3438 GemPC Key SmartCard Reader
+08e7 Pan-International Wire & Cable
+08e8 Integrated Memory Logic
+08e9 Extended Systems, Inc.
+ 0100 XTNDAccess IrDA Dongle
+08ea Ericsson, Inc., Blue Ridge Labs
+08ec M-Systems Flash Disk Pioneers
+ 0010 DiskOnKey
+08ee CCSI/Hesso
+08f0 Corex Technologies
+08f1 CTI Electronics Corp.
+08f5 SysTec Co., Ltd
+08f6 Logic 3 International, Ltd
+08f7 Vernier
+ 0001 LabPro
+ 0002 EasyTemp
+08f8 Keen Top International Enterprise Co., Ltd
+08f9 Wipro Technologies
+08fa Caere
+08fb Socket Communications
+08fc Sicon Cable Technology Co., Ltd
+08fd Digianswer A/S
+08ff AuthenTec, Inc.
+0900 Pinnacle Systems, Inc.
+0901 VST Technologies
+0906 Faraday Technology Corp.
+0909 Audio-Technica Corp.
+090a Trumpion Microelectronics, Inc.
+ 1540 Digitex Container Flash Disk
+090b Neurosmith
+090c Feiya Technology Corp.
+ 1000 Memory Bar
+090d Multiport Computer Vertriebs GmbH
+090e Shining Technology, Inc.
+090f Fujitsu Devices, Inc.
+0910 Alation Systems, Inc.
+0911 Philips Speech Processing
+0912 Voquette, Inc.
+0915 GlobeSpan, Inc.
+0917 SmartDisk Corp.
+0919 Tiger Electronics
+ 0100 Fast Flicks Digital Camera
+091e Garmin International
+ 0003 GPSmap (various models)
+0920 Echelon Co.
+0921 GoHubs, Inc.
+0922 Dymo-CoStar Corp.
+ 0007 LabelWriter 330
+ 0009 LabelWriter 310
+0923 IC Media Corp.
+ 010f SIIG MobileCam
+0924 Xerox
+0925 Lakeview Research
+ 8101 Phidgets, Inc., 1-Motor PhidgetServo v2.0
+ 8104 Phidgets, Inc., 4-Motor PhidgetServo v2.0
+ 8800 WiseGroup Ltd, MP-8800 Quad Joypad
+ 8866 WiseGroup Ltd, MP-8866 Dual Joypad
+0927 Summus, Ltd
+0928 Oxford Semiconductor, Ltd
+0929 American Biometric Co.
+092a Toshiba Information & Industrial Sys. And Services
+092b Sena Technologies, Inc.
+0930 Toshiba Corp.
+ 6519 Kingston DataTraveler 2.0 USB Stick
+ 6533 512M USB Stick
+0931 Harmonic Data Systems, Ltd
+0932 Crescentec Corp.
+0933 Quantum Corp.
+0934 Netcom Systems
+0939 Lumberg, Inc.
+093a Pixart Imaging, Inc.
+ 2468 Easy Snap Snake Eye WebCam
+093b Plextor Corp.
+ 0042 PX-712UF DVD RW
+093c Intrepid Control Systems, Inc.
+ 0601 ValueCAN
+093d InnoSync, Inc.
+093e J.S.T. Mfg. Co., Ltd
+093f Olympia Telecom Vertriebs GmbH
+0940 Japan Storage Battery Co., Ltd
+0941 Photobit Corp.
+0942 i2Go.com, LLC
+0943 HCL Technologies India Private, Ltd
+0944 KORG, Inc.
+0945 Pasco Scientific
+0948 Kronauer music in digital
+ 0301 USB Pro (24/48)
+ 0302 USB Pro (24/96 playback)
+ 0303 USB Pro (24/96 record)
+ 0304 USB Pro (16/48)
+ 1105 USB One
+094b Linkup Systems Corp.
+094d Cable Television Laboratories
+0951 Kingston Technology
+ 000a KNU101TX 100baseTX Ethernet
+ 1600 Data Traveler II Pen Drive
+0954 RPM Systems Corp.
+0955 NVidia Corp.
+0956 BSquare Corp.
+0957 Agilent Technologies, Inc.
+0958 CompuLink Research, Inc.
+0959 Cologne Chip AG
+095a Portsmith
+095b Medialogic Corp.
+095c K-Tec Electronics
+095d Polycom, Inc.
+0967 Acer (??)
+ 0204 WarpLink 802.11b Adapter
+0968 Catalyst Enterprises, Inc.
+0971 Gretag-Macbeth AG
+0973 Schlumberger
+0974 Datagraphix, a business unit of Anacomp
+0975 OL'E Communications, Inc.
+0976 Adirondack Wire & Cable
+0977 Lightsurf Technologies
+0978 Beckhoff GmbH
+0979 Jeilin Technology Corp., Ltd
+097a Minds At Work LLC
+097b Knudsen Engineering, Ltd
+097c Marunix Co., Ltd
+097d Rosun Technologies, Inc.
+097f Barun Electronics Co., Ltd
+0981 Oak Technology, Ltd
+0984 Apricorn
+0985 cab Produkttechnik GmbH & Co KG
+ 00a3 A3/200 or A3/300 Label Printer
+098c Vitana Corp.
+098d INDesign
+098e Integrated Intellectual Property, Inc.
+098f Kenwood TMI Corp.
+0993 Gemstar eBook Group, Ltd
+ 0001 REB1100 eBook Reader
+0996 Integrated Telecom Express, Inc.
+099a Zippy Technology Corp.
+ 610c EL-610 Super Mini Electron luminescent Keyboard
+09a3 PairGain Technologies
+09a4 Contech Research, Inc.
+09a5 VCON Telecommunications
+09a6 Poinchips
+09a7 Data Transmission Network Corp.
+09a8 Lin Shiung Enterprise Co., Ltd
+09a9 Smart Card Technologies Co., Ltd
+09aa Intersil Corp.
+ 1000 Prism GT 802.11b/g Adapter
+ 3642 Prism 2.x 802.11b Adapter
+09ae Tripp Lite
+09b2 Franklin Electronic Publishers, Inc.
+ 0001 eBookman Palm Computer
+09b3 Altius Solutions, Inc.
+09b4 MDS Telephone Systems
+09b5 Celltrix Technology Co., Ltd
+09bc Grundig
+ 0002 MPaxx MP150 MP3 Player
+09be MySmart.Com
+ 0001 MySmartPad
+09bf Auerswald GmbH & Co. KG
+ 00c0 COMpact 2104 ISDN PBX
+ 00db COMpact 4410/2206 ISDN ISDN
+ 00f1 COMfort System Telephones
+09c1 Arris Interactive LLC
+09c2 Nisca Corp.
+09c3 ActivCard, Inc.
+ 0008 SmartCard Reader
+09c4 ACTiSYS Corp.
+ 0011 ACT-IR2000U IrDA Dongle
+09c5 Memory Corp.
+09cc Workbit Corp.
+09cd Psion Dacom Home Networks, Ltd
+09ce City Electronics, Ltd
+09cf Electronics Testing Center, Taiwan
+09d1 NeoMagic, Inc.
+09d2 Vreelin Engineering, Inc.
+09d3 Com One
+ 0001 ISDN TA
+09d9 KRF Tech, Ltd
+09da A4 Tech Co., Ltd
+ 0006 Optical Mouse WOP-35 / Trust 450L Optical Mouse
+ 001a Wireless Mouse & RXM-15 Receiver
+ 002a Wireless Optical Mouse NB-30
+09db Measurement Computing Corp.
+ 0075 MiniLab 1008
+ 0076 PMD-1024
+ 007A PMD-1208LS
+09dc Aimex Corp.
+09dd Fellowes, Inc.
+09df Addonics Technologies Corp.
+09e1 Intellon Corp.
+09e5 Jo-Dan International, Inc.
+09e6 Silutia, Inc.
+09e7 Real 3D, Inc.
+09e8 AKAI Professional M.I. Corp.
+09e9 Chen-Source, Inc.
+09eb IM Networks, Inc.
+ 4331 iRhythm Tuner Remote
+09ef Xitel
+ 0101 MD-Port DG2 MiniDisc Interface
+09f5 AresCom
+09f6 RocketChips, Inc.
+09f7 Edu-Science (H.K.), Ltd
+09f8 SoftConnex Technologies, Inc.
+09f9 Bay Associates
+09fa Mtek Vision
+09fb Altera
+09ff Gain Technology Corp.
+0a00 Liquid Audio
+0a01 ViA, Inc.
+0a07 Ontrak Control Systems Inc.
+ 0064 ADU100 Data Acquisition Interface
+ 00c8 ADU200 Relay I/O Interface
+ 00d0 ADU208 Data Acquisition Interface
+0a0b Cybex Computer Products Co.
+0a11 Xentec, Inc.
+0a12 Cambridge Silicon Radio, Ltd
+ 0001 Bluetooth Dongle (HCI mode)
+ 1000 Bluetooth Dongle (HID proxy mode)
+0a13 Telebyte, Inc.
+0a14 Spacelabs Medical, Inc.
+0a15 Scalar Corp.
+0a16 Trek Technology (S) PTE, Ltd
+ 9988 Trek2000 TD-G2
+0a17 Pentax Corp.
+ 0004 Pentax Optio 330
+ 0006 Pentax Optio S
+ 0007 Pentax Optio 550
+ 003d Pentax Optio S55
+0a18 Heidelberger Druckmaschinen AG
+0a19 Hua Geng Technologies, Inc.
+0a21 Medtronic Physio Control Corp.
+0a22 Century Semiconductor USA, Inc.
+0a2c AK-Modul-Bus Computer GmbH
+ 0008 GPIO Ports
+0a39 Gilat Satellite Networks, Ltd
+0a3a PentaMedia Co., Ltd
+0a3c NTT DoCoMo, Inc.
+0a3d Varo Vision
+0a3f Swissonic AG
+0a43 Boca Systems, Inc.
+0a46 Davicom Semiconductor, Inc.
+0a47 Hirose Electric
+0a48 I/O Interconnect
+ 3258 Dane Elec zMate SD Reader
+ 3259 Dane Elec zMate CF Reader
+0a4b Fujitsu Media Devices, Ltd
+0a4c Computex Co., Ltd
+0a4d Evolution Electronics, Ltd
+ 008e MK-249C MIDI Keyboard
+ 00a3 MK-461C MIDI Keyboard
+ 00f5 UC-33e MIDI Controller
+0a4e Steinberg Soft-und Hardware GmbH
+0a4f Litton Systems, Inc.
+0a50 Mimaki Engineering Co., Ltd
+0a51 Sony Electronics, Inc.
+0a52 Jebsee Electronics Co., Ltd
+0a53 Portable Peripheral Co., Ltd
+0a5a Electronics For Imaging, Inc.
+0a5b EAsics NV
+0a5c Broadcom Corp.
+ 2033 BCM2033 Bluetooth
+ 2035 BCM2035 Bluetooth
+0a5d Diatrend Corp.
+0a5f Zebra
+ 0009 LP2844 Printer
+0a62 MPMan
+ 0010 MPMan MP-F40 MP3 Player
+0a66 ClearCube Technology
+0a67 Medeli Electronics Co., Ltd
+0a68 Comaide Corp.
+0a69 Chroma ate, Inc.
+0a6b Green House Co., Ltd
+ 0001 Compact Flash R/W with MP3 player
+0a6c Integrated Circuit Systems, Inc.
+0a6d UPS Manufacturing
+0a6e Benwin
+0a6f Core Technology, Inc.
+ 0400 Xanboo
+0a70 International Game Technology
+0a72 Sanwa Denshi
+0a7d NSTL, Inc.
+0a7e Octagon Systems Corp.
+0a80 Rexon Technology Corp., Ltd
+0a81 Chesen Electronics Corp.
+ 0101 Keyboard
+ 0103 Keyboard
+ 0203 Mouse
+ 0205 PS/2 Keyboard+Mouse Adapter
+0a82 Syscan
+ 4600 TravelScan 460/464
+0a83 NextComm, Inc.
+0a84 Maui Innovative Peripherals
+0a85 Idexx Labs
+0a86 NITGen Co., Ltd
+0a8d Picturetel
+0a8e Japan Aviation Electronics Industry, Ltd
+0a90 Candy Technology Co., Ltd
+0a91 Globlink Technology, Inc.
+0a92 EGO SYStems, Inc.
+0a93 C Technologies AB
+0a94 Intersense
+0aa3 Lava Computer Mfg., Inc.
+0aa4 Develco Elektronik
+0aa5 First International Digital
+0aa6 Perception Digital, Ltd
+ 0101 Hercules Jukebox
+0aa7 Wincor Nixdorf GmbH & Co KG
+ 0200 POS Display BA63
+ 0201 POS Display BA66
+ 0300 POS Printer TH210
+ 0302 POS Printer TH220
+ 0305 Lottery Printer XiPrintPlus
+ 0306 POS Printer TH320
+ 0308 POS Printer TH420
+ 4304 Banking Printer TP07
+0aa8 TriGem Computer, Inc.
+0aa9 Baromtec Co.
+ f01b Medion MD 6242 MP3 Player
+0aaa Japan CBM Corp.
+0aab Vision Shape Europe SA
+0aac iCompression, Inc.
+0aad Rohde & Schwarz GmbH & Co. KG
+0aae NEC infrontia Corp. (Nitsuko)
+0aaf Digitalway Co., Ltd
+0ab0 Arrow Strong Electronics Co., Ltd
+0aba Ellisys
+ 8001 USB Tracker 110 Protocol Analyzer
+0abe Stereo-Link
+ 0101 SL1200 DAC
+0ac3 Sanyo Semiconductor Company Micro
+0ac4 Leco Corp.
+0ac5 I & C Corp.
+0ac6 Singing Electrons, Inc.
+0ac7 Panwest Corp.
+0ac8 Z-Star Microelectronics Corp.
+ 0302 ZC0302 WebCam
+ 301b ZC0301 WebCam
+ 303b ZC0303 WebCam
+0ac9 Micro Solutions, Inc.
+ 0000 Backpack CD-ReWriter
+ 0011 Backpack 40GB Hard Drive
+0acc Koga Electronics Co.
+0acd ID Tech
+0ace ZyDAS
+ 1201 802.11b WiFi
+ 1211 802.11b/g USB2 WiFi
+0acf Intoto, Inc.
+0ad0 Intellix Corp.
+0ad1 Remotec Technology, Ltd
+0ad2 Service & Quality Technology Co., Ltd
+0ae3 Allion Computer, Inc.
+0ae4 Taito Corp.
+0ae7 Neodym Systems, Inc.
+0ae8 System Support Co., Ltd
+0ae9 North Shore Circuit Design L.L.P.
+0aea SciEssence, LLC
+0aeb TTP Communications, Ltd
+0aec Neodio Technologies Corp.
+ 3050 ND3050 8-in-1 Card Reader
+ 3260 7-in-1 Card Reader
+ 5010 ND5010 Card Reader
+0af0 Option
+ 5000 UMTS Card
+0af6 Silver I Co., Ltd
+0af7 B2C2, Inc.
+ 0101 Digital TV USB Receiver (DVB-S/T/C / ATSC)
+0af9 Hama, Inc.
+ 0010 USB SightCam 100
+ 0011 Micro Innovations IC50C WebCam
+0afc Zaptronix Ltd
+0afd Tateno Dennou, Inc.
+0afe Cummins Engine Co.
+0aff Jump Zone Network Products, Inc.
+0b05 ASUSTek Computer, Inc.
+0b0c Todos Data System AB
+ 0009 Todos Argos Mini II Smart Card Reader
+0b0e GN Netcom
+0b0f AVID Technology
+0b10 Pcally
+0b11 I Tech Solutions Co., Ltd
+0b1e Electronic Warfare Assoc., Inc. (EWA)
+0b1f Insyde Software Corp.
+0b20 TransDimension, Inc.
+0b21 Yokogawa Electric Corp.
+0b22 Japan System Development Co., Ltd
+0b23 Pan-Asia Electronics Co., Ltd
+0b24 Link Evolution Corp.
+0b27 Ritek Corp.
+0b28 Kenwood Corp.
+0b2c Village Center, Inc.
+0b30 PNY Technologies, Inc.
+ 0006 SM Media-Shuttle Card Reader
+0b33 Contour Design, Inc.
+0b37 Hitachi ULSI Systems Co., Ltd
+0b39 Omnidirectional Control Technology, Inc.
+0b3a IPaxess
+0b3b Tekram Technology Co., Ltd
+ 1601 Allnet 0193 802.11b Adapter
+ 1602 ZyXEL ZyAIR B200 802.11b Adapter
+ 1612 AIR.Mate 2@net 802.11b Adapter
+0b3c Olivetti Techcenter
+0b3e Kikusui Electronics Corp.
+0b41 Hal Corp.
+0b43 Play.com, Inc.
+ 0003 PS2 Controller Converter
+0b47 Sportbug.com, Inc.
+0b48 TechnoTrend AG
+ 1003 Technotrend/Hauppauge USB-Nova
+ 1005 Technotrend/Hauppauge USB-Nova
+ 1006 Technotrend/Hauppauge DEC3000-s
+ 1008 Technotrend/Hauppauge DEC2000-t
+ 1009 Technotrend/Hauppauge DEC2540-t
+0b49 ASCII Corp.
+ 064f Trance Vibrator
+0b4b Pine Corp. Ltd.
+ 0100 D'music MP3 Player
+0b4e Musical Electronics, Ltd
+0b50 Dumpries Co., Ltd
+0b51 Comfort Keyboard Co.
+ 0020 Comfort Keyboard
+0b52 Colorado MicroDisplay, Inc.
+0b54 Sinbon Electronics Co., Ltd
+0b56 TYI Systems, Ltd
+0b57 Beijing HanwangTechnology Co., Ltd
+0b59 Lake Communications, Ltd
+0b5a Corel Corp.
+0b5f Green Electronics Co., Ltd
+0b60 Nsine, Ltd
+0b61 NEC Viewtechnology, Ltd
+0b62 Orange Micro, Inc.
+ 0059 iBOT2 WebCam
+0b63 ADLink Technology, Inc.
+0b64 Wonderful Wire Cable Co., Ltd
+0b65 Expert Magnetics Corp.
+0b69 CacheVision
+0b6a Maxim Integrated Products
+0b6f Nagano Japan Radio Co., Ltd
+0b70 PortalPlayer, Inc.
+0b71 SHIN-EI Sangyo Co., Ltd
+0b72 Embedded Wireless Technology Co., Ltd
+0b73 Computone Corp.
+0b75 Roland DG Corp.
+0b79 Sunrise Telecom, Inc.
+0b7a Zeevo, Inc.
+0b7b Taiko Denki Co., Ltd
+0b7c ITRAN Communications, Ltd
+0b7d Astrodesign, Inc.
+0b84 Rextron Technology, Inc.
+0b85 Elkat Electronics, Sdn., Bhd.
+0b86 Exputer Systems, Inc.
+0b87 Plus-One I & T, Inc.
+0b88 Sigma Koki Co., Ltd, Technology Center
+0b89 Advanced Digital Broadcast, Ltd
+0b95 ASIX Electronics Corp.
+0b96 Sewon Telecom
+0b97 O2 Micro, Inc.
+ 7762 Oz776 SmartCard Reader
+0b98 Playmates Toys, Inc.
+0b99 Audio International, Inc.
+0b9b Dipl.-Ing. Stefan Kunde
+ 4012 Reflex RC-controller Interface
+0b9d Softprotec Co.
+0b9f Chippo Technologies
+0baf U.S. Robotics
+ 00eb USR1120 802.11b Adapter
+ 0118 U5 802.11g Adapter
+ 6112 FaxModem Model 5633
+0bb0 Concord Camera Corp.
+0bb1 Infinilink Corp.
+0bb2 Ambit Microsystems Corp.
+ 6098 USB Cable Modem
+0bb3 Ofuji Technology
+0bb4 High Tech Computer Corp.
+ 00ce mmO2 XDA GSM/GPRS Pocket PC
+ 00cf SPV C500 Smart Phone
+ 0a02 Himalaya GSM/GPRS Pocket PC
+ 0a51 SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC
+0bb5 Murata Manufacturing Co., Ltd
+0bb6 Network Alchemy
+0bb7 Joytech Computer Co., Ltd
+0bb8 Hitachi Semiconductor and Devices Sales Co., Ltd
+0bb9 Eiger M&C Co., Ltd
+0bba ZAccess Systems
+0bbb General Meters Corp.
+0bbc Assistive Technology, Inc.
+0bbd System Connection, Inc.
+0bc0 Knilink Technology, Inc.
+0bc1 Fuw Yng Electronics Co., Ltd
+0bc2 Seagate RSS LLC
+0bc3 IPWireless, Inc.
+0bc4 Microcube Corp.
+0bc5 JCN Co., Ltd
+0bc6 ExWAY, Inc.
+0bc7 X10 Wireless Technology, Inc.
+ 0004 X10 Receiver
+0bc8 Telmax Communications
+0bc9 ECI Telecom, Ltd
+0bca Startek Engineering, Inc.
+0bcb Perfect Technic Enterprise Co., Ltd
+0bda Realtek Semiconductor Corp.
+ 8150 RTL8150 Fast Ethernet Adapter
+ 8151 RTL8151 Adapteon Business Mobile Networks BV
+0bdb Ericsson Business Mobile Networks BV
+0bdc Y Media Corp.
+0bdd Orange PCS
+0be2 Kanda Tsushin Kogyo Co., Ltd
+0be3 TOYO Corp.
+0be4 Elka International, Ltd
+0be5 DOME imaging systems, Inc.
+0be6 Dong Guan Humen Wonderful Wire Cable Factory
+0bee LTK Industries, Ltd
+0bef Way2Call Communications
+0bf0 Pace Micro Technology PLC
+0bf1 Intracom S.A.
+0bf2 Konexx
+0bf6 Addonics Technologies, Inc.
+ a002 IDE Bridge
+0bf7 Sunny Giken, Inc.
+0bf8 Fujitsu Siemens Computers
+ 1001 Fujitsu Pocket Loox 600 PDA
+0c04 MOTO Development Group, Inc.
+0c05 Appian Graphics
+0c06 Hasbro Games, Inc.
+0c07 Infinite Data Storage, Ltd
+0c08 Agate
+ 0378 Q 16MB Storage Device
+0c09 Comjet Information System
+0c0a Highpoint Technologies, Inc.
+0c0b Dura Micro, Inc. (Acomdata)
+ 27cb 6-in-1 Flash Reader and Writer
+ a109 CF/SM Reader and Writer
+ a10c SD/MS Reader and Writer
+ b004 MMC/SD Reader and Writer
+0c12 Zeroplus
+ 0005 PSX Vibration Feedback Converter
+ 8809 Red Octane Ignition Xbox DDR Pad
+0c15 Iris Graphics
+0c16 Gyration, Inc.
+0c17 Cyberboard A/S
+0c18 SynerTek Korea, Inc.
+0c19 cyberPIXIE, Inc.
+0c1a Silicon Motion, Inc.
+0c1b MIPS Technologies
+0c1c Hang Zhou Silan Electronics Co., Ltd
+0c22 Tally Printer Corp.
+0c23 Lernout + Hauspie
+0c24 Taiyo Yuden
+0c25 Sampo Corp.
+0c2e Metro
+ 0200 Metrologic Scanner
+0c35 Eagletron, Inc.
+0c36 E Ink Corp.
+0c37 e.Digital
+0c38 Der An Electric Wire & Cable Co., Ltd
+0c39 IFR
+0c3a Furui Precise Component (Kunshan) Co., Ltd
+0c3b Komatsu, Ltd
+0c3c Radius Co., Ltd
+0c3d Innocom, Inc.
+0c3e Nextcell, Inc.
+0c44 Motorola iDEN
+0c45 Microdia
+ 1060 iFlash SM-Direct Card Reader
+ 6001 Genius VideoCAM NB
+ 6005 Sweex Mini WebCam
+ 6029 Triplex i-mini PC Camera
+ 602a Meade ETX-105EC Camera
+ 602c Clas Ohlson TWC-30XOP WebCam
+0c46 WaveRider Communications, Inc.
+0c4b Reiner SCT Kartensysteme GmbH
+ 0100 cyberJack e-com/pinpad
+ 0300 cyberJack pinpad(a)
+0c52 Sealevel Systems, Inc.
+0c53 ViewPLUS, Inc.
+0c54 Glory, Ltd
+0c55 Spectrum Digital, Inc.
+ 0510 Spectrum Digital XDS510 JTAG Debugger
+0c56 Billion Bright, Ltd
+0c57 Imaginative Design Operation Co., Ltd
+0c58 Vidar Systems Corp.
+0c59 Dong Guan Shinko Wire Co., Ltd
+0c5a TRS International Mfg., Inc.
+0c5e Xytronix Research & Design
+0c62 Chant Sincere Co., Ltd
+0c63 Toko, Inc.
+0c64 Signality System Engineering Co., Ltd
+0c65 Eminence Enterprise Co., Ltd
+0c66 Rexon Electronics Corp.
+0c67 Concept Telecom, Ltd
+0c70 MCT Elektronikladen
+ 0000 USB08 Development board
+0c74 Optronic Laboratories Inc.
+ 0002 OL 700-30 Goniometer
+0c76 JMTek, LLC.
+ 0003 USBdisk
+ 0005 USBdisk
+ 0006 Transcend JetFlash
+0c77 Sipix Group, Ltd
+0c78 Detto Corp.
+0c79 NuConnex Technologies Pte., Ltd
+0c7a Wing-Span Enterprise Co., Ltd
+0c86 NDA Technologies, Inc.
+0c88 Kyocera Wireless Corp.
+0c89 Honda Tsushin Kogyo Co., Ltd
+0c8a Pathway Connectivity, Inc.
+0c8b Wavefly Corp.
+0c8c Coactive Networks
+0c8d Tempo
+0c8e Cesscom Co., Ltd
+0c8f Applied Microsystems
+0c99 Innochips Co., Ltd
+0c9a Hanwool Robotics Corp.
+0c9b Jobin Yvon, Inc.
+0ca2 Zyfer
+0ca3 Sega Corp.
+0ca4 ST&T Instrument Corp.
+0ca5 BAE Systems Canada, Inc.
+0ca6 Castles Technology Co., Ltd
+0ca7 Information Systems Laboratories
+0cad Motorola CGISS
+0cae Ascom Business Systems, Ltd
+0caf Buslink
+ 2515 Flash Disk Embedded Hub
+ 2516 Flash Disk Security Device
+ 2517 Flash Disk Mass Storage Device
+ 3a00 Hard Drive
+0cb0 Flying Pig Systems
+0cb1 Innovonics, Inc.
+0cb6 Celestix Networks, Pte., Ltd
+0cb7 Singatron Enterprise Co., Ltd
+0cb8 Opticis Co., Ltd
+0cba Trust Electronic (Shanghai) Co., Ltd
+0cbb Shanghai Darong Electronics Co., Ltd
+0cbc Palmax Technology Co., Ltd
+0cbd Pentel Co., Ltd (Electronics Equipment Div.)
+0cbe Keryx Technologies, Inc.
+0cbf Union Genius Computer Co., Ltd
+0cc0 Kuon Yi Industrial Corp.
+0cc1 Given Imaging, Ltd
+0cc2 Timex Corp.
+0cc3 Rimage Corp.
+0cc4 emsys GmbH
+0cc5 Sendo
+0cc6 Intermagic Corp.
+0cc7 Kontron Medical AG
+0cc8 Technotools Corp.
+0cc9 BroadMAX Technologies, Inc.
+0cca Amphenol
+0ccb SKNet Co., Ltd
+0ccc Domex Technology Corp.
+0ccd TerraTec Electronic GmbH
+ 0038 Cinergy T^2 DVB-T Receiver
+0cd4 Bang Olufsen
+ 0101 BeolinkPC2
+0cd7 NewChip S.r.l.
+0cd8 JS Digitech, Inc.
+0cd9 Hitachi Shin Din Cable, Ltd
+0cde Z-Com
+ 0002 XI-725/726 Prism2.5 802.11b Adapter
+ 0005 XI-735 Prism3 802.11b Adapter
+ 0006 Medion 40900 802.11b Adapter
+0cf1 e-Conn Electronic Co., Ltd
+0cf2 ENE Technology, Inc.
+0cf3 Atheros Communications, Inc.
+0cf4 Fomtex Corp.
+0cf5 Cellink Co., Ltd
+0cf6 Compucable Corp.
+0cf7 ishoni Networks
+0cf8 Clarisys, Inc.
+0cf9 Central System Research Co., Ltd
+0cfa Inviso, Inc.
+0cfc Minolta-QMS, Inc.
+0d06 telos EDV Systementwicklung GmbH
+0d0b Contemporary Controls
+0d0c Astron Electronics Co., Ltd
+0d0d MKNet Corp.
+0d0e Hybrid Networks, Inc.
+0d0f Feng Shin Cable Co., Ltd
+0d10 Elastic Networks
+0d11 Maspro Denkoh Corp.
+0d12 Hansol Electronics, Inc.
+0d13 BMF Corp.
+0d14 Array Comm, Inc.
+0d15 OnStream b.v.
+0d16 Hi-Touch Imaging Technologies Co., Ltd
+0d17 NALTEC, Inc.
+0d18 coaXmedia
+0d19 Hank Connection Industrial Co., Ltd
+0d32 Leo Hui Electric Wire & Cable Co., Ltd
+0d33 AirSpeak, Inc.
+0d34 Rearden Steel Technologies
+0d35 Dah Kun Co., Ltd
+0d3c Sri Cable Technology, Ltd
+0d3d Tangtop Technology Co., Ltd
+0d3e Fitcom, inc.
+0d3f MTS Systems Corp.
+0d40 Ascor, Inc.
+0d41 Ta Yun Terminals Industrial Co., Ltd
+0d42 Full Der Co., Ltd
+0d46 Kobil Systems GmbH
+ 3003 mIDentity Light / KAAN SIM III
+ 4000 mIDentity (mass storage)
+ 4001 mIDentity Basic/Classic (composite device)
+ 4081 mIDentity Basic/Classic (installationless)
+0d49 Maxtor
+0d4a NF Corp.
+0d4b Grape Systems, Inc.
+0d4c Tedas AG
+0d4d Coherent, Inc.
+0d4e Agere Systems Netherland BV
+0d4f EADS Airbus France
+0d50 Cleware GmbH
+ 0011 USB-Temp2 Thermometer
+0d51 Volex (Asia) Pte., Ltd
+0d53 HMI Co., Ltd
+0d54 Holon Corp.
+0d55 ASKA Technologies, Inc.
+0d56 AVLAB Technology, Inc.
+0d57 Solomon Microtech, Ltd
+0d5c Belkin
+ a002 F5D6050 802.11b Adapter
+0d5e Myacom, Ltd
+0d5f CSI, Inc.
+0d60 IVL Technologies, Ltd
+0d61 Meilu Electronics (Shenzhen) Co., Ltd
+0d62 Darfon Electronics Corp.
+ a100 Benq Mouse
+0d63 Fritz Gegauf AG
+0d64 DXG Technology Corp.
+ 0107 Horus MT-409 Camera
+ 0303 DXG-305V Camera
+0d65 KMJP Co., Ltd
+0d66 TMT
+0d67 Advanet, Inc.
+0d68 Super Link Electronics Co., Ltd
+0d69 NSI
+0d6a Megapower International Corp.
+0d6b And-Or Logic
+0d70 Try Computer Co., Ltd
+0d71 Hirakawa Hewtech Corp.
+0d72 Winmate Communication, Inc.
+0d73 Hit's Communications, Inc.
+0d76 MFP Korea, Inc.
+0d77 Power Sentry/Newpoint
+0d78 Japan Distributor Corp.
+0d7a MARX Datentechnik GmbH
+0d7b Wellco Technology Co., Ltd
+0d7c Taiwan Line Tek Electronic Co., Ltd
+0d7d Phison Electronics Corp.
+ 0100 PS1001/1011/1006/1026 Flash Disk
+ 0110 Gigabyte FlexDrive
+ 0240 I/O-Magic/Transcend 6-in-1 Card Reader
+ 110E NEC uPD720121/130 USB-ATA/ATAPI Bridge
+ 1240 Apacer 6-in-1 Card Reader 2.0
+ 1300 Flash Disk
+ 1320 PS2031 Flash Disk
+ 1420 PS2044 Pen Drive
+ 1470 Vosonic X's-Drive II+ VP2160
+0d7e American Computer & Digital Components
+0d7f Essential Reality LLC
+0d80 H.R. Silvine Electronics, Inc.
+0d81 TechnoVision
+0d83 Think Outside, Inc.
+0d89 Oz Software
+0d8a King Jim Co., Ltd
+0d8b Ascom Telecommunications, Ltd
+0d8c C-Media Electronics, Inc.
+ 000c Audio Adapter
+0d8d Promotion & Display Technology, Ltd
+0d8e Global Sun Technology, Inc.
+ 7100 802.11b Adapter
+ 7a01 PRISM25 802.11b Adapter
+0d8f Pitney Bowes
+0d90 Sure-Fire Electrical Corp.
+0d96 Skanhex Technology, Inc.
+ 3300 SX330z Camera
+ 4100 SX410z Camera
+ 4102 MD 9700 Camera
+ 5200 SX-520z Camera
+0d97 Santa Barbara Instrument Group
+ 0001 SBIG Astronomy Camera (without firmware)
+ 0101 SBIG Astronomy Camera (with firmware)
+0d98 Mars Semiconductor Corp.
+0d99 Trazer Technologies, Inc.
+0d9a RTX Telecom AS
+0d9b Tat Shing Electrical Co.
+0d9c Chee Chen Hi-Technology Co., Ltd
+0d9d Sanwa Supply, Inc.
+0d9e Avaya
+0d9f Powercom Co., Ltd
+0da0 Danger Research
+0da1 Suzhou Peter's Precise Industrial Co., Ltd
+0da2 Land Instruments International, Ltd
+0da3 Nippon Electro-Sensory Devices Corp.
+0da4 Polar Electro OY
+0da7 IOGear, Inc.
+0da8 softDSP Co., Ltd
+ 0001 SDS 200A Oscilloscope
+0dab Cubig Group
+ 0100 DVR/CVR-M140 MP3 Player
+0dad Westover Scientific
+0db0 Micro Star International
+ 1967 Bluetooth Dongle
+ 4011 Medion Flash XL V2.0 Card Reader
+ 697a Bluetooth Dongle
+ 6982 Medion Flash XL V2.7A Card Reader
+0db1 Wen Te Electronics Co., Ltd
+0db2 Shian Hwi Plug Parts, Plastic Factory
+0db3 Tekram Technology Co., Ltd
+0db4 Chung Fu Chen Yeh Enterprise Corp.
+0dbe Jiuh Shiuh Precision Industry Co., Ltd
+0dbf Quik Tech Solutions
+0dc0 Great Notions
+0dc1 Tamagawa Seiki Co., Ltd
+0dc3 Athena Smartcard Solutions, Inc.
+0dc4 Macpower Peripherals, Ltd
+0dc5 SDK Co., Ltd
+0dc6 Precision Squared Technology Corp.
+0dc7 First Cable Line, Inc.
+0dcd NetworkFab Corp.
+ 0001 Remote Interface Adapter
+ 0002 High Bandwidth Codec
+0dd0 Access Solutions
+ 1002 Triple Talk Speech Synthesizer
+0dd1 Contek Electronics Co., Ltd
+0dd2 Power Quotient International Co., Ltd
+0dd3 MediaQ
+0dd4 Custom Engineering SPA
+0dd5 California Micro Devices
+0dd7 Kocom Co., Ltd
+0dd8 Netac Technology Co., Ltd
+ e007 OnlyDisk U222 Pendrive
+0dd9 HighSpeed Surfing
+0dda Integrated Circuit Solution, Inc.
+0ddb Tamarack, Inc.
+0ddd Datelink Technology Co., Ltd
+0dde Ubicom, Inc.
+0de0 BD Consumer Healthcare
+0ded Novasonics
+0dee Lifetime Memory Products
+0def Full Rise Electronic Co., Ltd
+0df6 Sitecom Europe B.V.
+ 9071 zd1211 802.11g Adapter
+0df7 Mobile Action Technology, Inc.
+ 0620 MA-620 Infrared Adapter
+ 0700 MA-700 Bluetooth Adapter
+0dfa Toyo Communication Equipment Co., Ltd
+0dfc GeneralTouch Technology Co., Ltd
+ 0001 Touchscreen
+0e03 Nippon Systemware Co., Ltd
+0e08 Winbest Technology Co., Ltd
+0e0c Gesytec
+ 0101 LonUSB LonTalk Network Adapter
+0e16 JMTek, LLC
+0e17 Walex Electronic, Ltd
+0e1b Crewave
+0e21 Cowon Systems, Inc.
+ 0300 iAudio CW200
+0e23 Liou Yuane Enterprise Co., Ltd
+0e25 VinChip Systems, Inc.
+0e26 J-Phone East Co., Ltd
+0e30 HeartMath LLC
+0e34 Micro Computer Control Corp.
+0e35 3Pea Technologies, Inc.
+0e36 TiePie engineering
+0e38 Stratitec, Inc.
+0e39 Smart Modular Technologies, Inc.
+0e3a Neostar Technology Co., Ltd
+ 1100 CW-1100 Wireless Network Adapter
+0e3b Mansella, Ltd
+0e41 Line6, Inc.
+ 4250 BassPODxt
+ 4252 BassPODxt Pro
+ 4642 BassPODxt Live
+ 4650 PODxt Live
+ 4750 GuitarPort
+ 5044 PODxt
+ 5050 PODxt Pro
+ 534D SeaMonkey
+0e48 Julia Corp., Ltd
+ 0100 CardPro SmartCard Reader
+0e4a Shenzhen Bao Hing Electric Wire & Cable Mfr. Co.
+0e4c Radica Games, Ltd
+0e55 Speed Dragon Multimedia, Ltd
+0e5a Active Co., Ltd
+0e5b Union Power Information Industrial Co., Ltd
+0e5c Bitland Information Technology Co., Ltd
+0e5d Neltron Industrial Co., Ltd
+0e66 Hawking
+ 400c UF100 Ethernet [pegasus2]
+0e67 Fossil, Inc.
+ 0002 Wrist PDA
+0e6a Megawin Technology Co., Ltd
+0e70 Tokyo Electronic Industry Co., Ltd
+0e72 Hsi-Chin Electronics Co., Ltd
+0e75 TVS Electronics, Ltd
+0e7b On-Tech Industry Co., Ltd
+0e7e Gmate, Inc.
+ 0001 Yopy 3000 PDA
+0e82 Ching Tai Electric Wire & Cable Co., Ltd
+0e8c Well Force Electronic Co., Ltd
+0e90 WiebeTech, LLC
+0e91 VTech Engineering Canada, Ltd
+0e92 C's Glory Enterprise Co., Ltd
+0e93 eM Technics Co., Ltd
+0e95 Future Technology Co., Ltd
+0e96 Aplux Communications, Ltd
+0e97 Fingerworks, Inc.
+0e98 Advanced Analogic Technologies, Inc.
+0e99 Parallel Dice Co., Ltd
+0e9a TA HSING Industries, Ltd
+0e9b ADTEC Corp.
+0e9c Streamzap, Inc.
+ 0000 Streamzap Remote Control
+0e9f Tamura Corp.
+0ea0 Ours Technology, Inc.
+ 2126 7-in-1 Card Reader
+ 2168 Transcend JetFlash 2.0 / Astone USB Drive
+ 6803 OTI-6803 Flash Disk
+ 6808 OTI-6808 Flash Disk
+ 6828 OTI-6828 Flash Disk
+0ea6 Nihon Computer Co., Ltd
+0ea7 MSL Enterprises Corp.
+0ea8 CenDyne, Inc.
+0ead Humax Co., Ltd
+0eb1 WIS Technologies, Inc.
+0eb2 Y-S Electronic Co., Ltd
+0eb3 Saint Technology Corp.
+0eb7 Endor AG
+0ebe VWeb Corp.
+0ebf Omega Technology of Taiwan, Inc.
+0ec0 LHI Technology (China) Co., Ltd
+0ec1 Abit Computer Corp.
+0ec2 Sweetray Industrial, Ltd
+0ec3 Axell Co., Ltd
+0ec4 Ballracing Developments, Ltd
+0ec5 GT Information System Co., Ltd
+0ec6 InnoVISION Multimedia, Ltd
+0ec7 Theta Link Corp.
+ 1008 So., Show 301 Digital Camera
+0ecd Lite-On IT Corp.
+0ece TaiSol Electronics Co., Ltd
+0ecf Phogenix Imaging, LLC
+0ed1 WinMaxGroup
+ 6660 USB Flash Disk 64M-C
+ 6680 USB Flash Disk 64M-B
+0ed2 Kyoto Micro Computer Co., Ltd
+0ed3 Wing-Tech Enterprise Co., Ltd
+0eda Noriake Itron Corp.
+0edf e-MDT Co., Ltd
+0ee0 Shima Seiki Mfg., Ltd
+0ee1 Sarotech Co., Ltd
+0ee2 AMI Semiconductor, Inc.
+0ee3 ComTrue Technology Corp.
+ 1000 Image Tank 1.5
+0ee4 Sunrich Technology, Ltd
+0eee Digital Stream Technology, Inc.
+0eef D-WAV Scientific Co., Ltd
+ 0001 eGalax TouchScreen
+0ef0 Hitachi Cable, Ltd
+0ef1 Aichi Micro Intelligent Corp.
+0ef2 I/O Magic Corp.
+0ef3 Lynn Products, Inc.
+0ef4 DSI Datotech
+0ef5 PointChips
+ 2202 Flash Disk
+0ef6 Yield Microelectronics Corp.
+0ef7 SM Tech Co., Ltd (Tulip)
+0efe Wem Technology, Inc.
+0efd Oasis Semiconductor
+0f06 Visual Frontier Enterprise Co., Ltd
+0f08 CSL Wire & Plug (Shen Zhen) Co.
+0f0c CAS Corp.
+0f0d Hori Co., Ltd
+0f0e Energy Full Corp.
+0f12 Mars Engineering Corp.
+0f13 Acetek Technology Co., Ltd
+0f19 Oracom Co., Ltd
+0f1b Onset Computer Corp.
+0f1c Funai Electric Co., Ltd
+0f1d Iwill Corp.
+0f21 IOI Technology Corp.
+0f22 Senior Industries, Inc.
+0f23 Leader Tech Manufacturer Co., Ltd
+0f24 Flex-P Industries, Snd., Bhd.
+0f2d ViPower, Inc.
+0f2e Geniality Maple Technology Co., Ltd
+0f2f Priva Design Services
+0f30 Jess Technology Co., Ltd
+0f31 Chrysalis Development
+0f32 YFC-BonEagle Electric Co., Ltd
+0f37 Kokuyo Co., Ltd
+0f38 Nien-Yi Industrial Corp.
+0f3d Airprime, Incorporated
+ 0112 CDMA 1xEVDO PC Card, PC 5220
+0f41 RDC Semiconductor Co., Ltd
+0f42 Nital Consulting Services, Inc.
+0f4b St. John Technology Co., Ltd
+0f4c WorldWide Cable Opto Corp.
+0f4d Microtune, Inc.
+ 1000 Bluetooth Dongle
+0f4e Freedom Scientific
+0f52 Wing Key Electrical Co., Ltd
+0f53 Dongguan White Horse Cable Factory, Ltd
+0f54 Kawai Musical Instruments Mfg. Co., Ltd
+0f55 AmbiCom, Inc.
+0f5c Prairiecomm, Inc.
+0f5d NewAge International, LLC
+0f5f Key Technology Corp.
+0f60 NTK, Ltd
+0f61 Varian, Inc.
+0f62 Acrox Technologies Co., Ltd
+0f68 Kobe Steel, Ltd
+0f69 Dionex Corp.
+0f6a Vibren Technologies, Inc.
+0f73 DFI
+0f7c DQ Technology, Inc.
+0f7d NetBotz, Inc.
+0f7e Fluke Corp.
+0f88 VTech Holdings, Ltd
+0f8b Yazaki Corp.
+0f8c Young Generation International Corp.
+0f8d Uniwill Computer Corp.
+0f8e Kingnet Technology Co., Ltd
+0f8f Soma Networks
+0f97 CviLux Corp.
+0f98 CyberBank Corp.
+0f9c Hyun Won, Inc.
+ 0301 M-Any Premium DAH-610 MP3/WMA Player
+ 0332 mobiBLU DAH-1200 MP3/Ogg Player
+0f9e Lucent Technologies
+0fa3 Starconn Electronic Co., Ltd
+0fa4 ATL Technology
+0fa5 Sotec Co., Ltd
+0fa7 Epox Computer Co., Ltd
+0fa8 Logic Controls, Inc.
+0faf Winpoint Electronic Corp.
+0fb0 Haurtian Wire & Cable Co., Ltd
+0fb1 Inclose Design, Inc.
+0fb2 Juan-Chern Industrial Co., Ltd
+0fb8 Wistron Corp.
+0fb9 AACom Corp.
+0fba San Shing Electronics Co., Ltd
+0fbb Bitwise Systems, Inc.
+0fc1 Mitac Internatinal Corp.
+0fc2 Plug and Jack Industrial, Inc.
+0fc5 Delcom Engineering
+ 1222 I/O Development Board
+0fc6 Dataplus Supplies, Inc.
+0fca Research In Motion, Ltd.
+ 0001 Blackberry Handheld
+0fce Sony Ericsson Mobile Communications AB
+ d017 K608i Phone
+0fcf Dynastream Innovations, Inc.
+0fd0 Tulip Computers B.V.
+0fd4 Tenovis GmbH & Co., KG
+0fd5 Direct Access Technology, Inc.
+0fdc Micro Plus
+0fe4 IN-Tech Electronics, Ltd
+0fe5 Greenconn (U.S.A.), Inc.
+0fe9 DVICO
+ db00 FusionHDTV DVB-T (MT352+LgZ201) (uninitialized)
+ db01 FusionHDTV DVB-T (MT352+LgZ201) (initialized)
+ db10 FusionHDTV DVB-T (MT352+Thomson7579) (uninitialized)
+ db11 FusionHDTV DVB-T (MT352+Thomson7579) (initialized)
+0fea United Computer Accessories
+0feb CRS Electronic Co., Ltd
+0fec UMC Electronics Co., Ltd
+0fed Access Co., Ltd
+0fee Xsido Corp.
+0fef MJ Research, Inc.
+0ff6 Core Valley Co., Ltd
+0ff7 CHI SHING Computer Accessories Co., Ltd
+0fff Aopen, Inc.
+1000 Speed Tech Corp.
+1001 Ritronics Components (S) Pte., Ltd
+1003 Sigma Corp.
+1004 LG Electronics, Inc.
+ 1fae U8120 3G Cellphone
+ 6000 VX4400/VX6000 Cellphone
+ 6800 CDMA Modem
+1005 Apacer Technology, Inc.
+ b113 Handy Steno 2.0 (256MB)
+1006 iRiver, Ltd.
+ 3002 iHP-100/120/140 MP3 Player
+1009 Emuzed, Inc.
+100a AV Chaseway, Ltd
+100b Chou Chin Industrial Co., Ltd
+100d Netopia, Inc.
+ 3342 Cayman 3352 DSL Modem
+ cb01 Cayman 3341 Ethernet DSL Router
+1010 Fukuda Denshi Co., Ltd
+1011 Mobile Media Tech.
+1012 SDKM Fibres, Wires & Cables Berhad
+1013 TST-Touchless Sensor Technology AG
+1014 Densitron Technologies PLC
+1015 Softronics Pty., Ltd
+1016 Xiamen Hung's Enterprise Co., Ltd
+1017 Speedy Industrial Supplies, Pte., Ltd
+1020 Labtec
+ 000a Wireless Optical Mouse
+1022 Shinko Shoji Co., Ltd
+1025 Hyper-Paltek
+ 005e USB DVB-T device
+ 005f USB DVB-T device
+1026 Newly Corp.
+1027 Time Domain
+1028 Inovys Corp.
+1029 Atlantic Coast Telesys
+102a Ramos Technology Co., Ltd
+102b Infotronic America, Inc.
+102c Etoms Electronics Corp.
+102d Winic Corp.
+1031 Comax Technology, Inc.
+1032 C-One Technology Corp.
+1033 Nucam Corp.
+1038 Ideazon, Inc.
+ 0100 Zboard
+1043 iCreate Technologies Corp.
+ 8006 Flash Disk 32 MB
+1044 Chu Yuen Enterprise Co., Ltd
+1046 Winbond Electronics Corp. [hex]
+ 9967 W9967CF/W9968CF WebCam IC
+104c AMCO TEC International, Inc.
+1053 Immanuel Electronics Co., Ltd
+1054 BMS International Beheer N.V.
+1055 Complex Micro Interconnection Co., Ltd
+1056 Hsin Chen Ent Co., Ltd
+1057 ON Semiconductor
+1058 Western Digital Technologies, Inc.
+1059 Giesecke & Devrient GmbH
+105c Hong Ji Electric Wire & Cable (Dongguan) Co., Ltd
+105d Delkin Devices, Inc.
+105e Valence Semiconductor Design, Ltd
+105f Chin Shong Enterprise Co., Ltd
+1060 Easthome Industrial Co., Ltd
+1063 Motorola Electronics Taiwan, Ltd [hex]
+ 1555 MC141555 Hub
+1065 CCYU Technology
+ 2136 EasyDisk ED1064
+106a Loyal Legend, Ltd
+106c Curitel Communications, Inc.
+ 2101 AudioVox 8900 Cell Phone
+106d San Chieh Manufacturing, Ltd
+106e ConectL
+106f Money Controls
+1076 GCT Semiconductor, Inc.
+107d Arlec Australia, Ltd
+107e Midoriya Electric Co., Ltd
+107f KidzMouse, Inc.
+1082 Shin-Etsukaken Co., Ltd
+1083 Canon Electronics, Inc.
+1084 Pantech Co., Ltd
+108a Chloride Power Protection
+108b Grand-tek Technology Co., Ltd
+108c Robert Bosch GmbH
+1099 Surface Optics Corp.
+109a DATASOFT Systems GmbH
+109f eSOL Co., Ltd
+10a0 Hirotech, Inc.
+10a3 Mitsubishi Materials Corp.
+10a9 SK Teletech Co., Ltd
+10aa Cables To Go
+10ab USI Co., Ltd
+ 10c5 Sony-Ericsson / Samsung DataCable
+10ac Honeywell, Inc.
+10ae Princeton Technology Corp.
+10b5 Comodo (PLX?)
+ 9060 Test Board
+10b8 DiBcom
+ 0bb8 DiBcom USB DVB-T reference design (MOD300) (cold)
+ 0bb9 DiBcom USB DVB-T reference design (MOD300) (warm)
+ 0bc6 DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold)
+ 0bc7 DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm)
+10bb TM Technology, Inc.
+10bc Dinging Technology Co., Ltd
+10bd TMT Technology, Inc.
+10bf SmartHome
+ 0001 SmartHome PowerLinc
+10c4 Cygnal Integrated Products, Inc.
+10c5 Sanei Electric, Inc.
+10c6 Intec, Inc.
+10cb Eratech
+10cc GBM Connector Co., Ltd
+10cd Kycon, Inc.
+10cf Velleman Components, Inc.
+ 5500 8055 Experiment Interface Board (address=0)
+ 5501 8055 Experiment Interface Board (address=1)
+ 5502 8055 Experiment Interface Board (address=2)
+ 5503 8055 Experiment Interface Board (address=3)
+10d1 Hottinger Baldwin Measurement
+ 0101 USB-Module for Spider8, CP32
+ 0202 CP22 - Communication Processor
+ 0301 CP42 - Communication Processor
+10d4 Man Boon Manufactory, Ltd
+10d5 Uni Class Technology Co., Ltd
+10d6 Actions Semiconductor Co., Ltd
+ 1000 MP3 Player
+ 1100 MPMan MP-Ki 128 MP3 Player/Recorder
+10de Authenex, Inc.
+10df In-Win Development, Inc.
+10e0 Post-Op Video, Inc.
+10e1 CablePlus, Ltd
+10e2 Nada Electronics, Ltd
+10ec Vast Technologies, Inc.
+10fb Pictos Technologies, Inc.
+10fd Anubis Electronics, Ltd
+ 804d Typhoon Webshot II Webcam [zc0301]
+1a0a ...
+ badd USB OTG Compliance test device
+1100 VirTouch, Ltd
+ 0001 VTPlayer VTP-1 Braille Mouse
+1101 EasyPass Industrial Co., Ltd
+ 0001 FSK Electronics Super GSM Reader
+1108 Brightcom Technologies, Ltd
+1110 Analog Devices Canada, Ltd (Allied Telesyn)
+ 900f AT-AR215 DSL Modem
+1112 YM ELECTRIC CO., Ltd
+1113 Medion AG
+111e VSO Electric Co., Ltd
+112e Master Hill Electric Wire and Cable Co., Ltd
+112f Cellon International, Inc.
+1130 Tenx Technology, Inc.
+1131 Integrated System Solution Corp.
+ 1001 KY-BT100 Bluetooth Adapter
+1132 Toshiba Corp., Digital Media Equipment [hex]
+ 4331 PDR-M4/M5/M70 Digital Camera
+ 4332 PDR-M60 Digital Camera
+113c Arin Tech Co., Ltd
+113d Mapower Electronics Co., Ltd
+1141 V One Multimedia, Pte., Ltd
+1142 CyberScan Technologies, Inc.
+1147 Ever Great Electric Wire and Cable Co., Ltd
+114c Tinius Olsen Testing Machine Co., Inc.
+114d Alpha Imaging Technology Corp.
+1162 Secugen Corp.
+1163 DeLorme Publishing, Inc.
+1164 YUAN High-Tech Development Co., Ltd
+1165 Telson Electronics Co., Ltd
+1166 Bantam Interactive Technologies
+1167 Salient Systems Corp.
+1168 BizConn International Corp.
+116e Gigastorage Corp.
+116f Silicon 10 Technology Corp.
+1175 Shengyih Steel Mold Co., Ltd
+117d Santa Electronic, Inc.
+117e JNC, Inc.
+1182 Venture Corp., Ltd
+1183 Compaq Computer Corp. [hex] (Digital Dream ??)
+ 19c7 ISDN TA
+ 4008 56k FaxModem
+ 504a PJB-100 Personal Jukebox
+1184 Kyocera Elco Corp.
+118f You Yang Technology Co., Ltd
+1190 Tripace
+1191 Loyalty Founder Enterprise Co., Ltd
+1196 Yankee Robotics, LLC
+ 0010 Trifid Camera without code
+ 0011 Trifid Camera
+1197 Technoimagia Co., Ltd
+1198 StarShine Technology Corp.
+1199 Sierra Wireless, Inc.
+ 0112 CDMA 1xEVDO PC Card, AirCard 580
+119a ZHAN QI Technology Co., Ltd
+119b ruwido austria GmbH
+ 0400 Infrared Keyboard V2.01
+11a0 Chipcon AS
+ eb11 CC2400EB 2.0 ZigBee Sniffer
+11a3 Technovas Co., Ltd
+11aa GlobalMedia Group, LLC
+11ab Exito Electronics Co., Ltd
+11db Topfield Co., Ltd.
+ 1000 PVR
+ 1100 PVR
+11f5 Siemens AG (?)
+ 0003 Mobile phone USB cable
+11f7 Alcatel (?)
+ 02df TD10 Mobile phone USB cable
+1209 InterBiometrics
+ 1001 USB Hub
+ 1002 USB Relais
+ 1003 IBSecureCam-P
+ 1004 IBSecureCam-O
+ 1005 IBSecureCam-N
+120e Hudson Soft Co., Ltd
+121e Jungsoft Co., Ltd
+ 3403 Muzio JM250 Audio Player
+1241 Belkin
+ 1111 Mouse
+ 1177 F8E842-DL Mouse
+124a AirVast
+ 4017 PC-Chips 802.11b Adapter
+124b Nyko (Honey Bee)
+ 4d01 Airflo EX Joystick
+1267 Logic3 / SpectraVideo plc
+ 0201 A4Tech SWOP-3 Mouse
+ a001 JP260 PC Game Pad
+126e Strobe Data, Inc.
+126f TwinMOS
+ 1325 Mobile Disk
+ 2168 Mobile Disk III
+1275 Xaxero Marine Software Engineering, Ltd.
+ 0002 WeatherFax 2000 Demodulator
+ 0080 SkyEye Weather Satellite Receiver
+1292 Innomedia
+ 0258 Creative Labs VoIP Blaster
+1293 Belkin Components [hex]
+ 0002 F5U002 Parallel Port [uss720]
+ 2101 104-key keyboard
+12fd AIN Comm. Technology Co., Ltd
+ 1001 AWU2000b 802.11b Stick
+1310 Roper
+ 0001 Class 1 Bluetooth Dongle
+1312 ICS Electronics
+131d Natural Point
+ 0155 TrackIR 3 Pro Head Tracker
+132b Konica Minolta
+ 0000 Dimage A2 Camera
+ 0003 Dimage Xg Camera
+ 0006 Dimage Z2 Camera
+ 0008 Dimage X21 Camera
+ 000b Dimage Z10 Camera
+ 000d Dimage X50 Camera [storage?]
+ 000f Dimage X50 Camera [p2p?]
+ 0010 Dimage G600 Camera
+ 0012 Dimage Scan Elite5400 2
+ 0013 Dimage X31 Camera
+ 0015 Dimage G530 Camera
+ 0017 Dimage Z3 Camera
+ 0019 Dimage A200 Camera
+ 0021 Dimage Z5 Camera
+1342 Mobility
+ 0200 EasiDock 200 Hub
+ 0201 EasiDock 200 Keyboard and Mouse Port
+ 0202 EasiDock 200 Serial Port
+ 0203 EasiDock 200 Printer Port
+134e Digby's Bitpile, Inc. DBA D Bit
+1370 Swissbit
+ 6828 Victorinox Flash Drive
+1398 Q-tec
+ 2103 USB 2.0 Storage Device
+13b0 Alesis
+ 000a Photon X25 MIDI Controller
+13b1 Linksys
+ 000b WUSB11 v4.0 802.11b Adapter
+ 0011 WUSB54GP v4.0 802.11g Adapter
+ 0018 USB200M 10/100 Ethernet Adapter
+13d2 Shark Multimedia
+ 0400 Pocket Ethernet [klsi]
+13d3 IMC Networks
+ 3201 VisionDTV USB-Ter/HAMA USB DVB-T device cold
+ 3202 VisionDTV USB-Ter/HAMA USB DVB-T device warm
+1453 Radio Shack
+ 4026 26-183 Serial Cable
+1462 Micro Star International
+ 5512 MegaStick-1 Flash Stick
+147a Formosa Industrial Computing, Inc.
+1484 Elsa AG [hex]
+ 1746 Ecomo 19H99 Monitor
+ 7616 Elsa Hub
+148f Ralink Technology, Corp.
+ 2570 802.11g WiFi
+14aa AVerMedia (again) or C&E
+ 0001 Avermedia AverTV DVBT USB1.1 (cold)
+ 0002 Avermedia AverTV DVBT USB1.1 (warm)
+ 0201 AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (cold)
+ 0301 AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (warm)
+14c2 Gemlight Computer, Ltd
+1518 Cheshire Engineering Corp.
+ 0001 HDReye High Dynamic Range Camera
+ 0002 HDReye (before firmware loads)
+1520 Bitwire Corp.
+152e LG (HLDS)
+ e001 GSA-5120D DVD-RW
+1546 U-Blox AG
+1554 Prolink Microsystems Corp.
+1568 Sunf Pu Technology Co., Ltd
+15c2 SoundGraph Inc.
+ ffdc iMON PAD Remote Controller
+15c6 Laboratoires MXM
+15e8 SohoWare
+ 9100 NUB100 Ethernet [pegasus]
+15e9 Pacific Digital Corp.
+15f4 HanfTek
+ 0001 HanfTek UMT-010 USB2.0 DVB-T (cold)
+ 0025 HanfTek UMT-010 USB2.0 DVB-T (warm)
+1604 Tascam
+ 8000 US-428 Audio/Midi Controller (without fw)
+ 8001 US-428 Audio/Midi Controller
+ 8004 US-224 Audio/Midi Controller (without fw)
+ 8005 US-224 Audio/Midi Controller
+ 8006 US-122 Audio/Midi Interface (without fw)
+ 8007 US-122 Audio/Midi Interface
+1606 Umax [hex]
+ 0010 Astra 1220U
+ 0030 Astra 2000U
+ 0060 Astra 3400U
+ 0130 Astra 2100U
+ 0160 Astra 5400U
+ 0230 Astra 2200/2200SU
+ 2020 AstraCam 1000
+1608 Inside Out Networks [hex]
+ 0001 EdgePort/4 Serial Port
+ 1403 MultiTech Systems MT4X56 Modem
+1645 Entrega [hex]
+ 0001 1S Serial Port
+ 0002 2S Serial Port
+ 0003 1S25 Serial Port
+ 0004 4S Serial Port
+ 0005 E45 Ethernet [klsi]
+ 0006 Parallel Port
+ 0007 U1-SC25 SCSI
+ 0093 1S9 Serial Port
+ 8000 EZ-USB
+ 8002 2x Serial Port
+ 8093 PortGear Serial Port
+1657 Struck Innovative Systeme GmbH
+ 3150 SIS3150 USB2.0 to VME interface
+1668 Actiontec Electronics, Inc. [hex]
+ 0333 Modem
+ 0408 Prism2.5 802.11b Adapter
+ 0421 Prism2.5 802.11b Adapter
+ 0500 BTM200B BlueTooth Adapter
+1690 Askey Computer Corp. [hex]
+ 0101 Creative Modem Blaster DE5670
+ 0103 Askey 1456 VQE-R3 Modem [conexant]
+ 0109 Askey MagicXpress V.90 Pocket Modem [conexant]
+1696 Hitachi Video and Information System, Inc.
+1697 VTec Test, Inc.
+1706 BlueView Technologies, Inc.
+1733 Cellink Technology Co., Ltd
+ 0101 RF Wireless Optical Mouse OP-701
+17b3 Grey Innovation
+ 0004 Linux-USB Midi Gadget
+17eb Cornice, Inc.
+1822 Twinhan
+ 3201 VisionDTV USB-Ter/HAMA USB DVB-T device cold
+ 3202 VisionDTV USB-Ter/HAMA USB DVB-T device warm
+185b Compro
+ d000 Compro Videomate DVB-U2000 - DVB-T USB cold
+ d001 Compro Videomate DVB-U2000 - DVB-T USB warm
+1894 Topseed
+ 5632 Atek Tote Remote
+ 5641 TSAM-004 Presentation Remote
+1977 T-Logic
+ 0111 TL203 MP3 Player and Voice Recorder
+1995 Trillium Technology Pty. Ltd.
+ 3202 REC-ADPT-USB (recorder)
+ 3203 REC-A-ADPT-USB (recorder)
+1ebb NuCORE Technology, Inc.
+2001 D-Link Corp. [hex]
+ 3200 DWL-120 802.11b (Atmel RFMD503A) [usbvnetr]
+ 3700 DWL-122 802.11b
+ 3701 DWL-G120 Spinnaker 802.11b
+ 3703 DWL-122 802.11b
+ 3704 DWL-G122 802.11g rev. A2
+ 3c00 DWL-G122 802.11g rev. B1 [ralink]
+ 4000 DSB-650C Ethernet [klsi]
+ 4001 DSB-650TX Ethernet [pegasus]
+ 4002 DSB-650TX Ethernet [pegasus]
+ 4003 DSB-650TX-PNA Ethernet [pegasus]
+ abc1 DSB-650 Ethernet [pegasus]
+ f013 DLink 7 port USB2.0 Hub
+ f10d Accent Communications Modem
+2040 Hauppauge
+ 9300 Hauppauge WinTV NOVA-T USB2 (cold)
+ 9301 Hauppauge WinTV NOVA-T USB2 (warm)
+2101 ActionStar
+ 0201 SIIG 4-to-2 Printer Switch
+2162 Creative (?)
+ 500c DE5771 Modem Blaster
+2222 MacAlly
+ 0004 iWebKey Keyboard
+22b8 Motorola PCS
+ 0005 V.60c/V.60i GSM Phone
+ 1005 T280e GSM/GPRS Phone
+ 2821 T720 GSM Phone
+ 2822 V.120e GSM Phone
+ 3002 A835 GSM Phone
+ 3802 C330/A780 GSM Phone
+ 4002 A920/A925 UMTS Phone
+ 4810 E398 Storage
+ 4902 E398 GSM Phone
+ 600c A768i GSM Phone
+ 604c A780 GSM Phone (storage)
+ 6631 CDC Modem
+ 6604 Washington CDMA Phone
+22b9 eTurboTouch Technology, Inc.
+22ba Technology Innovation Holdings, Ltd
+2304 Pinnacle Systems, Inc. [hex]
+ 0109 Pinnacle Studio PCTV USB (SECAM)
+ 0110 Pinnacle Studio PCTV USB (PAL)
+ 0111 Miro PCTV USB
+ 0112 Pinnacle Studio PCTV USB (NTSC) with FM radio
+ 0208 Pinnacle Studio PCTV USB2
+ 0210 Pinnacle Studio PCTV USB (PAL) with FM radio
+ 0212 Pinnacle Studio PCTV USB (NTSC)
+ 0214 Pinnacle Studio PCTV USB (PAL) with FM radio
+ 0300 Pinnacle Studio Linx Video input cable (NTSC)
+ 0301 Pinnacle Studio Linx Video input cable (PAL)
+ 0419 Pinnacle PCTV Bungee USB (PAL) with FM radio
+2318 Shining Technologies, Inc. [hex]
+ 0011 CitiDISK Jr. IDE Enclosure
+2375 Digit@lway, Inc.
+ 0001 Digital Audio Player
+2406 SANHO Digital Electronics Co., Ltd.
+ 6688 PD7X Portable Storage
+2632 TwinMOS
+ 3209 7-in-1 Card Reader
+2650 Electronics For Imaging, Inc. [hex]
+2770 NHJ, Ltd
+ 9120 Che-ez! Snap / iClick Tiny VGA Digital Camera
+2899 Toptronic Industrial Co., Ltd
+2fb2 Fujitsu, Ltd
+3125 Eagletron
+ 0001 TrackerPod Camera Stand
+3176 Whanam Electronics Co., Ltd
+3340 Yakumo
+ 0e3a Pocket PC 300 GPS SL
+3504 Micro Star
+ f110 Security Key
+3538 Power Quotient International Co., Ltd
+ 0001 Travel Flash
+ 0042 Cool Drive U339 Flash Disk
+3579 DIVA
+ 6901 Media Reader
+3636 InVibro
+3838 WEM
+ 0001 5-in-1 Card Reader
+3923 National Instruments Corp.
+ 703c USB-485 RS485 Cable
+4102 iRiver, Ltd.
+ 1001 iFP-100 series mp3 player
+ 1003 iFP-300 series mp3 player
+ 1005 iFP-500 series mp3 player
+ 1007 iFP-700 series mp3/ogg vorbis player
+ 1008 iFP-800 series mp3/ogg vorbis player
+ 100A iFP-1000 series mp3/ogg vorbis player
+ 1101 iFP-100 series mp3 player (ums firmware)
+ 1103 iFP-300 series mp3 player (ums firmware)
+ 1105 iFP-500 series mp3 player (ums firmware)
+413c Dell Computer Corp.
+ 1002 Keyboard Hub
+ 2002 SK-8125 Keyboard
+ 2100 SK-3106 Keyboard
+ 2101 SmartCard Reader Keyboard
+ 2500 DRAC4 Remote Access Card
+ 3010 Optical Wheel Mouse
+ 4001 Axim X5
+ 4002 Axim X3
+ 4003 Axim X30
+ 8100 TrueMobile 1180 802.11b Adapter
+ 8103 Wireless 350 Bluetooth
+ a001 Hub
+ a700 Hub (in 1905FP LCD Monitor)
+4242 USB Design by Example
+ 4201 Buttons and Lights HID device
+ 4220 Echo 1 Camera
+4146 USBest Technology
+ 9281 Iomega Micro Mini 128MB Flash Drive
+ ba01 Intuix Flash Drive
+4572 Shuttle, Inc.
+ 4572 Shuttle PN31 Remote
+4586 Panram
+ 1026 Crystal Bar Flash Drive
+4670 EMS Production
+ 9394 Game Cube USB Memory Adaptor 64M
+5032 Grandtec
+ 0bb8 Grandtec USB1.1 DVB-T (cold)
+ 0bb9 Grandtec USB1.1 DVB-T (warm)
+ 0fa0 Grandtec USB1.1 DVB-T (cold)
+ 0fa1 Grandtec USB1.1 DVB-T (warm)
+5041 Linksys (?)
+ 2234 WUSB54G 802.11g Adapter
+544d Transmeta Corp.
+5543 UC-Logic Technology Corp.
+ 0002 SuperPen WP3325U Tablet
+ 0004 Genius MousePen 5x4 Tablet
+55aa OnSpec Electronic, Inc.
+ 1234 ATAPI Bridge
+ a103 Sandisk SDDR-55 SmartMedia Card Reader
+ b012 Mitsumi FA402M 8-in-2 Card Reader
+636c CoreLogic, Inc.
+6666 Prototype product Vendor ID
+ 0667 Smart Joy PSX, PS-PC Smart JoyPad
+6993 Freshtel
+ b001 FT-102 VoIP USB Phone
+6a75 Shanghai Jujo Electronics Co., Ltd
+8086 Intel Corp.
+ 0110 Easy PC Camera
+ 0431 Intel Pro Video PC Camera
+ 0510 Digital Movie Creator
+ 0630 Pocket PC Camera
+ 07d3 BLOB boot loader firmware
+ 1111 PRO/Wireless 2011B 802.11b Adapter
+ 9890 82930 Test Board
+ c013 Wireless HID Station
+8341 EGO Systems, Inc.
+ 2000 Flashdisk
+9710 MosChip Semiconductor
+ 7705 Printer cable
+ 7715 Printer cable
+c251 Keil Software, Inc.
+ 2710 ULink
+eb1a eMPIA Technology, Inc.
+ 17de KWorld V-Stream XPERT DTV - DVB-T USB cold
+ 17df KWorld V-Stream XPERT DTV - DVB-T USB warm
+ 2710 SilverCrest WebCam
+ 2800 Terratec Cinergy 200
+ 2801 GrabBeeX+ Video Encoder
+
+# List of known device classes, subclasses and protocols
+
+# Syntax:
+# C class class_name
+# subclass subclass_name <-- single tab
+# protocol protocol_name <-- two tabs
+
+C 00 (Defined at Interface level)
+C 01 Audio
+ 01 Control Device
+ 02 Streaming
+ 03 MIDI Streaming
+C 02 Communications
+ 01 Direct Line
+ 02 Abstract (modem)
+ 00 None
+ 01 AT-commands (v.25ter)
+ 02 AT-commands (PCCA101)
+ 03 AT-commands (PCCA101 + wakeup)
+ 04 AT-commands (GSM)
+ 05 AT-commands (3G)
+ 06 AT-commands (CDMA)
+ fe Defined by command set descriptor
+ ff Vendor Specific (MSFT RNDIS?)
+ 03 Telephone
+ 04 Multi-Channel
+ 05 CAPI Control
+ 06 Ethernet Networking
+ 07 ATM Networking
+ 08 Wireless Handset Control
+ 09 Device Management
+ 0a Mobile Direct Line
+ 0b OBEX
+ 0c Ethernet Emulation
+ 07 Ethernet Emulation (EEM)
+C 03 Human Interface Devices
+ 00 No Subclass
+ 00 None
+ 01 Keyboard
+ 02 Mouse
+ 01 Boot Interface Subclass
+ 00 None
+ 01 Keyboard
+ 02 Mouse
+C 06 Imaging
+ 01 Still Image Capture
+ 01 Picture Transfer Protocol (PIMA 15470)
+C 07 Printer
+ 01 Printer
+ 00 Reserved/Undefined
+ 01 Unidirectional
+ 02 Bidirectional
+ 03 IEEE 1284.4 compatible bidirectional
+ ff Vendor Specific
+C 08 Mass Storage
+ 01 RBC (typically Flash)
+ 00 Control/Bulk/Interrupt
+ 01 Control/Bulk
+ 50 Bulk (Zip)
+ 02 SFF-8020i, MMC-2 (ATAPI)
+ 03 QIC-157
+ 04 Floppy (UFI)
+ 00 Control/Bulk/Interrupt
+ 01 Control/Bulk
+ 50 Bulk (Zip)
+ 05 SFF-8070i
+ 06 SCSI
+ 00 Control/Bulk/Interrupt
+ 01 Control/Bulk
+ 50 Bulk (Zip)
+C 09 Hub
+ 00 Unused
+ 00 Full speed hub
+ 01 Single TT
+ 02 TT per port
+C 0a CDC Data
+ 00 Unused
+ 30 I.430 ISDN BRI
+ 31 HDLC
+ 32 Transparent
+ 50 Q.921M
+ 51 Q.921
+ 52 Q.921TM
+ 90 V.42bis
+ 91 Q.932 EuroISDN
+ 92 V.120 V.24 rate ISDN
+ 93 CAPI 2.0
+ fd Host Based Driver
+ fe CDC PUF
+ ff Vendor specific
+C 0b Chip/SmartCard
+C 0d Content Security
+C 0e Video
+ 00 Undefined
+ 01 Video Control
+ 02 Video Streaming
+ 03 Video Interface Collection
+C dc Diagnostic
+ 01 Reprogrammable Diagnostics
+ 01 USB2 Compliance
+C e0 Wireless
+ 01 Radio Frequency
+ 01 Bluetooth
+ 02 Ultra WideBand Radio Control
+ 03 RNDIS
+ 02 Wireless USB Wire Adapter
+ 01 Host Wire Adapter Control/Data Streaming
+ 02 Device Wire Adapter Control/Data Streaming
+ 03 Device Wire Adapter Isochronous Streaming
+C ef Miscellaneous Device
+ 01 ?
+ 01 Microsoft ActiveSync
+ 02 Palm Sync
+ 02 Common Class
+ 01 Interface Association
+ 02 Wire Adapter Multifunction Peripheral
+ 03 ?
+ 01 Cable Based Association
+C fe Application Specific Interface
+ 01 Device Firmware Update
+ 02 IRDA Bridge
+ 03 Test and Measurement
+ 01 TMC
+ 02 USB488
+C ff Vendor Specific Class
+ ff Vendor Specific Subclass
+ ff Vendor Specific Protocol
+
+# List of Audio Class Terminal Types
+
+# Syntax:
+# AT terminal_type terminal_type_name
+
+AT 0100 USB Undefined
+AT 0101 USB Streaming
+AT 01ff USB Vendor Specific
+AT 0200 Input Undefined
+AT 0201 Microphone
+AT 0202 Desktop Microphone
+AT 0203 Personal Microphone
+AT 0204 Omni-directional Microphone
+AT 0205 Microphone Array
+AT 0206 Processing Microphone Array
+AT 0300 Output Undefined
+AT 0301 Speaker
+AT 0302 Headphones
+AT 0303 Head Mounted Display Audio
+AT 0304 Desktop Speaker
+AT 0305 Room Speaker
+AT 0306 Communication Speaker
+AT 0307 Low Frequency Effects Speaker
+AT 0400 Bidirectional Undefined
+AT 0401 Handset
+AT 0402 Headset
+AT 0403 Speakerphone, no echo reduction
+AT 0404 Echo-suppressing speakerphone
+AT 0405 Echo-canceling speakerphone
+AT 0500 Telephony Undefined
+AT 0501 Phone line
+AT 0502 Telephone
+AT 0503 Down Line Phone
+AT 0600 External Undefined
+AT 0601 Analog Connector
+AT 0602 Digital Audio Interface
+AT 0603 Line Connector
+AT 0604 Legacy Audio Connector
+AT 0605 SPDIF interface
+AT 0606 1394 DA stream
+AT 0607 1394 DV stream soundtrack
+AT 0700 Embedded Undefined
+AT 0701 Level Calibration Noise Source
+AT 0702 Equalization Noise
+AT 0703 CD Player
+AT 0704 DAT
+AT 0705 DCC
+AT 0706 MiniDisc
+AT 0707 Analog Tape
+AT 0708 Phonograph
+AT 0709 VCR Audio
+AT 070a Video Disc Audio
+AT 070b DVD Audio
+AT 070c TV Tuner Audio
+AT 070d Satellite Receiver Audio
+AT 070e Cable Tuner Audio
+AT 070f DSS Audio
+AT 0710 Radio Receiver
+AT 0711 Radio Transmitter
+AT 0712 Multitrack Recorder
+AT 0713 Synthesizer
+
+# List of HID Descriptor Types
+
+# Syntax:
+# HID descriptor_type descriptor_type_name
+
+HID 21 HID
+HID 22 Report
+HID 23 Physical
+
+# List of HID Descriptor Item Types
+# Note: 2 bits LSB encode data length following
+
+# Syntax:
+# R item_type item_type_name
+
+# Main Items
+R 80 Input
+R 90 Output
+R b0 Feature
+R a0 Collection
+R c0 End Collection
+
+# Global Items
+R 04 Usage Page
+R 14 Logical Minimum
+R 24 Logical Maximum
+R 34 Physical Minimum
+R 44 Physical Maximum
+R 54 Unit Exponent
+R 64 Unit
+R 74 Report Size
+R 84 Report ID
+R 94 Report Count
+R a4 Push
+R b4 Pop
+
+# Local Items
+R 08 Usage
+R 18 Usage Minimum
+R 28 Usage Maximum
+R 38 Designator Index
+R 48 Designator Minimum
+R 58 Designator Maximum
+R 78 String Index
+R 88 String Minimum
+R 98 String Maximum
+R a8 Delimiter
+
+# List of Physical Descriptor Bias Types
+
+# Syntax:
+# BIAS item_type item_type_name
+
+BIAS 0 Not Applicable
+BIAS 1 Right Hand
+BIAS 2 Left Hand
+BIAS 3 Both Hands
+BIAS 4 Either Hand
+
+# List of Physical Descriptor Item Types
+
+# Syntax:
+# PHY item_type item_type_name
+
+PHY 00 None
+PHY 01 Hand
+PHY 02 Eyeball
+PHY 03 Eyebrow
+PHY 04 Eyelid
+PHY 05 Ear
+PHY 06 Nose
+PHY 07 Mouth
+PHY 08 Upper Lip
+PHY 09 Lower Lip
+PHY 0a Jaw
+PHY 0b Neck
+PHY 0c Upper Arm
+PHY 0d Elbow
+PHY 0e Forearm
+PHY 0f Wrist
+PHY 10 Palm
+PHY 11 Thumb
+PHY 12 Index Finger
+PHY 13 Middle Finger
+PHY 14 Ring Finger
+PHY 15 Little Finger
+PHY 16 Head
+PHY 17 Shoulder
+PHY 18 Hip
+PHY 19 Waist
+PHY 1a Thigh
+PHY 1b Knee
+PHY 1c calf
+PHY 1d Ankle
+PHY 1e Foot
+PHY 1f Heel
+PHY 20 Ball of Foot
+PHY 21 Big Toe
+PHY 22 Second Toe
+PHY 23 Third Toe
+PHY 24 Fourth Toe
+PHY 25 Fifth Toe
+PHY 26 Brow
+PHY 27 Cheek
+
+# List of HID Usages
+
+# Syntax:
+# HUT hi _usage_page hid_usage_page_name
+# hid_usage hid_usage_name
+
+HUT 00 Undefined
+HUT 01 Generic Desktop Controls
+ 000 Undefined
+ 001 Pointer
+ 002 Mouse
+ 004 Joystick
+ 005 Gamepad
+ 006 Keyboard
+ 007 Keypad
+ 008 Multi-Axis Controller
+ 030 Direction-X
+ 031 Direction-Y
+ 032 Direction-Z
+ 033 Rotate-X
+ 034 Rotate-Y
+ 035 Rotate-Z
+ 036 Slider
+ 037 Dial
+ 038 Wheel
+ 039 Hat Switch
+ 03a Counted Buffer
+ 03b Byte Count
+ 03c Motion Wakeup
+ 03d Start
+ 03e Select
+ 040 Vector-X
+ 041 Vector-Y
+ 042 Vector-Z
+ 043 Vector-X relative Body
+ 044 Vector-Y relative Body
+ 045 Vector-Z relative Body
+ 046 Vector
+ 080 System Control
+ 081 System Power Down
+ 082 System Sleep
+ 083 System Wake Up
+ 084 System Context Menu
+ 085 System Main Menu
+ 086 System App Menu
+ 087 System Menu Help
+ 088 System Menu Exit
+ 089 System Menu Select
+ 08a System Menu Right
+ 08b System Menu Left
+ 08c System Menu Up
+ 08d System Menu Down
+ 090 Direction Pad Up
+ 091 Direction Pad Down
+ 092 Direction Pad Right
+ 093 Direction Pad Left
+HUT 02 Simulation Controls
+ 000 Undefined
+ 001 Flight Simulation Device
+ 002 Automobile Simulation Device
+ 003 Tank Simulation Device
+ 004 Spaceship Simulation Device
+ 005 Submarine Simulation Device
+ 006 Sailing Simulation Device
+ 007 Motorcycle Simulation Device
+ 008 Sports Simulation Device
+ 009 Airplane Simualtion Device
+ 00a Helicopter Simulation Device
+ 00b Magic Carpet Simulation Device
+ 00c Bicycle Simulation Device
+ 020 Flight Control Stick
+ 021 Flight Stick
+ 022 Cyclic Control
+ 023 Cyclic Trim
+ 024 Flight Yoke
+ 025 Track Control
+ 0b0 Aileron
+ 0b1 Aileron Trim
+ 0b2 Anti-Torque Control
+ 0b3 Autopilot Enable
+ 0b4 Chaff Release
+ 0b5 Collective Control
+ 0b6 Dive Break
+ 0b7 Electronic Countermeasures
+ 0b8 Elevator
+ 0b9 Elevator Trim
+ 0ba Rudder
+ 0bb Throttle
+ 0bc Flight COmmunications
+ 0bd Flare Release
+ 0be Landing Gear
+ 0bf Toe Break
+ 0c0 Trigger
+ 0c1 Weapon Arm
+ 0c2 Weapons Select
+ 0c3 Wing Flaps
+ 0c4 Accelerator
+ 0c5 Brake
+ 0c6 Clutch
+ 0c7 Shifter
+ 0c8 Steering
+ 0c9 Turret Direction
+ 0ca Barrel Elevation
+ 0cb Drive Plane
+ 0cc Ballast
+ 0cd Bicylce Crank
+ 0ce Handle Bars
+ 0cf Front Brake
+ 0d0 Rear Brake
+HUT 03 VR Controls
+ 000 Unidentified
+ 001 Belt
+ 002 Body Suit
+ 003 Flexor
+ 004 Glove
+ 005 Head Tracker
+ 006 Head Mounted Display
+ 007 Hand Tracker
+ 008 Oculometer
+ 009 Vest
+ 00a Animatronic Device
+ 020 Stereo Enable
+ 021 Display Enable
+HUT 04 Sport Controls
+ 000 Unidentified
+ 001 Baseball Bat
+ 002 Golf Club
+ 003 Rowing Machine
+ 004 Treadmill
+ 030 Oar
+ 031 Slope
+ 032 Rate
+ 033 Stick Speed
+ 034 Stick Face Angle
+ 035 Stick Heel/Toe
+ 036 Stick Follow Through
+ 047 Stick Temp
+ 038 Stick Type
+ 039 Stick Height
+ 050 Putter
+ 051 1 Iron
+ 052 2 Iron
+ 053 3 Iron
+ 054 4 Iron
+ 055 5 Iron
+ 056 6 Iron
+ 057 7 Iron
+ 058 8 Iron
+ 059 9 Iron
+ 05a 10 Iron
+ 05b 11 Iron
+ 05c Sand Wedge
+ 05d Loft Wedge
+ 05e Power Wedge
+ 05f 1 Wood
+ 060 3 Wood
+ 061 5 Wood
+ 062 7 Wood
+ 063 9 Wood
+HUT 05 Game Controls
+ 000 Undefined
+ 001 3D Game Controller
+ 002 Pinball Device
+ 003 Gun Device
+ 020 Point Of View
+ 021 Turn Right/Left
+ 022 Pitch Right/Left
+ 023 Roll Forward/Backward
+ 024 Move Right/Left
+ 025 Move Forward/Backward
+ 026 Move Up/Down
+ 027 Lean Right/Left
+ 028 Lean Forward/Backward
+ 029 Height of POV
+ 02a Flipper
+ 02b Secondary Flipper
+ 02c Bump
+ 02d New Game
+ 02e Shoot Ball
+ 02f Player
+ 030 Gun Bolt
+ 031 Gun Clip
+ 032 Gun Selector
+ 033 Gun Single Shot
+ 034 Gun Burst
+ 035 Gun Automatic
+ 036 Gun Safety
+ 037 Gamepad Fire/Jump
+ 038 Gamepad Fun
+ 039 Gamepad Trigger
+HUT 07 Keyboard
+ 000 No Event
+ 001 Keyboard ErrorRollOver
+ 002 Keyboard POSTfail
+ 003 Keyboard Error Undefined
+ 004 A
+ 005 B
+ 006 C
+ 007 D
+ 008 E
+ 009 F
+ 00a G
+ 00b H
+ 00c I
+ 00d J
+ 00e K
+ 00f L
+ 010 M
+ 011 N
+ 012 O
+ 013 P
+ 014 Q
+ 015 R
+ 016 S
+ 017 T
+ 018 U
+ 019 V
+ 01a W
+ 01b X
+ 01c Y
+ 01d Z
+ 01e 1 and ! (One and Exclamation)
+ 01f 2 and @ (2 and at)
+ 020 3 and # (3 and Hash)
+ 021 4 and $ (4 and Dollar Sign)
+ 022 5 and % (5 and Percent Sign)
+ 023 6 and ^ (6 and circumflex)
+ 024 7 and & (Seven and Ampersand)
+ 025 8 and * (Eight and asterisk)
+ 026 9 and ( (Nine and Parenthesis Left)
+ 027 0 and ) (Zero and Parenthesis Right)
+ 028 Return (Enter)
+ 029 Escape
+ 02a Delete (Backspace)
+ 02b Tab
+ 02c Space Bar
+ 02d - and _ (Minus and underscore)
+ 02e = and + (Equal and Plus)
+ 02f [ and { (Bracket and Braces Left)
+ 030 ] and } (Bracket and Braces Right)
+ 031 \ and | (Backslash and Bar)
+ 032 # and ~ (Hash and Tilde, Non-US Keyboard near right shift)
+ 033 ; and : (Semicolon and Colon)
+ 034 ´ and " (Accent Acute and Double Quotes)
+ 035 ` and ~ (Accent Grace and Tilde)
+ 036 , and < (Comma and Less)
+ 037 . and > (Period and Greater)
+ 038 / and ? (Slash and Question Mark)
+ 039 Caps Lock
+ 03a F1
+ 03b F2
+ 03c F3
+ 03d F4
+ 03e F5
+ 03f F6
+ 040 F7
+ 041 F8
+ 042 F9
+ 043 F10
+ 044 F11
+ 045 F12
+ 046 Print Screen
+ 047 Scroll Lock
+ 048 Pause
+ 049 Insert
+ 04a Home
+ 04b Page Up
+ 04c Delete Forward (without Changing Position)
+ 04d End
+ 04e Page Down
+ 04f Right Arrow
+ 050 Left Arrow
+ 051 Down Arrow
+ 052 Up Arrow
+ 053 Num Lock and Clear
+ 054 Keypad / (Division Sign)
+ 055 Keypad * (Multiplication Sign)
+ 056 Keypad - (Subtraction Sign)
+ 057 Keypad + (Addition Sign)
+ 058 Keypad Enter
+ 059 Keypad 1 and END
+ 05a Keypad 2 and Down Arrow
+ 05b Keypad 3 and Page Down
+ 05c Keypad 4 and Left Arrow
+ 05d Keypad 5 (Tactilei Raised)
+ 05f Keypad 6 and Right Arrow
+ 060 Keypad 7 and Home
+ 061 Keypad 8 and Up Arrow
+ 062 Keypad 8 and Page Up
+ 063 Keypad . (decimal delimiter) and Delete
+ 064 \ and | (Backslash and Bar, UK and Non-US Keyboard near left shift)
+ 065 Keyboard Application (Windows Key for Win95 or Compose)
+ 066 Power (not a key)
+ 067 Keypad = (Equal Sign)
+ 068 F13
+ 069 F14
+ 06a F15
+ 06b F16
+ 06c F17
+ 06d F18
+ 06e F19
+ 06f F20
+ 070 F21
+ 071 F22
+ 072 F23
+ 073 F24
+ 074 Execute
+ 075 Help
+ 076 Menu
+ 077 Select
+ 078 Stop
+ 079 Again
+ 07a Undo
+ 07b Cut
+ 07c Copy
+ 07d Paste
+ 07e Find
+ 07f Mute
+ 080 Volume Up
+ 081 Volume Down
+ 082 Locking Caps Lock
+ 083 Locking Num Lock
+ 084 Locking Scroll Lock
+ 085 Keypad Comma
+ 086 Keypad Equal Sign (AS/400)
+ 087 International 1 (PC98)
+ 088 International 2 (PC98)
+ 089 International 3 (PC98)
+ 08a International 4 (PC98)
+ 08b International 5 (PC98)
+ 08c International 6 (PC98)
+ 08d International 7 (Toggle Single/Double Byte Mode)
+ 08e International 8
+ 08f International 9
+ 090 LANG 1 (Hangul/English Toggle, Korea)
+ 091 LANG 2 (Hanja Conversion, Korea)
+ 092 LANG 3 (Katakana, Japan)
+ 093 LANG 4 (Hiragana, Japan)
+ 094 LANG 5 (Zenkaku/Hankaku, Japan)
+ 095 LANG 6
+ 096 LANG 7
+ 097 LANG 8
+ 098 LANG 9
+ 099 Alternate Erase
+ 09a SysReq/Attention
+ 09b Cancel
+ 09c Clear
+ 09d Prior
+ 09e Return
+ 09f Separator
+ 0a0 Out
+ 0a1 Open
+ 0a2 Clear/Again
+ 0a3 CrSel/Props
+ 0a4 ExSel
+ 0e0 Control Left
+ 0e1 Shift Left
+ 0e2 Alt Left
+ 0e3 GUI Left
+ 0e4 Control Right
+ 0e5 Shift Right
+ 0e6 Alt Rigth
+ 0e7 GUI Right
+HUT 08 LEDs
+ 000 Undefined
+ 001 NumLock
+ 002 CapsLock
+ 003 Scroll Lock
+ 004 Compose
+ 005 Kana
+ 006 Power
+ 007 Shift
+ 008 Do not disturb
+ 009 Mute
+ 00a Tone Enabke
+ 00b High Cut Filter
+ 00c Low Cut Filter
+ 00d Equalizer Enable
+ 00e Sound Field ON
+ 00f Surround On
+ 010 Repeat
+ 011 Stereo
+ 012 Sampling Rate Detect
+ 013 Spinning
+ 014 CAV
+ 015 CLV
+ 016 Recording Format Detect
+ 017 Off-Hook
+ 018 Ring
+ 019 Message Waiting
+ 01a Data Mode
+ 01b Battery Operation
+ 01c Battery OK
+ 01d Battery Low
+ 01e Speaker
+ 01f Head Set
+ 020 Hold
+ 021 Microphone
+ 022 Coverage
+ 023 Night Mode
+ 024 Send Calls
+ 025 Call Pickup
+ 026 Conference
+ 027 Stand-by
+ 028 Camera On
+ 029 Camera Off
+ 02a On-Line
+ 02b Off-Line
+ 02c Busy
+ 02d Ready
+ 02e Paper-Out
+ 02f Paper-Jam
+ 030 Remote
+ 031 Forward
+ 032 Reverse
+ 033 Stop
+ 034 Rewind
+ 035 Fast Forward
+ 036 Play
+ 037 Pause
+ 038 Record
+ 039 Error
+ 03a Usage Selected Indicator
+ 03b Usage In Use Indicator
+ 03c Usage Multi Indicator
+ 03d Indicator On
+ 03e Indicator Flash
+ 03f Indicator Slow Blink
+ 040 Indicator Fast Blink
+ 041 Indicator Off
+ 042 Flash On Time
+ 043 Slow Blink On Time
+ 044 Slow Blink Off Time
+ 045 Fast Blink On Time
+ 046 Fast Blink Off Time
+ 047 Usage Color Indicator
+ 048 Indicator Red
+ 049 Indicator Green
+ 04a Indicator Amber
+ 04b Generic Indicator
+ 04c System Suspend
+ 04d External Power Connected
+HUT 09 Buttons
+ 000 No Button Pressed
+ 001 Button 1 (Primary)
+ 002 Button 2 (Secondary)
+ 003 Button 3 (Tertiary)
+ 004 Button 4
+ 005 Button 5
+HUT 0a Ordinal
+ 001 Instance 1
+ 002 Instance 2
+ 003 Instance 3
+HUT 0b Telephony
+ 000 Unassigned
+ 001 Phone
+ 002 Answering Machine
+ 003 Message Controls
+ 004 Handset
+ 005 Headset
+ 006 Telephony Key Pad
+ 007 Programmable Button
+ 020 Hook Switch
+ 021 Flash
+ 022 Feature
+ 023 Hold
+ 024 Redial
+ 025 Transfer
+ 026 Drop
+ 027 Park
+ 028 Forward Calls
+ 029 Alternate Function
+ 02a Line
+ 02b Speaker Phone
+ 02c Conference
+ 02d Ring Enable
+ 02e Ring Select
+ 02f Phone Mute
+ 030 Caller ID
+ 050 Speed Dial
+ 051 Store Number
+ 052 Recall Number
+ 053 Phone Directory
+ 070 Voice Mail
+ 071 Screen Calls
+ 072 Do Not Disturb
+ 073 Message
+ 074 Answer On/Offf
+ 090 Inside Dial Tone
+ 091 Outside Dial Tone
+ 092 Inside Ring Tone
+ 093 Outside Ring Tone
+ 094 Priority Ring Tone
+ 095 Inside Ringback
+ 096 Priority Ringback
+ 097 Line Busy Tone
+ 098 Recorder Tone
+ 099 Call Waiting Tone
+ 09a Confirmation Tone 1
+ 09b Confirmation Tone 2
+ 09c Tones Off
+ 09d Outside Ringback
+ 0b0 Key 1
+ 0b1 Key 2
+ 0b3 Key 3
+ 0b4 Key 4
+ 0b5 Key 5
+ 0b6 Key 6
+ 0b7 Key 7
+ 0b8 Key 8
+ 0b9 Key 9
+ 0ba Key Star
+ 0bb Key Pound
+ 0bc Key A
+ 0bd Key B
+ 0be Key C
+ 0bf Key D
+HUT 0c Consumer
+ 000 Unassigned
+ 001 Consumer Control
+ 002 Numeric Ky Pad
+ 003 Programmable Buttons
+ 020 +10
+ 021 +100
+ 022 AM/PM
+ 030 Power
+ 031 Reset
+ 032 Sleep
+ 033 Sleep After
+ 034 Sleep Mode
+ 035 Illumination
+ 036 Funtion Buttons
+ 040 Menu
+ 041 Menu Pick
+ 042 Menu Up
+ 043 Menu Down
+ 044 Menu Left
+ 045 Menu Right
+ 046 Menu Escape
+ 047 Menu Value Increase
+ 048 Menu Value Decrease
+ 060 Data on Screen
+ 061 Closed Caption
+ 062 Closed Caption Select
+ 063 VCR/TV
+ 064 Broadcast Mode
+ 065 SNapshot
+ 066 Still
+ 080 Selection
+ 081 Assign Selection
+ 082 Mode Step
+ 083 Recall Last
+ 084 Enter Channel
+ 085 Order Movie
+ 086 Channel
+ 087 Media Selection
+ 088 Media Select Computer
+ 089 Media Select TV
+ 08a Media Select WWW
+ 08b Media Select DVD
+ 08c Media Select Telephone
+ 08d Media Select Program Guide
+ 08e Media Select Video Phone
+ 08f Media Select Games
+ 090 Media Select Messages
+ 091 Media Select CD
+ 092 Media Select VCR
+ 093 Media Select Tuner
+ 094 Quit
+ 095 Help
+ 096 Media Select Tape
+ 097 Media Select Cable
+ 098 Media Select Satellite
+ 099 Media Select Security
+ 09a Media Select Home
+ 09b Media Select Call
+ 09c Channel Increment
+ 09d Channel Decrement
+ 09e Media Select SAP
+ 0a0 VCR Plus
+ 0a1 Once
+ 0a2 Daily
+ 0a3 Weekly
+ 0a4 Monthly
+ 0b0 Play
+ 0b1 Pause
+ 0b2 Record
+ 0b3 Fast Forward
+ 0b4 Rewind
+ 0b5 Scan Next Track
+ 0b6 Scan Previous Track
+ 0b7 Stop
+ 0b8 Eject
+ 0b9 Random Play
+ 0ba Select Disc
+ 0bb Enter Disc
+ 0bc Repeat
+ 0bd Tracking
+ 0be Track Normal
+ 0bf Slow Tracking
+ 0c0 Frame Forward
+ 0c1 Frame Back
+ 0c2 Mark
+ 0c3 Clear Mark
+ 0c4 Repeat from Mark
+ 0c5 Return to Mark
+ 0c6 Search Mark Forward
+ 0c7 Search Mark Backward
+ 0c8 Counter Reset
+ 0c9 Show Counter
+ 0ca Tracking Increment
+ 0cb Tracking Decrement
+ 0cc Stop/Eject
+ 0cd Play/Pause
+ 0ce Play/Skip
+ 0e0 Volume
+ 0e1 Balance
+ 0e2 Mute
+ 0e3 Bass
+ 0e4 Treble
+ 0e5 Bass Boost
+ 0e6 Surround Mode
+ 0e7 Loudness
+ 0e8 MPX
+ 0e9 Volume Increment
+ 0ea Volume Decrement
+ 0f0 Speed Select
+ 0f1 Playback Speed
+ 0f2 Standard Play
+ 0f3 Long Play
+ 0f4 Extended Play
+ 0f5 Slow
+ 100 Fan Enable
+ 101 Fan Speed
+ 102 Light Enable
+ 103 Light Illumination Level
+ 104 Climate Control Enable
+ 105 Room Temperature
+ 106 Security Enable
+ 107 Fire Alarm
+ 108 Police Alarm
+ 150 Balance Right
+ 151 Balance Left
+ 152 Bass Increment
+ 153 Bass Decrement
+ 154 Treble Increment
+ 155 Treble Decrement
+ 160 Speaker System
+ 161 Channel Left
+ 162 Channel Right
+ 163 Channel Center
+ 164 Channel Front
+ 165 Channel Center Front
+ 166 Channel Side
+ 167 Channel Surround
+ 168 Channel Low Frequency Enhancement
+ 169 Channel Top
+ 16a Channel Unknown
+ 170 Sub-Channel
+ 171 Sub-Channel Increment
+ 172 Sub-Channel Decrement
+ 173 Alternative Audio Increment
+ 174 Alternative Audio Decrement
+ 180 Application Launch Buttons
+ 181 AL Launch Button Configuration Tool
+ 182 AL Launch Button Configuration
+ 183 AL Consumer Control Configuration
+ 184 AL Word Processor
+ 185 AL Text Editor
+ 186 AL Spreadsheet
+ 187 AL Graphics Editor
+ 188 AL Presentation App
+ 189 AL Database App
+ 18a AL Email Reader
+ 18b AL Newsreader
+ 18c AL Voicemail
+ 18d AL Contacts/Address Book
+ 18e AL Calendar/Schedule
+ 18f AL Task/Project Manager
+ 190 AL Log/Jounal/Timecard
+ 191 AL Checkbook/Finance
+ 192 AL Calculator
+ 193 AL A/V Capture/Playback
+ 194 AL Local Machine Browser
+ 195 AL LAN/Wan Browser
+ 196 AL Internet Browser
+ 197 AL Remote Networking/ISP Connect
+ 198 AL Network Conference
+ 199 AL Network Chat
+ 19a AL Telephony/Dialer
+ 19b AL Logon
+ 19c AL Logoff
+ 19d AL Logon/Logoff
+ 19e AL Terminal Local/Screensaver
+ 19f AL Control Panel
+ 1a0 AL Command Line Processor/Run
+ 1a1 AL Process/Task Manager
+ 1a2 AL Select Task/Application
+ 1a3 AL Next Task/Application
+ 1a4 AL Previous Task/Application
+ 1a5 AL Preemptive Halt Task/Application
+ 200 Generic GUI Application Controls
+ 201 AC New
+ 202 AC Open
+ 203 AC CLose
+ 204 AC Exit
+ 205 AC Maximize
+ 206 AC Minimize
+ 207 AC Save
+ 208 AC Print
+ 209 AC Properties
+ 21a AC Undo
+ 21b AC Copy
+ 21c AC Cut
+ 21d AC Paste
+ 21e AC Select All
+ 21f AC Find
+ 220 AC Find and Replace
+ 221 AC Search
+ 222 AC Go To
+ 223 AC Home
+ 224 AC Back
+ 225 AC Forward
+ 226 AC Stop
+ 227 AC Refresh
+ 228 AC Previous Link
+ 229 AC Next Link
+ 22b AC History
+ 22c AC Subscriptions
+ 22d AC Zoom In
+ 22e AC Zoom Out
+ 22f AC Zoom
+ 230 AC Full Screen View
+ 231 AC Normal View
+ 232 AC View Toggle
+ 233 AC Scroll Up
+ 234 AC Scroll Down
+ 235 AC Scroll
+ 236 AC Pan Left
+ 237 AC Pan Right
+ 238 AC Pan
+ 239 AC New Window
+ 23a AC Tile Horizontally
+ 23b AC Tile Vertically
+ 23c AC Format
+HUT 0d Digitizer
+ 000 Undefined
+ 001 Digitizer
+ 002 Pen
+ 003 Light Pen
+ 004 Touch Screen
+ 005 Touch Pad
+ 006 White Board
+ 007 Coordinate Measuring Machine
+ 008 3D Digitizer
+ 009 Stereo Plotter
+ 00a Articulated Arm
+ 00b Armature
+ 00c Multiple Point Digitizer
+ 00d Free Space Wand
+ 020 Stylus
+ 021 Puck
+ 022 Finger
+ 030 Tip Pressure
+ 031 Barrel Pressure
+ 032 In Range
+ 033 Touch
+ 034 Untouch
+ 035 Tap
+ 036 Quality
+ 037 Data Valid
+ 038 Transducer Index
+ 039 Tablet Function Keys
+ 03a Program Change Keys
+ 03b Battery Strength
+ 03c Invert
+ 03d X Tilt
+ 03e Y Tilt
+ 03f Azimuth
+ 040 Altitude
+ 041 Twist
+ 042 Tip Switch
+ 043 Secondary Tip Switch
+ 044 Barrel Switch
+ 045 Eraser
+ 046 Tablet Pick
+HUT 0f PID Page
+ 000 Undefined
+ 001 Physical Interface Device
+ 020 Normal
+ 021 Set Effect Report
+ 022 Effect Block Index
+ 023 Parameter Block Offset
+ 024 ROM Flag
+ 025 Effect Type
+ 026 ET Constant Force
+ 027 ET Ramp
+ 028 ET Custom Force Data
+ 030 ET Square
+ 031 ET Sine
+ 032 ET Triangle
+ 033 ET Sawtooth Up
+ 034 ET Sawtooth Down
+ 040 ET Spring
+ 041 ET Damper
+ 042 ET Inertia
+ 043 ET Friction
+ 050 Duration
+ 051 Sample Period
+ 052 Gain
+ 053 Trigger Button
+ 054 Trigger Repeat Interval
+ 055 Axes Enable
+ 056 Direction Enable
+ 057 Direction
+ 058 Type Specific Block Offset
+ 059 Block Type
+ 05A Set Envelope Report
+ 05B Attack Level
+ 05C Attack Time
+ 05D Fade Level
+ 05E Fade Time
+ 05F Set Condition Report
+ 060 CP Offset
+ 061 Positive Coefficient
+ 062 Negative Coefficient
+ 063 Positive Saturation
+ 064 Negative Saturation
+ 065 Dead Band
+ 066 Download Force Sample
+ 067 Isoch Custom Force Enable
+ 068 Custom Force Data Report
+ 069 Custom Force Data
+ 06A Custom Force Vendor Defined Data
+ 06B Set Custom Force Report
+ 06C Custom Force Data Offset
+ 06D Sample Count
+ 06E Set Periodic Report
+ 06F Offset
+ 070 Magnitude
+ 071 Phase
+ 072 Period
+ 073 Set Constant Force Report
+ 074 Set Ramp Force Report
+ 075 Ramp Start
+ 076 Ramp End
+ 077 Effect Operation Report
+ 078 Effect Operation
+ 079 Op Effect Start
+ 07A Op Effect Start Solo
+ 07B Op Effect Stop
+ 07C Loop Count
+ 07D Device Gain Report
+ 07E Device Gain
+ 07F PID Pool Report
+ 080 RAM Pool Size
+ 081 ROM Pool Size
+ 082 ROM Effect Block Count
+ 083 Simultaneous Effects Max
+ 084 Pool Alignment
+ 085 PID Pool Move Report
+ 086 Move Source
+ 087 Move Destination
+ 088 Move Length
+ 089 PID Block Load Report
+ 08B Block Load Status
+ 08C Block Load Success
+ 08D Block Load Full
+ 08E Block Load Error
+ 08F Block Handle
+ 090 PID Block Free Report
+ 091 Type Specific Block Handle
+ 092 PID State Report
+ 094 Effect Playing
+ 095 PID Device Control Report
+ 096 PID Device Control
+ 097 DC Enable Actuators
+ 098 DC Disable Actuators
+ 099 DC Stop All Effects
+ 09A DC Device Reset
+ 09B DC Device Pause
+ 09C DC Device Continue
+ 09F Device Paused
+ 0A0 Actuators Enabled
+ 0A4 Safety Switch
+ 0A5 Actuator Override Switch
+ 0A6 Actuator Power
+ 0A7 Start Delay
+ 0A8 Parameter Block Size
+ 0A9 Device Managed Pool
+ 0AA Shared Parameter Blocks
+ 0AB Create New Effect Report
+ 0AC RAM Pool Available
+HUT 10 Unicode
+HUT 14 Alphanumeric Display
+ 000 Undefined
+ 001 Alphanumeric Display
+ 020 Display Attributes Report
+ 021 ASCII Character Set
+ 022 Data Read Back
+ 023 Font Read Back
+ 024 Display Control Report
+ 025 Clear Display
+ 026 Display Enable
+ 027 Screen Saver Delay
+ 028 Screen Saver Enable
+ 029 Vertical Scroll
+ 02a Horizontal Scroll
+ 02b Character Report
+ 02c Display Data
+ 02d Display Status
+ 02e Stat Not Ready
+ 02f Stat Ready
+ 030 Err Not a loadable Character
+ 031 Err Font Data Cannot Be Read
+ 032 Cursur Position Report
+ 033 Row
+ 034 Column
+ 035 Rows
+ 036 Columns
+ 037 Cursor Pixel Positioning
+ 038 Cursor Mode
+ 039 Cursor Enable
+ 03a Cursor Blink
+ 03b Font Report
+ 03c Font Data
+ 03d Character Width
+ 03e Character Height
+ 03f Character Spacing Horizontal
+ 040 Character Spacing Vertical
+ 041 Unicode Character Set
+HUT 80 USB Monitor
+ 001 Monitor Control
+ 002 EDID Information
+ 003 VDIF Information
+ 004 VESA Version
+HUT 81 USB Monitor Enumerated Values
+HUT 82 Monitor VESA Virtual Controls
+ 001 Degauss
+ 010 Brightness
+ 012 Contrast
+ 016 Red Video Gain
+ 018 Green Video Gain
+ 01a Blue Video Gain
+ 01c Focus
+ 020 Horizontal Position
+ 022 Horizontal Size
+ 024 Horizontal Pincushion
+ 026 Horizontal Pincushion Balance
+ 028 Horizontal Misconvergence
+ 02a Horizontal Linearity
+ 02c Horizontal Linearity Balance
+ 030 Vertical Position
+ 032 Vertical Size
+ 034 Vertical Pincushion
+ 036 Vertical Pincushion Balance
+ 038 Vertical Misconvergence
+ 03a Vertical Linearity
+ 03c Vertical Linearity Balance
+ 040 Parallelogram Balance (Key Distortion)
+ 042 Trapezoidal Distortion (Key)
+ 044 Tilt (Rotation)
+ 046 Top Corner Distortion Control
+ 048 Top Corner Distortion Balance
+ 04a Bottom Corner Distortion Control
+ 04c Bottom Corner Distortion Balance
+ 056 Horizontal Moire
+ 058 Vertical Moire
+ 05e Input Level Select
+ 060 Input Source Select
+ 06c Red Video Black Level
+ 06e Green Video Black Level
+ 070 Blue Video Black Level
+ 0a2 Auto Size Center
+ 0a4 Polarity Horizontal Sychronization
+ 0a6 Polarity Vertical Synchronization
+ 0aa Screen Orientation
+ 0ac Horizontal Frequency in Hz
+ 0ae Vertical Frequency in 0.1 Hz
+ 0b0 Settings
+ 0ca On Screen Display (OSD)
+ 0d4 Stereo Mode
+HUT 84 Power Device Page
+ 000 Undefined
+ 001 iName
+ 002 Present Status
+ 003 Changed Status
+ 004 UPS
+ 005 Power Supply
+ 010 Battery System
+ 011 Battery System ID
+ 012 Battery
+ 013 Battery ID
+ 014 Charger
+ 015 Charger ID
+ 016 Power Converter
+ 017 Power Converter ID
+ 018 Outlet System
+ 019 Outlet System ID
+ 01a Input
+ 01b Input ID
+ 01c Output
+ 01d Output ID
+ 01e Flow
+ 01f Flow ID
+ 020 Outlet
+ 021 Outlet ID
+ 022 Gang
+ 023 Gang ID
+ 024 Power Summary
+ 025 Power Summary ID
+ 030 Voltage
+ 031 Current
+ 032 Frequency
+ 033 Apparent Power
+ 034 Active Power
+ 035 Percent Load
+ 036 Temperature
+ 037 Humidity
+ 038 Bad Count
+ 040 Config Voltage
+ 041 Config Current
+ 042 Config Frequency
+ 043 Config Apparent Power
+ 044 Config Active Power
+ 045 Config Percent Load
+ 046 Config Temperature
+ 047 Config Humidity
+ 050 Switch On Control
+ 051 Switch Off Control
+ 052 Toggle Control
+ 053 Low Voltage Transfer
+ 054 High Voltage Transfer
+ 055 Delay Before Reboot
+ 056 Delay Before Startup
+ 057 Delay Before Shutdown
+ 058 Test
+ 059 Module Reset
+ 05a Audible Alarm Control
+ 060 Present
+ 061 Good
+ 062 Internal Failure
+ 063 Voltage out of range
+ 064 Frequency out of range
+ 065 Overload
+ 066 Over Charged
+ 067 Over Temperature
+ 068 Shutdown Requested
+ 069 Shutdown Imminent
+ 06a Reserved
+ 06b Switch On/Off
+ 06c Switchable
+ 06d Used
+ 06e Boost
+ 06f Buck
+ 070 Initialized
+ 071 Tested
+ 072 Awaiting Power
+ 073 Communication Lost
+ 0fd iManufacturer
+ 0fe iProduct
+ 0ff iSerialNumber
+HUT 85 Battery System Page
+ 000 Undefined
+ 001 SMB Battery Mode
+ 002 SMB Battery Status
+ 003 SMB Alarm Warning
+ 004 SMB Charger Mode
+ 005 SMB Charger Status
+ 006 SMB Charger Spec Info
+ 007 SMB Selector State
+ 008 SMB Selector Presets
+ 009 SMB Selector Info
+ 010 Optional Mfg. Function 1
+ 011 Optional Mfg. Function 2
+ 012 Optional Mfg. Function 3
+ 013 Optional Mfg. Function 4
+ 014 Optional Mfg. Function 5
+ 015 Connection to SMBus
+ 016 Output Connection
+ 017 Charger Connection
+ 018 Battery Insertion
+ 019 Use Next
+ 01a OK to use
+ 01b Battery Supported
+ 01c SelectorRevision
+ 01d Charging Indicator
+ 028 Manufacturer Access
+ 029 Remaining Capacity Limit
+ 02a Remaining Time Limit
+ 02b At Rate
+ 02c Capacity Mode
+ 02d Broadcast To Charger
+ 02e Primary Battery
+ 02f Charge Controller
+ 040 Terminate Charge
+ 041 Terminate Discharge
+ 042 Below Remaining Capacity Limit
+ 043 Remaining Time Limit Expired
+ 044 Charging
+ 045 Discharging
+ 046 Fully Charged
+ 047 Fully Discharged
+ 048 Conditioning Flag
+ 049 At Rate OK
+ 04a SMB Error Code
+ 04b Need Replacement
+ 060 At Rate Time To Full
+ 061 At Rate Time To Empty
+ 062 Average Current
+ 063 Max Error
+ 064 Relative State Of Charge
+ 065 Absolute State Of Charge
+ 066 Remaining Capacity
+ 067 Full Charge Capacity
+ 068 Run Time To Empty
+ 069 Average Time To Empty
+ 06a Average Time To Full
+ 06b Cycle Count
+ 080 Batt. Pack Model Level
+ 081 Internal Charge Controller
+ 082 Primary Battery Support
+ 083 Design Capacity
+ 084 Specification Info
+ 085 Manufacturer Date
+ 086 Serial Number
+ 087 iManufacturerName
+ 088 iDeviceName
+ 089 iDeviceChemistry
+ 08a Manufacturer Data
+ 08b Rechargeable
+ 08c Warning Capacity Limit
+ 08d Capacity Granularity 1
+ 08e Capacity Granularity 2
+ 08f iOEMInformation
+ 0c0 Inhibit Charge
+ 0c1 Enable Polling
+ 0c2 Reset To Zero
+ 0d0 AC Present
+ 0d1 Battery Present
+ 0d2 Power Fail
+ 0d3 Alarm Inhibited
+ 0d4 Thermistor Under Range
+ 0d5 Thermistor Hot
+ 0d6 Thermistor Cold
+ 0d7 Thermistor Over Range
+ 0d8 Voltage Out Of Range
+ 0d9 Current Out Of Range
+ 0da Current Not Regulated
+ 0db Voltage Not Regulated
+ 0dc Master Mode
+ 0f0 Charger Selector Support
+ 0f1 Charger Spec
+ 0f2 Level 2
+ 0f3 Level 3
+HUT 86 Power Pages
+HUT 87 Power Pages
+HUT 8c Bar Code Scanner Page (POS)
+HUT 8d Scale Page (POS)
+HUT 90 Camera Control Page
+HUT 91 Arcade Control Page
+HUT f0 Cash Device
+ 0f1 Cash Drawer
+ 0f2 Cash Drawer Number
+ 0f3 Cash Drawer Set
+ 0f4 Cash Drawer Status
+HUT ff Vendor Specific
+
+# List of Languages
+
+# Syntax:
+# L language_id language_name
+# dialect_id dialect_name
+
+L 0001 Arabic
+ 01 Saudi Arabia
+ 02 Iraq
+ 03 Egypt
+ 04 Libya
+ 05 Algeria
+ 06 Morocco
+ 07 Tunesia
+ 08 Oman
+ 09 Yemen
+ 0a Syria
+ 0b Jordan
+ 0c Lebanon
+ 0d Kuwait
+ 0e U.A.E
+ 0f Bahrain
+ 10 Qatar
+L 0002 Bulgarian
+L 0003 Catalan
+L 0004 Chinese
+ 01 Traditional
+ 02 Simplified
+ 03 Hongkong SAR, PRC
+ 04 Singapore
+ 05 Macau SAR
+L 0005 Czech
+L 0006 Danish
+L 0007 German
+ 01 German
+ 02 Swiss
+ 03 Austrian
+ 04 Luxembourg
+ 05 Liechtenstein
+L 0008 Greek
+L 0009 English
+ 01 US
+ 02 UK
+ 03 Australian
+ 04 Canadian
+ 05 New Zealand
+ 06 Ireland
+ 07 South Africa
+ 08 Jamaica
+ 09 Carribean
+ 0a Belize
+ 0b Trinidad
+ 0c Zimbabwe
+ 0d Philippines
+L 000a Spanish
+ 01 Castilian
+ 02 Mexican
+ 03 Modern
+ 04 Guatemala
+ 05 Costa Rica
+ 06 Panama
+ 07 Dominican Republic
+ 08 Venzuela
+ 09 Colombia
+ 0a Peru
+ 0b Argentina
+ 0c Ecuador
+ 0d Chile
+ 0e Uruguay
+ 0f Paraguay
+ 10 Bolivia
+ 11 El Salvador
+ 12 Honduras
+ 13 Nicaragua
+ 14 Puerto Rico
+L 000b Finnish
+L 000c French
+ 01 French
+ 02 Belgian
+ 03 Canadian
+ 04 Swiss
+ 05 Luxembourg
+ 06 Monaco
+L 000d Hebrew
+L 000e Hungarian
+L 000f Idelandic
+L 0010 Italian
+ 01 Italian
+ 02 Swiss
+L 0011 Japanese
+L 0012 Korean
+ 01 Korean
+L 0013 Dutch
+ 01 Dutch
+ 02 Belgian
+L 0014 Norwegian
+ 01 Bokmal
+ 02 Nynorsk
+L 0015 Polish
+L 0016 Portuguese
+ 01 Portuguese
+ 02 Brazilian
+L 0017 forgotten
+L 0018 Romanian
+L 0019 Russian
+L 001a Serbian
+ 01 Croatian
+ 02 Latin
+ 03 Cyrillic
+L 001b Slovak
+L 001c Albanian
+L 001d Swedish
+ 01 Swedish
+ 02 Finland
+L 001e Thai
+L 001f Turkish
+L 0020 Urdu
+ 01 Pakistan
+ 02 India
+L 0021 Indonesian
+L 0022 Ukrainian
+L 0023 Belarusian
+L 0024 Slovenian
+L 0025 Estonian
+L 0026 Latvian
+L 0027 Lithuanian
+ 01 Lithuanian
+L 0028 forgotten
+L 0029 Farsi
+L 002a Vietnamese
+L 002b Armenian
+L 002c Azeri
+ 01 Cyrillic
+ 02 Latin
+L 002d Basque
+L 002e forgotten
+L 002f Macedonian
+L 0036 Afrikaans
+L 0037 Georgian
+L 0038 Faeroese
+L 0039 Hindi
+L 003e Malay
+ 01 Malaysia
+ 02 Brunei Darassalam
+L 003f Kazak
+L 0041 Awahili
+L 0043 Uzbek
+ 01 Latin
+ 02 Cyrillic
+L 0044 Tatar
+L 0045 Bengali
+L 0046 Punjabi
+L 0047 Gujarati
+L 0048 Oriya
+L 0049 Tamil
+L 004a Telugu
+L 004b Kannada
+L 004c Malayalam
+L 004d Assamese
+L 004e Marathi
+L 004f Sanskrit
+L 0057 Konkani
+L 0058 Manipuri
+L 0059 Sindhi
+L 0060 Kashmiri
+ 02 India
+L 0061 Nepali
+ 02 India
+
+# HID Descriptor bCountryCode
+# HID Specification 1.11 (2001-06-27) page 23
+#
+# Syntax:
+# HCC country_code keymap_type
+
+HCC 00 Not supported
+HCC 01 Arabic
+HCC 02 Belgian
+HCC 03 Canadian-Bilingual
+HCC 04 Canadian-French
+HCC 05 Czech Republic
+HCC 06 Danish
+HCC 07 Finnish
+HCC 08 French
+HCC 09 German
+HCC 10 Greek
+HCC 11 Hebrew
+HCC 12 Hungary
+HCC 13 International (ISO)
+HCC 14 Italian
+HCC 15 Japan (Katakana)
+HCC 16 Korean
+HCC 17 Latin American
+HCC 18 Netherlands/Dutch
+HCC 19 Norwegian
+HCC 20 Persian (Farsi)
+HCC 21 Poland
+HCC 22 Portuguese
+HCC 23 Russia
+HCC 24 Slovakia
+HCC 25 Spanish
+HCC 26 Swedish
+HCC 27 Swiss/French
+HCC 28 Swiss/German
+HCC 29 Switzerland
+HCC 30 Taiwan
+HCC 31 Turkish-Q
+HCC 32 UK
+HCC 33 US
+HCC 34 Yugoslavia
+HCC 35 Turkish-F
+
+# List of Video Class Terminal Types
+
+# Syntax:
+# VT terminal_type terminal_type_name
+
+VT 0100 USB Vendor Specific
+VT 0101 USB Streaming
+VT 0200 Input Vendor Specific
+VT 0201 Camera Sensor
+VT 0202 Sequential Media
+VT 0300 Output Vendor Specific
+VT 0301 Generic Display
+VT 0302 Sequential Media
+VT 0400 External Vendor Specific
+VT 0401 Composite Video
+VT 0402 S-Video
+VT 0403 Component Video
+
diff --git a/usr/src/cmd/initpkg/init.d/Makefile b/usr/src/cmd/initpkg/init.d/Makefile
index 1f9e90d9b8..e7b847ddbb 100644
--- a/usr/src/cmd/initpkg/init.d/Makefile
+++ b/usr/src/cmd/initpkg/init.d/Makefile
@@ -50,7 +50,6 @@ PROG= \
slpd \
sysetup \
uucp \
- volmgt \
$($(MACH)_PROG)
diff --git a/usr/src/cmd/login/logindevperm.sh b/usr/src/cmd/login/logindevperm.sh
index 3c3e7ff25e..e8decd3a3f 100644
--- a/usr/src/cmd/login/logindevperm.sh
+++ b/usr/src/cmd/login/logindevperm.sh
@@ -62,6 +62,10 @@ cat <<EOM
/dev/console 0600 /dev/sound/* # audio devices
/dev/console 0600 /dev/fbs/* # frame buffers
/dev/console 0600 /dev/dri/* # dri devices
+/dev/console 0400 /dev/removable-media/dsk/* # removable media
+/dev/console 0400 /dev/removable-media/rdsk/* # removable media
+/dev/console 0400 /dev/hotpluggable/dsk/* # hotpluggable storage
+/dev/console 0400 /dev/hotpluggable/rdsk/* # hotpluggable storage
EOM
case "$MACH" in
diff --git a/usr/src/cmd/pgrep/pgrep.c b/usr/src/cmd/pgrep/pgrep.c
index ae3eaa0e42..a8371dd6d8 100644
--- a/usr/src/cmd/pgrep/pgrep.c
+++ b/usr/src/cmd/pgrep/pgrep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,7 +87,6 @@ static int opt_projid(char, char *);
static int opt_taskid(char, char *);
static int opt_zoneid(char, char *);
static int opt_ctid(char, char *);
-static int opt_V(char, char *);
static const char *g_procdir = "/proc"; /* Default procfs mount point */
static const char *g_delim = "\n"; /* Default output delimiter */
@@ -117,7 +115,7 @@ static optdesc_t g_optdtab[] = {
{ 0, 0, 0, 0 }, /* 'S' */
{ OPT_FUNC | OPT_CRIT, 0, opt_taskid, 0 }, /* -T taskid */
{ OPT_FUNC | OPT_CRIT, 0, opt_uid, 0 }, /* -U uid */
- { OPT_FUNC | OPT_CRIT, 0, opt_V, 0 }, /* -V */
+ { 0, 0, 0, 0 }, /* 'V' */
{ 0, 0, 0, 0 }, /* 'W' */
{ 0, 0, 0, 0 }, /* 'X' */
{ 0, 0, 0, 0 }, /* 'Y' */
@@ -166,8 +164,8 @@ Usage: %s [-signal] [-fnovx] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\
[-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\
[-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n";
-static const char PGREP_OPTS[] = "flnovVxc:d:D:u:U:G:P:g:s:t:z:J:T:";
-static const char PKILL_OPTS[] = "fnovVxc:D:u:U:G:P:g:s:t:z:J:T:";
+static const char PGREP_OPTS[] = "flnovxc:d:D:u:U:G:P:g:s:t:z:J:T:";
+static const char PKILL_OPTS[] = "fnovxc:D:u:U:G:P:g:s:t:z:J:T:";
static const char LSEP[] = ",\t "; /* Argument list delimiter chars */
@@ -583,16 +581,6 @@ opt_ctid(char c, char *arg)
return (parse_ids(&g_psexp.ps_ctids, arg, 10, c, getctid()));
}
-/*ARGSUSED*/
-static int
-opt_V(char c, char *arg)
-{
- idtab_append(&g_psexp.ps_ruids, 0);
- g_flags |= F_EXACT_MATCH;
- g_psexp.ps_pat = "vold";
- return (0);
-}
-
static void
print_usage(FILE *stream)
{
diff --git a/usr/src/cmd/policykit/Makefile b/usr/src/cmd/policykit/Makefile
new file mode 100644
index 0000000000..c7fff81ed4
--- /dev/null
+++ b/usr/src/cmd/policykit/Makefile
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = polkit-is-privileged
+
+SRCS = $(PROG:%=%.c)
+
+include ../Makefile.cmd
+include $(SRC)/lib/policykit/Makefile.policykit
+
+LDLIBS += -lpolkit $(POLICYKIT_GLIB_LDLIBS)
+
+CPPFLAGS += -I$(ROOT)/usr/include/libpolkit
+CPPFLAGS += $(POLICYKIT_DBUS_CPPFLAGS) $(POLICYKIT_GLIB_CPPFLAGS)
+CPPFLAGS += -DPACKAGE_VERSION=\"$(POLICYKIT_VERSION)\"
+C99MODE = $(C99_ENABLE)
+
+ROOTUSRSBINPROG = $(PROG:%=$(ROOTUSRSBIN)/%)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+ $(RM) $(CLEANFILES)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/policykit/polkit-is-privileged.c b/usr/src/cmd/policykit/polkit-is-privileged.c
new file mode 100644
index 0000000000..85116cf3d0
--- /dev/null
+++ b/usr/src/cmd/policykit/polkit-is-privileged.c
@@ -0,0 +1,205 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * polkit-is-privileged.c : Determine if a user has privileges
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <dbus/dbus.h>
+
+#include <libpolkit/libpolkit.h>
+
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr, "polkit-is-privileged version " PACKAGE_VERSION "\n");
+
+ fprintf (stderr,
+ "\n"
+ "usage : %s -u <uid> -p <privilege> [-r <resource>]\n"
+ " [-s <system-bus-connection-name>]", argv[0]);
+ fprintf (stderr,
+ "\n"
+ "Options:\n"
+ " -u, --user Username or user id\n"
+ " -s, --system-bus-unique-name Unique system bus connection name\n"
+ " -r, --resource Resource\n"
+ " -p, --privilege Privilege to test for\n"
+ " -h, --help Show this information and exit\n"
+ " -v, --verbose Verbose operation\n"
+ " -V, --version Print version number\n"
+ "\n"
+ "Queries system policy whether a given user is allowed for a given\n"
+ "privilege for a given resource. The resource may be omitted.\n"
+ "\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ int rc;
+ char *user = NULL;
+ char *privilege = NULL;
+ char *resource = NULL;
+ char *system_bus_unique_name = NULL;
+ static const struct option long_options[] = {
+ {"user", required_argument, NULL, 'u'},
+ {"system-bus-unique-name", required_argument, NULL, 's'},
+ {"resource", required_argument, NULL, 'r'},
+ {"privilege", required_argument, NULL, 'p'},
+ {"help", no_argument, NULL, 'h'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"version", no_argument, NULL, 'V'},
+ {NULL, 0, NULL, 0}
+ };
+ LibPolKitContext *ctx = NULL;
+ gboolean is_allowed;
+ gboolean is_temporary;
+ LibPolKitResult result;
+ gboolean is_verbose = FALSE;
+ DBusError error;
+ DBusConnection *connection = NULL;
+
+ rc = 1;
+
+ while (TRUE) {
+ int c;
+
+ c = getopt_long (argc, argv, "u:r:p:s:hVv", long_options, NULL);
+
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 's':
+ system_bus_unique_name = g_strdup (optarg);
+ break;
+
+ case 'u':
+ user = g_strdup (optarg);
+ break;
+
+ case 'r':
+ resource = g_strdup (optarg);
+ break;
+
+ case 'p':
+ privilege = g_strdup (optarg);
+ break;
+
+ case 'v':
+ is_verbose = TRUE;
+ break;
+
+ case 'h':
+ usage (argc, argv);
+ rc = 0;
+ goto out;
+
+ case 'V':
+ printf ("polkit-is-privileged version " PACKAGE_VERSION "\n");
+ rc = 0;
+ goto out;
+
+ default:
+ usage (argc, argv);
+ goto out;
+ }
+ }
+
+ if (user == NULL || privilege == NULL) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ if (is_verbose) {
+ printf ("user = '%s'\n", user);
+ printf ("privilege = '%s'\n", privilege);
+ if (resource != NULL)
+ printf ("resource = '%s'\n", resource);
+ }
+
+#ifdef POLKITD_ENABLED
+ dbus_error_init (&error);
+ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (connection == NULL) {
+ g_warning ("Cannot connect to system message bus");
+ return 1;
+ }
+#endif /* POLKITD_ENABLED */
+
+ ctx = libpolkit_new_context (connection);
+ if (ctx == NULL) {
+ g_warning ("Cannot get libpolkit context");
+ goto out;
+ }
+
+ result = libpolkit_is_uid_allowed_for_privilege (ctx,
+ system_bus_unique_name,
+ user,
+ privilege,
+ resource,
+ &is_allowed,
+ &is_temporary,
+ NULL);
+ switch (result) {
+ case LIBPOLKIT_RESULT_OK:
+ rc = is_allowed ? 0 : 1;
+ break;
+
+ case LIBPOLKIT_RESULT_ERROR:
+ g_warning ("Error determing whether user is privileged.");
+ break;
+
+ case LIBPOLKIT_RESULT_INVALID_CONTEXT:
+ g_print ("Invalid context.\n");
+ goto out;
+
+ case LIBPOLKIT_RESULT_NOT_PRIVILEGED:
+ g_print ("Not privileged.\n");
+
+ case LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE:
+ g_print ("No such privilege '%s'.\n", privilege);
+ goto out;
+
+ case LIBPOLKIT_RESULT_NO_SUCH_USER:
+ g_print ("No such user '%s'.\n", user);
+ goto out;
+ }
+
+ if (is_verbose) {
+ printf ("result %d\n", result);
+ printf ("is_allowed %d\n", is_allowed);
+ }
+
+out:
+ if (ctx != NULL)
+ libpolkit_free_context (ctx);
+
+ return rc;
+}
+
diff --git a/usr/src/cmd/rmmount/Makefile b/usr/src/cmd/rmmount/Makefile
new file mode 100644
index 0000000000..a8affe358c
--- /dev/null
+++ b/usr/src/cmd/rmmount/Makefile
@@ -0,0 +1,71 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = rmmount
+LOCAL_OBJS = rmmount.o
+RMVOLMGR_OBJS = rmm_common.o vold.o
+OBJS = $(LOCAL_OBJS) $(RMVOLMGR_OBJS)
+LOCAL_SRCS = $(LOCAL_OBJS:%.o=%.c)
+RMVOLGMR_SRCS = $(RMVOLMGR_OBJS:%.o=$(SRC)/cmd/rmvolmgr/%.c)
+SRCS = $(LOCAL_SRCS) $(RMVOLMGR_SRCS)
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/hal/Makefile.hal
+
+LDLIBS += -ldbus-1 -ldbus-glib-1 -lglib-2.0 -lhal -lhal-storage -lcontract
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal
+CPPFLAGS += -I$(SRC)/cmd/rmvolmgr
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTPROG)
+ -$(RM) $(ROOT)/usr/bin/rmumount
+ -$(RM) $(ROOT)/usr/sbin/rmmount
+ -$(SYMLINK) ./rmmount $(ROOT)/usr/bin/rmumount
+ -$(SYMLINK) ../bin/rmmount $(ROOT)/usr/sbin/rmmount
+
+rmm_common.o: $(SRC)/cmd/rmvolmgr/rmm_common.c $(SRC)/cmd/rmvolmgr/rmm_common.h
+ $(COMPILE.c) -o $@ $(SRC)/cmd/rmvolmgr/rmm_common.c
+ $(POST_PROCESS_O)
+
+vold.o: $(SRC)/cmd/rmvolmgr/vold.c $(SRC)/cmd/rmvolmgr/vold.h
+ $(COMPILE.c) -o $@ $(SRC)/cmd/rmvolmgr/vold.c
+ $(POST_PROCESS_O)
+
+clean:
+ $(RM) $(OBJS)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/rmmount/rmmount.c b/usr/src/cmd/rmmount/rmmount.c
new file mode 100644
index 0000000000..d534f784fb
--- /dev/null
+++ b/usr/src/cmd/rmmount/rmmount.c
@@ -0,0 +1,274 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <errno.h>
+#include <sys/syscall.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libhal.h>
+
+#include <rmm_common.h>
+
+char *progname;
+
+static boolean_t d_opt, l_opt, o_opt, u_opt, eject_opt,
+ closetray_opt, query_opt;
+
+static void usage();
+static void nomem();
+
+static void
+usage()
+{
+ if (!u_opt) {
+ (void) fprintf(stderr,
+ "%s: [-dlu] [-o options] [nickname | device] "
+ "[mount_point]\n", progname);
+ } else {
+ (void) fprintf(stderr,
+ "%s: [-dl] [nickname | device]\n", progname);
+ }
+}
+
+static int
+rmmount(int argc, char **argv)
+{
+ int c;
+ action_t action;
+ LibHalContext *hal_ctx;
+ DBusError error;
+ rmm_error_t rmm_error;
+ LibHalDrive *d;
+ GSList *volumes;
+ const char *default_name;
+ char **opts = NULL;
+ int num_opts = 0;
+ char *mountpoint = NULL;
+ char **p;
+ int ret = 0;
+
+ progname = basename(argv[0]);
+
+ if (strcmp(progname, "rmumount") == 0) {
+ u_opt = B_TRUE;
+ }
+
+ if (getenv("RMMOUNT_DEBUG") != NULL) {
+ rmm_debug = 1;
+ }
+
+ while ((c = getopt(argc, argv, "?dlo:u")) != -1) {
+ switch (c) {
+ case 'd':
+ d_opt = B_TRUE;
+ break;
+ case 'l':
+ l_opt = B_TRUE;
+ break;
+ case 'o':
+ o_opt = B_TRUE;
+ if ((opts = g_strsplit(optarg, ",", 10)) == NULL) {
+ nomem();
+ }
+ for (num_opts = 0, p = &opts[0]; *p != NULL; p++) {
+ num_opts++;
+ }
+ break;
+ case 'u':
+ u_opt = B_TRUE;
+ break;
+ case '?':
+ usage();
+ return (0);
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ if (u_opt) {
+ action = UNMOUNT;
+ } else if (closetray_opt) {
+ action = CLOSETRAY;
+ } else if (eject_opt) {
+ action = EJECT;
+ } else {
+ action = INSERT;
+ }
+
+ if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) {
+ (void) fprintf(stderr, gettext("warning: %s\n"),
+ rmm_strerror(&error, rmm_error));
+ rmm_dbus_error_free(&error);
+ if ((rmm_error == RMM_EDBUS_CONNECT) ||
+ (rmm_error == RMM_EHAL_CONNECT)) {
+ return (99);
+ } else {
+ return (1);
+ }
+ }
+
+ if (d_opt) {
+ /* -d: print default name and exit */
+ if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
+ &default_name, &volumes)) == NULL) {
+ default_name = "nothing inserted";
+ } else {
+ rmm_volumes_free(volumes);
+ libhal_drive_free(d);
+ }
+ (void) printf(gettext("Default device is: %s\n"), default_name);
+ } else if (l_opt) {
+ /* -l: list volumes and exit */
+ rmm_print_volume_nicknames(hal_ctx, &error);
+ } else if (optind == argc) {
+ /* no name provided, use default */
+ if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
+ &default_name, &volumes)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("No default media available\n"));
+ ret = 1;
+ } else {
+ rmm_volumes_free(volumes);
+ libhal_drive_free(d);
+
+ if (query_opt) {
+ ret = rmm_rescan(hal_ctx, default_name,
+ B_TRUE) ? 0 : 1;
+ } else {
+ ret = rmm_action(hal_ctx, default_name, action,
+ 0, 0, 0, 0) ? 0 : 1;
+ }
+ }
+ } else {
+ if (argc - optind > 1) {
+ mountpoint = argv[optind + 1];
+ }
+ if (query_opt) {
+ ret = rmm_rescan(hal_ctx, argv[optind],
+ B_TRUE) ? 0 : 1;
+ } else {
+ ret = rmm_action(hal_ctx, argv[optind], action,
+ 0, opts, num_opts, mountpoint) ? 0 : 1;
+ }
+ }
+
+ rmm_dbus_error_free(&error);
+ rmm_hal_fini(hal_ctx);
+
+ return (ret);
+}
+
+static int
+rmumount(int argc, char **argv)
+{
+ return (rmmount(argc, argv));
+}
+
+static int
+eject(int argc, char **argv)
+{
+ if (getenv("EJECT_CLOSETRAY") != NULL) {
+ closetray_opt = B_TRUE;
+ } else if (getenv("EJECT_QUERY") != NULL) {
+ query_opt = B_TRUE;
+ } else {
+ eject_opt = B_TRUE;
+ }
+ return (rmmount(argc, argv));
+}
+
+static void
+nomem(void)
+{
+ (void) fprintf(stderr, gettext("%s: Out of memory\n"), progname);
+ exit(1);
+}
+
+
+/*
+ * get the name by which this program was called
+ */
+static char *
+get_progname(char *path)
+{
+ char *s;
+ char *p;
+
+ if ((s = strdup(path)) == NULL) {
+ perror(path);
+ exit(1);
+ }
+
+ p = strrchr(s, '/');
+ if (p != NULL) {
+ strcpy(s, p + 1);
+ }
+
+ return (s);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 1;
+
+ vold_init(argc, argv);
+
+ progname = get_progname(argv[0]);
+
+ if (strcmp(progname, "rmmount") == 0) {
+ if ((getenv("VOLUME_ACTION") != NULL) &&
+ (getenv("VOLUME_PATH") != NULL)) {
+ ret = vold_rmmount(argc, argv);
+ } else {
+ ret = rmmount(argc, argv);
+ }
+ } else if (strcmp(progname, "rmumount") == 0) {
+ ret = rmumount(argc, argv);
+ } else if (strcmp(progname, "eject") == 0) {
+ ret = eject(argc, argv);
+ } else {
+ (void) fprintf(stderr, "rmmount: invalid program name\n");
+ ret = 1;
+ }
+
+ return (ret);
+}
diff --git a/usr/src/cmd/rmvolmgr/Makefile b/usr/src/cmd/rmvolmgr/Makefile
new file mode 100644
index 0000000000..a4ffac4951
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/Makefile
@@ -0,0 +1,72 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = rmvolmgr
+OBJS = rmm_common.o rmvolmgr.o vold.o
+SRCS = $(OBJS:%.o=%.c)
+
+MANIFEST = rmvolmgr.xml
+SVCMETHOD = svc-rmvolmgr
+
+include ../Makefile.cmd
+include ../hal/Makefile.hal
+
+POFILE=rmvolmgr_all.po
+POFILES=$(OBJS:%.o=%.po)
+
+LDLIBS += -ldbus-1 -ldbus-glib-1 -lglib-2.0 -lhal -lhal-storage -lcontract -lscf
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal
+C99MODE = $(C99_ENABLE)
+
+ROOTCMDDIR = $(ROOTLIB)
+ROOTMANIFESTDIR = $(ROOTSVCSYSTEMFILESYSTEM)
+$(ROOTMANIFEST) := FILEMODE = 444
+$(ROOTLIBSVCMETHOD)/svc-rmvolmgr:= FILEMODE = 555
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD) $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+clean:
+ $(RM) $(OBJS)
+
+check: $(CHKMANIFEST)
+
+$(POFILE): $(POFILES)
+ $(RM) $@
+ $(CAT) $(POFILES) > $@
+
+include ../Makefile.targ
+
diff --git a/usr/src/cmd/rmvolmgr/rmm_common.c b/usr/src/cmd/rmvolmgr/rmm_common.c
new file mode 100644
index 0000000000..4859e8e2c2
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/rmm_common.c
@@ -0,0 +1,1355 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <libintl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mnttab.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libhal.h>
+#include <libhal-storage.h>
+
+#include "rmm_common.h"
+
+extern int rmm_debug;
+
+static const char *action_strings[] = {
+ "eject",
+ "mount",
+ "remount",
+ "unmount",
+ "clear_mounts",
+ "closetray"
+};
+
+
+LibHalContext *
+rmm_hal_init(LibHalDeviceAdded devadd_cb, LibHalDeviceRemoved devrem_cb,
+ LibHalDevicePropertyModified propmod_cb,
+ DBusError *error, rmm_error_t *rmm_error)
+{
+ DBusConnection *dbus_conn;
+ LibHalContext *ctx;
+ char **devices;
+ int nr;
+
+ dbus_error_init(error);
+
+ /*
+ * setup D-Bus connection
+ */
+ if (!(dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, error))) {
+ dprintf("cannot get system bus: %s\n", rmm_strerror(error, -1));
+ *rmm_error = RMM_EDBUS_CONNECT;
+ return (NULL);
+ }
+ rmm_dbus_error_free(error);
+
+ dbus_connection_setup_with_g_main(dbus_conn, NULL);
+ dbus_connection_set_exit_on_disconnect(dbus_conn, B_TRUE);
+
+ if ((ctx = libhal_ctx_new()) == NULL) {
+ dprintf("libhal_ctx_new failed");
+ *rmm_error = RMM_EHAL_CONNECT;
+ return (NULL);
+ }
+
+ libhal_ctx_set_dbus_connection(ctx, dbus_conn);
+
+ /*
+ * register callbacks
+ */
+ if (devadd_cb != NULL) {
+ libhal_ctx_set_device_added(ctx, devadd_cb);
+ }
+ if (devrem_cb != NULL) {
+ libhal_ctx_set_device_removed(ctx, devrem_cb);
+ }
+ if (propmod_cb != NULL) {
+ libhal_ctx_set_device_property_modified(ctx, propmod_cb);
+ if (!libhal_device_property_watch_all(ctx, error)) {
+ dprintf("property_watch_all failed %s",
+ rmm_strerror(error, -1));
+ libhal_ctx_free(ctx);
+ *rmm_error = RMM_EHAL_CONNECT;
+ return (NULL);
+ }
+ }
+
+ if (!libhal_ctx_init(ctx, error)) {
+ dprintf("libhal_ctx_init failed: %s", rmm_strerror(error, -1));
+ libhal_ctx_free(ctx);
+ *rmm_error = RMM_EHAL_CONNECT;
+ return (NULL);
+ }
+ rmm_dbus_error_free(error);
+
+ /*
+ * The above functions do not guarantee that HAL is actually running.
+ * Check by invoking a method.
+ */
+ if (!(devices = libhal_get_all_devices(ctx, &nr, error))) {
+ dprintf("HAL is not running: %s", rmm_strerror(error, -1));
+ libhal_ctx_shutdown(ctx, NULL);
+ libhal_ctx_free(ctx);
+ *rmm_error = RMM_EHAL_CONNECT;
+ return (NULL);
+ } else {
+ rmm_dbus_error_free(error);
+ libhal_free_string_array(devices);
+ }
+
+ return (ctx);
+}
+
+
+void
+rmm_hal_fini(LibHalContext *hal_ctx)
+{
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+
+ (void) dbus_connection_close(dbus_conn);
+ (void) libhal_ctx_free(hal_ctx);
+}
+
+
+/*
+ * find volume from any type of name, similar to the old media_findname()
+ * returns the LibHalDrive object and a list of LibHalVolume objects.
+ */
+LibHalDrive *
+rmm_hal_volume_find(LibHalContext *hal_ctx, const char *name, DBusError *error,
+ GSList **volumes)
+{
+ LibHalDrive *drive;
+ char *p;
+ char lastc;
+
+ *volumes = NULL;
+
+ /* temporarily remove trailing slash */
+ p = (char *)name + strlen(name) - 1;
+ if (*p == '/') {
+ lastc = *p;
+ *p = '\0';
+ } else {
+ p = NULL;
+ }
+
+ if (name[0] == '/') {
+ if (((drive = rmm_hal_volume_findby(hal_ctx,
+ "info.udi", name, volumes)) != NULL) ||
+ ((drive = rmm_hal_volume_findby(hal_ctx,
+ "block.device", name, volumes)) != NULL) ||
+ ((drive = rmm_hal_volume_findby(hal_ctx,
+ "block.solaris.raw_device", name, volumes)) != NULL) ||
+ ((drive = rmm_hal_volume_findby(hal_ctx,
+ "volume.mount_point", name, volumes)) != NULL)) {
+ goto out;
+ } else {
+ goto out;
+ }
+ }
+
+ /* try volume label */
+ if ((drive = rmm_hal_volume_findby(hal_ctx,
+ "volume.label", name, volumes)) != NULL) {
+ goto out;
+ }
+
+ drive = rmm_hal_volume_findby_nickname(hal_ctx, name, volumes);
+
+out:
+ if (p != NULL) {
+ *p = lastc;
+ }
+ return (drive);
+}
+
+/*
+ * find default volume. Returns volume pointer and name in 'name'.
+ */
+LibHalDrive *
+rmm_hal_volume_find_default(LibHalContext *hal_ctx, DBusError *error,
+ const char **name_out, GSList **volumes)
+{
+ LibHalDrive *drive;
+ static const char *names[] = { "floppy", "cdrom", "rmdisk" };
+ int i;
+
+ *volumes = NULL;
+
+ for (i = 0; i < NELEM(names); i++) {
+ if ((drive = rmm_hal_volume_findby_nickname(hal_ctx,
+ names[i], volumes)) != NULL) {
+ /*
+ * Skip floppy if it has no media.
+ * XXX might want to actually check for media
+ * every time instead of relying on volcheck.
+ */
+ if ((strcmp(names[i], "floppy") != 0) ||
+ libhal_device_get_property_bool(hal_ctx,
+ libhal_drive_get_udi(drive),
+ "storage.removable.media_available", NULL)) {
+ *name_out = names[i];
+ break;
+ }
+ }
+ rmm_dbus_error_free(error);
+ }
+
+ return (drive);
+}
+
+/*
+ * find volume by property=value
+ * returns the LibHalDrive object and a list of LibHalVolume objects.
+ * XXX add support for multiple properties, reduce D-Bus traffic
+ */
+LibHalDrive *
+rmm_hal_volume_findby(LibHalContext *hal_ctx, const char *property,
+ const char *value, GSList **volumes)
+{
+ DBusError error;
+ LibHalDrive *drive = NULL;
+ LibHalVolume *v = NULL;
+ char **udis;
+ int num_udis;
+ int i;
+
+ *volumes = NULL;
+
+ dbus_error_init(&error);
+
+ /* get all devices with property=value */
+ if ((udis = libhal_manager_find_device_string_match(hal_ctx, property,
+ value, &num_udis, &error)) == NULL) {
+ rmm_dbus_error_free(&error);
+ return (NULL);
+ }
+
+ /* find volumes among these devices */
+ for (i = 0; i < num_udis; i++) {
+ rmm_dbus_error_free(&error);
+ if (libhal_device_query_capability(hal_ctx, udis[i], "volume",
+ &error)) {
+ v = libhal_volume_from_udi(hal_ctx, udis[i]);
+ if (v != NULL) {
+ *volumes = g_slist_prepend(*volumes, v);
+ }
+ }
+ }
+
+ /* used prepend, preserve original order */
+ if (*volumes != NULL) {
+ *volumes = g_slist_reverse(*volumes);
+
+ v = (LibHalVolume *)(*volumes)->data;
+ drive = libhal_drive_from_udi(hal_ctx,
+ libhal_volume_get_storage_device_udi(v));
+ if (drive == NULL) {
+ rmm_volumes_free (*volumes);
+ *volumes = NULL;
+ }
+ }
+
+ libhal_free_string_array(udis);
+ rmm_dbus_error_free(&error);
+
+ return (drive);
+}
+
+
+/*
+ * print nicknames for each available volume
+ */
+void
+rmm_print_volume_nicknames(LibHalContext *hal_ctx, DBusError *error)
+{
+ char **udis;
+ int num_udis;
+ char *block_device;
+ char *drive_udi;
+ char *volume_label;
+ char *mount_point;
+ boolean_t comma;
+ char **nicknames;
+ int i, j;
+
+ dbus_error_init(error);
+
+ if ((udis = libhal_find_device_by_capability(hal_ctx, "volume",
+ &num_udis, error)) == NULL) {
+ return;
+ }
+
+ for (i = 0; i < num_udis; i++) {
+ if ((block_device = libhal_device_get_property_string(hal_ctx,
+ udis[i], "block.device", NULL)) == NULL) {
+ continue;
+ }
+ if ((drive_udi = libhal_device_get_property_string(hal_ctx,
+ udis[i], "block.storage_device", NULL)) == NULL) {
+ libhal_free_string(block_device);
+ continue;
+ }
+ (void) printf("%s\t", block_device);
+ comma = B_FALSE;
+
+ if ((nicknames = libhal_device_get_property_strlist(hal_ctx,
+ drive_udi, "storage.solaris.nicknames", NULL)) != NULL) {
+ for (j = 0; nicknames[j] != NULL; j++) {
+ (void) printf("%s%s", comma ? "," : "",
+ nicknames[j]);
+ comma = B_TRUE;
+ }
+ }
+
+ if (((volume_label = libhal_device_get_property_string(hal_ctx,
+ udis[i], "volume.label", NULL)) != NULL) &&
+ (strlen(volume_label) > 0)) {
+ (void) printf("%s%s", comma ? "," : "", volume_label);
+ comma = B_TRUE;
+ }
+
+ if (((mount_point = libhal_device_get_property_string(hal_ctx,
+ udis[i], "volume.mount_point", NULL)) != NULL) &&
+ (strlen(mount_point) > 0)) {
+ (void) printf("%s%s", comma ? "," : "", mount_point);
+ comma = B_TRUE;
+ }
+
+ (void) printf("\n");
+
+ libhal_free_string_array(nicknames);
+ libhal_free_string(drive_udi);
+ libhal_free_string(volume_label);
+ libhal_free_string(mount_point);
+ libhal_free_string(block_device);
+ }
+ libhal_free_string_array(udis);
+}
+
+
+/*
+ * find volume by nickname
+ * returns the LibHalDrive object and a list of LibHalVolume objects.
+ */
+LibHalDrive *
+rmm_hal_volume_findby_nickname(LibHalContext *hal_ctx, const char *name,
+ GSList **volumes)
+{
+ DBusError error;
+ LibHalDrive *drive = NULL;
+ LibHalDrive *drive_tmp;
+ char **udis;
+ int num_udis;
+ char **nicknames;
+ int i, j;
+
+ *volumes = NULL;
+
+ dbus_error_init(&error);
+
+ if ((udis = libhal_find_device_by_capability(hal_ctx, "storage",
+ &num_udis, &error)) == NULL) {
+ rmm_dbus_error_free(&error);
+ return (NULL);
+ }
+
+ /* find a drive by nickname */
+ for (i = 0; (i < num_udis) && (drive == NULL); i++) {
+ if ((nicknames = libhal_device_get_property_strlist(hal_ctx,
+ udis[i], "storage.solaris.nicknames", &error)) == NULL) {
+ rmm_dbus_error_free(&error);
+ continue;
+ }
+ for (j = 0; (nicknames[j] != NULL) && (drive == NULL); j++) {
+ if (strcmp(nicknames[j], name) == 0) {
+ drive = libhal_drive_from_udi(hal_ctx, udis[i]);
+ }
+ }
+ libhal_free_string_array(nicknames);
+ }
+ libhal_free_string_array(udis);
+
+ if (drive != NULL) {
+ /* found the drive, now find its volumes */
+ if ((drive_tmp = rmm_hal_volume_findby(hal_ctx,
+ "block.storage_device", libhal_drive_get_udi(drive),
+ volumes)) != NULL) {
+ libhal_drive_free(drive_tmp);
+ }
+ }
+
+ rmm_dbus_error_free(&error);
+
+ return (drive);
+}
+
+void
+rmm_volumes_free(GSList *volumes)
+{
+ GSList *i;
+
+ for (i = volumes; i != NULL; i = g_slist_next(i)) {
+ libhal_volume_free((LibHalVolume *)(i->data));
+ }
+ g_slist_free(volumes);
+}
+
+/*
+ * Call HAL's Mount() method on the given device
+ */
+boolean_t
+rmm_hal_mount(LibHalContext *hal_ctx, const char *udi,
+ char **opts, int num_opts, char *mountpoint, DBusError *error)
+{
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+ char *fstype;
+
+ dprintf("mounting %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Volume", "Mount"))) {
+ dprintf(
+ "mount failed for %s: cannot create dbus message\n", udi);
+ return (B_FALSE);
+ }
+
+ fstype = "";
+ if (mountpoint == NULL) {
+ mountpoint = "";
+ }
+
+ if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &mountpoint,
+ DBUS_TYPE_STRING, &fstype,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &opts, num_opts,
+ DBUS_TYPE_INVALID)) {
+ dprintf("mount failed for %s: cannot append args\n", udi);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, error))) {
+ dprintf("mount failed for %s: %s\n", udi, error->message);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dprintf("mounted %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ rmm_dbus_error_free(error);
+
+ return (B_TRUE);
+}
+
+
+/*
+ * Call HAL's Unmount() method on the given device
+ */
+boolean_t
+rmm_hal_unmount(LibHalContext *hal_ctx, const char *udi, DBusError *error)
+{
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+ char **opts = NULL;
+
+ dprintf("unmounting %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Volume", "Unmount"))) {
+ dprintf(
+ "unmount failed %s: cannot create dbus message\n", udi);
+ return (B_FALSE);
+ }
+
+ if (!dbus_message_append_args(dmesg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &opts, 0, DBUS_TYPE_INVALID)) {
+ dprintf("unmount failed %s: cannot append args\n", udi);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, error))) {
+ dprintf("unmount failed for %s: %s\n", udi, error->message);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dprintf("unmounted %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ rmm_dbus_error_free(error);
+
+ return (B_TRUE);
+}
+
+
+/*
+ * Call HAL's Eject() method on the given device
+ */
+boolean_t
+rmm_hal_eject(LibHalContext *hal_ctx, const char *udi, DBusError *error)
+{
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+ char **options = NULL;
+ uint_t num_options = 0;
+
+ dprintf("ejecting %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Storage", "Eject"))) {
+ dprintf("eject %s: cannot create dbus message\n", udi);
+ return (B_FALSE);
+ }
+
+ if (!dbus_message_append_args(dmesg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
+ DBUS_TYPE_INVALID)) {
+ dprintf("eject %s: cannot append args to dbus message ", udi);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, error))) {
+ dprintf("eject %s: %s\n", udi, error->message);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dprintf("ejected %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ rmm_dbus_error_free(error);
+
+ return (B_TRUE);
+}
+
+/*
+ * Call HAL's CloseTray() method on the given device
+ */
+boolean_t
+rmm_hal_closetray(LibHalContext *hal_ctx, const char *udi, DBusError *error)
+{
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+ char **options = NULL;
+ uint_t num_options = 0;
+
+ dprintf("closing tray %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device.Storage", "CloseTray"))) {
+ dprintf(
+ "closetray failed for %s: cannot create dbus message\n",
+ udi);
+ return (B_FALSE);
+ }
+
+ if (!dbus_message_append_args(dmesg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
+ DBUS_TYPE_INVALID)) {
+ dprintf("closetray %s: cannot append args to dbus message ",
+ udi);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, error))) {
+ dprintf("closetray failed for %s: %s\n", udi, error->message);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dprintf("closetray ok %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ rmm_dbus_error_free(error);
+
+ return (B_TRUE);
+}
+
+/*
+ * Call HAL's Rescan() method on the given device
+ */
+boolean_t
+rmm_hal_rescan(LibHalContext *hal_ctx, const char *udi, DBusError *error)
+{
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+
+ dprintf("rescanning %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device", "Rescan"))) {
+ dprintf("rescan failed for %s: cannot create dbus message\n",
+ udi);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, error))) {
+ dprintf("rescan failed for %s: %s\n", udi, error->message);
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dprintf("rescan ok %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ rmm_dbus_error_free(error);
+
+ return (B_TRUE);
+}
+
+boolean_t
+rmm_hal_claim_branch(LibHalContext *hal_ctx, const char *udi)
+{
+ DBusError error;
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+ const char *claimed_by = "rmvolmgr";
+
+ dprintf("claiming branch %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
+ "ClaimBranch"))) {
+ dprintf("cannot create dbus message\n");
+ return (B_FALSE);
+ }
+
+ if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_STRING, &claimed_by, DBUS_TYPE_INVALID)) {
+ dprintf("cannot append args to dbus message\n");
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(&error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, &error))) {
+ dprintf("cannot send dbus message\n");
+ dbus_message_unref(dmesg);
+ rmm_dbus_error_free(&error);
+ return (B_FALSE);
+ }
+
+ dprintf("claim branch ok %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ return (B_TRUE);
+}
+
+boolean_t
+rmm_hal_unclaim_branch(LibHalContext *hal_ctx, const char *udi)
+{
+ DBusError error;
+ DBusConnection *dbus_conn = libhal_ctx_get_dbus_connection(hal_ctx);
+ DBusMessage *dmesg, *reply;
+ const char *claimed_by = "rmvolmgr";
+
+ dprintf("unclaiming branch %s...\n", udi);
+
+ if (!(dmesg = dbus_message_new_method_call("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager",
+ "UnclaimBranch"))) {
+ dprintf("cannot create dbus message\n");
+ return (B_FALSE);
+ }
+
+ if (!dbus_message_append_args(dmesg, DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_STRING, &claimed_by, DBUS_TYPE_INVALID)) {
+ dprintf("cannot append args to dbus message\n");
+ dbus_message_unref(dmesg);
+ return (B_FALSE);
+ }
+
+ dbus_error_init(&error);
+ if (!(reply = dbus_connection_send_with_reply_and_block(dbus_conn,
+ dmesg, -1, &error))) {
+ dprintf("cannot send dbus message\n");
+ dbus_message_unref(dmesg);
+ rmm_dbus_error_free(&error);
+ return (B_FALSE);
+ }
+
+ dprintf("unclaim branch ok %s\n", udi);
+
+ dbus_message_unref(dmesg);
+ dbus_message_unref(reply);
+
+ return (B_TRUE);
+}
+
+static boolean_t
+rmm_action_one(LibHalContext *hal_ctx, const char *name, action_t action,
+ const char *dev, const char *udi, LibHalVolume *v,
+ char **opts, int num_opts, char *mountpoint)
+{
+ char dev_str[MAXPATHLEN];
+ char *mountp;
+ DBusError error;
+ boolean_t ret = B_FALSE;
+
+ if (strcmp(name, dev) == 0) {
+ (void) snprintf(dev_str, sizeof (dev_str), name);
+ } else {
+ (void) snprintf(dev_str, sizeof (dev_str), "%s %s", name, dev);
+ }
+
+ dbus_error_init(&error);
+
+ switch (action) {
+ case EJECT:
+ ret = rmm_hal_eject(hal_ctx, udi, &error);
+ break;
+ case INSERT:
+ case REMOUNT:
+ if (libhal_volume_is_mounted(v)) {
+ goto done;
+ }
+ ret = rmm_hal_mount(hal_ctx, udi,
+ opts, num_opts, mountpoint, &error);
+ break;
+ case UNMOUNT:
+ if (!libhal_volume_is_mounted(v)) {
+ goto done;
+ }
+ ret = rmm_hal_unmount(hal_ctx, udi, &error);
+ break;
+ case CLOSETRAY:
+ ret = rmm_hal_closetray(hal_ctx, udi, &error);
+ break;
+ }
+
+ if (!ret) {
+ (void) fprintf(stderr, gettext("%s of %s failed: %s\n"),
+ action_strings[action], dev_str, rmm_strerror(&error, -1));
+ goto done;
+ }
+
+ switch (action) {
+ case EJECT:
+ (void) printf(gettext("%s ejected\n"), dev_str);
+ break;
+ case INSERT:
+ case REMOUNT:
+ mountp = rmm_get_mnttab_mount_point(dev);
+ if (mountp != NULL) {
+ (void) printf(gettext("%s mounted at %s\n"),
+ dev_str, mountp);
+ free(mountp);
+ }
+ break;
+ case UNMOUNT:
+ (void) printf(gettext("%s unmounted\n"), dev_str);
+ break;
+ case CLOSETRAY:
+ (void) printf(gettext("%s tray closed\n"), dev_str);
+ break;
+ }
+
+done:
+ rmm_dbus_error_free(&error);
+ return (ret);
+}
+
+/*
+ * top level action routine
+ *
+ * If non-null 'aa' is passed, it will be used, otherwise a local copy
+ * will be created.
+ */
+boolean_t
+rmm_action(LibHalContext *hal_ctx, const char *name, action_t action,
+ struct action_arg *aap, char **opts, int num_opts, char *mountpoint)
+{
+ DBusError error;
+ GSList *volumes, *i;
+ LibHalDrive *d;
+ LibHalVolume *v;
+ const char *udi, *d_udi;
+ const char *dev, *d_dev;
+ struct action_arg aa_local;
+ boolean_t ret = B_FALSE;
+
+ dprintf("rmm_action %s %s\n", name, action_strings[action]);
+
+ if (aap == NULL) {
+ aap = &aa_local;
+ }
+
+ dbus_error_init(&error);
+
+ /* find the drive and its volumes */
+ d = rmm_hal_volume_find(hal_ctx, name, &error, &volumes);
+ rmm_dbus_error_free(&error);
+ if (d == NULL) {
+ (void) fprintf(stderr, gettext("cannot find '%s'\n"), name);
+ return (B_FALSE);
+ }
+ d_udi = libhal_drive_get_udi(d);
+ d_dev = libhal_drive_get_device_file(d);
+ if ((d_udi == NULL) || (d_dev == NULL)) {
+ goto out;
+ }
+
+ /*
+ * For those drives that do not require media eject,
+ * EJECT turns into UNMOUNT.
+ */
+ if ((action == EJECT) && !libhal_drive_requires_eject(d)) {
+ action = UNMOUNT;
+ }
+
+ /* per drive action */
+ if ((action == EJECT) || (action == CLOSETRAY)) {
+ ret = rmm_action_one(hal_ctx, name, action, d_dev, d_udi, NULL,
+ opts, num_opts, NULL);
+
+ if (!ret || (action == CLOSETRAY)) {
+ goto out;
+ }
+ }
+
+ /* per volume action */
+ for (i = volumes; i != NULL; i = g_slist_next(i)) {
+ v = (LibHalVolume *)i->data;
+ udi = libhal_volume_get_udi(v);
+ dev = libhal_volume_get_device_file(v);
+
+ if ((udi == NULL) || (dev == NULL)) {
+ continue;
+ }
+ if (aap == &aa_local) {
+ if (!rmm_volume_aa_from_prop(hal_ctx, udi, v, aap)) {
+ dprintf("rmm_volume_aa_from_prop failed %s\n",
+ udi);
+ continue;
+ }
+ }
+ aap->aa_action = action;
+
+ /* ejected above, just need postprocess */
+ if (action != EJECT) {
+ ret = rmm_action_one(hal_ctx, name, action, dev, udi, v,
+ opts, num_opts, mountpoint);
+ }
+ if (ret) {
+ (void) vold_postprocess(hal_ctx, udi, aap);
+ }
+
+ libhal_volume_free(v);
+ if (aap == &aa_local) {
+ rmm_volume_aa_free(aap);
+ }
+ }
+
+out:
+ g_slist_free(volumes);
+ libhal_drive_free(d);
+
+ return (ret);
+}
+
+
+/*
+ * rescan by name
+ * if name is NULL, rescan all drives
+ */
+boolean_t
+rmm_rescan(LibHalContext *hal_ctx, const char *name, boolean_t query)
+{
+ DBusError error;
+ GSList *volumes;
+ LibHalDrive *drive = NULL;
+ const char *drive_udi;
+ char **udis;
+ int num_udis;
+ char *nickname;
+ char **nicks = NULL;
+ boolean_t do_free_udis = FALSE;
+ int i;
+ int ret = 0;
+
+ dprintf("rmm_rescan %s\n", name != NULL ? name : "all");
+
+ dbus_error_init(&error);
+
+ if (name != NULL) {
+ if ((drive = rmm_hal_volume_find(hal_ctx, name, &error,
+ &volumes)) == NULL) {
+ rmm_dbus_error_free(&error);
+ (void) fprintf(stderr,
+ gettext("cannot find '%s'\n"), name);
+ return (B_FALSE);
+ }
+ rmm_dbus_error_free(&error);
+ g_slist_free(volumes);
+
+ drive_udi = libhal_drive_get_udi(drive);
+ udis = (char **)&drive_udi;
+ num_udis = 1;
+ } else {
+ if ((udis = libhal_find_device_by_capability(hal_ctx,
+ "storage", &num_udis, &error)) == NULL) {
+ rmm_dbus_error_free(&error);
+ return (B_TRUE);
+ }
+ rmm_dbus_error_free(&error);
+ do_free_udis = TRUE;
+ }
+
+ for (i = 0; i < num_udis; i++) {
+ if (name == NULL) {
+ nicks = libhal_device_get_property_strlist(hal_ctx,
+ udis[i], "storage.solaris.nicknames", NULL);
+ if (nicks != NULL) {
+ nickname = nicks[0];
+ } else {
+ nickname = "";
+ }
+ }
+ if (!(ret = rmm_hal_rescan(hal_ctx, udis[i], &error))) {
+ (void) fprintf(stderr,
+ gettext("rescan of %s failed: %s\n"),
+ name ? name : nickname,
+ rmm_strerror(&error, -1));
+ libhal_free_string_array(nicks);
+ continue;
+ }
+ if (query) {
+ printf(gettext("%s is%s available\n"),
+ name ? name : nickname,
+ libhal_device_get_property_bool(hal_ctx, udis[i],
+ "storage.removable.media_available", NULL) ?
+ "" : " not");
+ }
+ libhal_free_string_array(nicks);
+ }
+
+ if (drive != NULL) {
+ libhal_drive_free(drive);
+ }
+ if (do_free_udis) {
+ libhal_free_string_array(udis);
+ }
+
+ return (ret);
+}
+
+
+/*
+ * set action_arg from volume properties
+ */
+boolean_t
+rmm_volume_aa_from_prop(LibHalContext *hal_ctx, const char *udi_arg,
+ LibHalVolume *volume_arg, struct action_arg *aap)
+{
+ LibHalVolume *volume = volume_arg;
+ const char *udi = udi_arg;
+ const char *drive_udi;
+ char *volume_label;
+ char *mountpoint;
+ int len;
+ int ret = B_FALSE;
+
+ /* at least udi or volume must be supplied */
+ if ((udi == NULL) && (volume == NULL)) {
+ return (B_FALSE);
+ }
+ if (volume == NULL) {
+ if ((volume = libhal_volume_from_udi(hal_ctx, udi)) == NULL) {
+ dprintf("cannot get volume %s\n", udi);
+ goto out;
+ }
+ }
+ if (udi == NULL) {
+ if ((udi = libhal_volume_get_udi(volume)) == NULL) {
+ dprintf("cannot get udi\n");
+ goto out;
+ }
+ }
+ drive_udi = libhal_volume_get_storage_device_udi(volume);
+
+ if (!(aap->aa_symdev = libhal_device_get_property_string(hal_ctx,
+ drive_udi, "storage.solaris.legacy.symdev", NULL))) {
+ dprintf("property %s not found %s\n",
+ "storage.solaris.legacy.symdev", drive_udi);
+ goto out;
+ }
+ if (!(aap->aa_media = libhal_device_get_property_string(hal_ctx,
+ drive_udi, "storage.solaris.legacy.media_type", NULL))) {
+ dprintf("property %s not found %s\n",
+ "storage.solaris.legacy.media_type", drive_udi);
+ goto out;
+ }
+
+ /* name is derived from volume label */
+ aap->aa_name = NULL;
+ if ((volume_label = (char *)libhal_device_get_property_string(hal_ctx,
+ udi, "volume.label", NULL)) != NULL) {
+ if ((len = strlen(volume_label)) > 0) {
+ aap->aa_name = rmm_vold_convert_volume_label(
+ volume_label, len);
+ if (strlen(aap->aa_name) == 0) {
+ free(aap->aa_name);
+ aap->aa_name = NULL;
+ }
+ }
+ libhal_free_string(volume_label);
+ }
+ /* if no label, then unnamed_<mediatype> */
+ if (aap->aa_name == NULL) {
+ aap->aa_name = (char *)calloc(1, sizeof ("unnamed_floppyNNNN"));
+ if (aap->aa_name == NULL) {
+ goto out;
+ }
+ (void) snprintf(aap->aa_name, sizeof ("unnamed_floppyNNNN"),
+ "unnamed_%s", aap->aa_media);
+ }
+
+ if (!(aap->aa_path = libhal_device_get_property_string(hal_ctx, udi,
+ "block.device", NULL))) {
+ dprintf("property %s not found %s\n", "block.device", udi);
+ goto out;
+ }
+ if (!(aap->aa_rawpath = libhal_device_get_property_string(hal_ctx, udi,
+ "block.solaris.raw_device", NULL))) {
+ dprintf("property %s not found %s\n",
+ "block.solaris.raw_device", udi);
+ goto out;
+ }
+ if (!(aap->aa_type = libhal_device_get_property_string(hal_ctx, udi,
+ "volume.fstype", NULL))) {
+ dprintf("property %s not found %s\n", "volume.fstype", udi);
+ goto out;
+ }
+ if (!libhal_device_get_property_bool(hal_ctx, udi,
+ "volume.is_partition", NULL)) {
+ aap->aa_partname = NULL;
+ } else if (!(aap->aa_partname = libhal_device_get_property_string(
+ hal_ctx, udi, "block.solaris.slice", NULL))) {
+ dprintf("property %s not found %s\n",
+ "block.solaris.slice", udi);
+ goto out;
+ }
+ if (!(mountpoint = libhal_device_get_property_string(hal_ctx, udi,
+ "volume.mount_point", NULL))) {
+ dprintf("property %s not found %s\n",
+ "volume.mount_point", udi);
+ goto out;
+ }
+ /*
+ * aa_mountpoint can be reallocated in rmm_volume_aa_update_mountpoint()
+ * won't have to choose between free() or libhal_free_string() later on
+ */
+ aap->aa_mountpoint = strdup(mountpoint);
+ libhal_free_string(mountpoint);
+ if (aap->aa_mountpoint == NULL) {
+ dprintf("mountpoint is NULL %s\n", udi);
+ goto out;
+ }
+
+ ret = B_TRUE;
+
+out:
+ if ((volume != NULL) && (volume != volume_arg)) {
+ libhal_volume_free(volume);
+ }
+ if (!ret) {
+ rmm_volume_aa_free(aap);
+ }
+ return (ret);
+}
+
+/* ARGSUSED */
+void
+rmm_volume_aa_update_mountpoint(LibHalContext *hal_ctx, const char *udi,
+ struct action_arg *aap)
+{
+ if (aap->aa_mountpoint != NULL) {
+ free(aap->aa_mountpoint);
+ }
+ aap->aa_mountpoint = rmm_get_mnttab_mount_point(aap->aa_path);
+}
+
+void
+rmm_volume_aa_free(struct action_arg *aap)
+{
+ if (aap->aa_symdev != NULL) {
+ libhal_free_string(aap->aa_symdev);
+ aap->aa_symdev = NULL;
+ }
+ if (aap->aa_name != NULL) {
+ free(aap->aa_name);
+ aap->aa_name = NULL;
+ }
+ if (aap->aa_path != NULL) {
+ libhal_free_string(aap->aa_path);
+ aap->aa_path = NULL;
+ }
+ if (aap->aa_rawpath != NULL) {
+ libhal_free_string(aap->aa_rawpath);
+ aap->aa_rawpath = NULL;
+ }
+ if (aap->aa_type != NULL) {
+ libhal_free_string(aap->aa_type);
+ aap->aa_type = NULL;
+ }
+ if (aap->aa_media != NULL) {
+ libhal_free_string(aap->aa_media);
+ aap->aa_media = NULL;
+ }
+ if (aap->aa_partname != NULL) {
+ libhal_free_string(aap->aa_partname);
+ aap->aa_partname = NULL;
+ }
+ if (aap->aa_mountpoint != NULL) {
+ free(aap->aa_mountpoint);
+ aap->aa_mountpoint = NULL;
+ }
+}
+
+/*
+ * get device's mount point from mnttab
+ */
+char *
+rmm_get_mnttab_mount_point(const char *special)
+{
+ char *mount_point = NULL;
+ FILE *f;
+ struct mnttab mnt;
+ struct mnttab mpref = { NULL, NULL, NULL, NULL, NULL };
+
+ if ((f = fopen(MNTTAB, "r")) != NULL) {
+ mpref.mnt_special = (char *)special;
+ if (getmntany(f, &mnt, &mpref) == 0) {
+ mount_point = strdup(mnt.mnt_mountp);
+ }
+ fclose(f);
+ }
+
+ return (mount_point);
+}
+
+
+/*
+ * get human readable string from error values
+ */
+const char *
+rmm_strerror(DBusError *dbus_error, int rmm_error)
+{
+ const char *str;
+
+ if ((dbus_error != NULL) && dbus_error_is_set(dbus_error)) {
+ str = dbus_error->message;
+ } else {
+ switch (rmm_error) {
+ case RMM_EOK:
+ str = gettext("success");
+ break;
+ case RMM_EDBUS_CONNECT:
+ str = gettext("cannot connect to D-Bus");
+ break;
+ case RMM_EHAL_CONNECT:
+ str = gettext("cannot connect to HAL");
+ break;
+ default:
+ str = gettext("undefined error");
+ break;
+ }
+ }
+
+ return (str);
+}
+
+void
+rmm_dbus_error_free(DBusError *error)
+{
+ if (error != NULL && dbus_error_is_set(error)) {
+ dbus_error_free(error);
+ }
+}
+
+static int
+rmm_vold_isbadchar(int c)
+{
+ int ret_val = 0;
+
+
+ switch (c) {
+ case '/':
+ case ';':
+ case '|':
+ ret_val = 1;
+ break;
+ default:
+ if (iscntrl(c) || isspace(c)) {
+ ret_val = 1;
+ }
+ }
+
+ return (ret_val);
+}
+
+char *
+rmm_vold_convert_volume_label(const char *name, size_t len)
+{
+ char buf[MAXNAMELEN+1];
+ char *s = buf;
+ int i;
+
+ if (len > MAXNAMELEN) {
+ len = MAXNAMELEN;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (name[i] == '\0') {
+ break;
+ }
+ if (isgraph((int)name[i])) {
+ if (isupper((int)name[i])) {
+ *s++ = tolower((int)name[i]);
+ } else if (rmm_vold_isbadchar((int)name[i])) {
+ *s++ = '_';
+ } else {
+ *s++ = name[i];
+ }
+ }
+ }
+ *s = '\0';
+ s = strdup(buf);
+
+ return (s);
+}
+
+/*
+ * swiped from mkdir.c
+ */
+int
+makepath(char *dir, mode_t mode)
+{
+ int err;
+ char *slash;
+
+
+ if ((mkdir(dir, mode) == 0) || (errno == EEXIST)) {
+ return (0);
+ }
+ if (errno != ENOENT) {
+ return (-1);
+ }
+ if ((slash = strrchr(dir, '/')) == NULL) {
+ return (-1);
+ }
+ *slash = '\0';
+ err = makepath(dir, mode);
+ *slash++ = '/';
+
+ if (err || (*slash == '\0')) {
+ return (err);
+ }
+
+ return (mkdir(dir, mode));
+}
+
+
+void
+dprintf(const char *fmt, ...)
+{
+
+ va_list ap;
+ const char *p;
+ char msg[BUFSIZ];
+ char *errmsg = strerror(errno);
+ char *s;
+
+ if (rmm_debug == 0) {
+ return;
+ }
+
+ (void) memset(msg, 0, BUFSIZ);
+
+ /* scan for %m and replace with errno msg */
+ s = &msg[strlen(msg)];
+ p = fmt;
+
+ while (*p != '\0') {
+ if ((*p == '%') && (*(p+1) == 'm')) {
+ (void) strcat(s, errmsg);
+ p += 2;
+ s += strlen(errmsg);
+ continue;
+ }
+ *s++ = *p++;
+ }
+ *s = '\0'; /* don't forget the null byte */
+
+ va_start(ap, fmt);
+ (void) vfprintf(stderr, msg, ap);
+ va_end(ap);
+}
diff --git a/usr/src/cmd/rmvolmgr/rmm_common.h b/usr/src/cmd/rmvolmgr/rmm_common.h
new file mode 100644
index 0000000000..ed80c535a3
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/rmm_common.h
@@ -0,0 +1,106 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _COMMON_H
+#define _COMMON_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <zone.h>
+
+#include <glib.h>
+#include <libhal.h>
+#include <libhal-storage.h>
+
+#include "vold.h"
+
+typedef enum {
+ RMM_EOK = 0,
+ RMM_EDBUS_CONNECT, /* cannot connect to DBUS */
+ RMM_EHAL_CONNECT /* cannot connect to HAL */
+} rmm_error_t;
+
+#define HAL_BRANCH_LOCAL "/org/freedesktop/Hal/devices/local"
+
+#define NELEM(a) (sizeof (a) / sizeof (*(a)))
+
+extern char *progname;
+
+LibHalContext *rmm_hal_init(LibHalDeviceAdded, LibHalDeviceRemoved,
+ LibHalDevicePropertyModified, DBusError *, rmm_error_t *);
+void rmm_hal_fini(LibHalContext *hal_ctx);
+
+LibHalDrive *rmm_hal_volume_find(LibHalContext *, const char *,
+ DBusError *, GSList **);
+LibHalDrive *rmm_hal_volume_find_default(LibHalContext *, DBusError *,
+ const char **, GSList **);
+LibHalDrive *rmm_hal_volume_findby(LibHalContext *, const char *,
+ const char *, GSList **);
+LibHalDrive *rmm_hal_volume_findby_nickname(LibHalContext *, const char *,
+ GSList **);
+void rmm_print_volume_nicknames(LibHalContext *, DBusError *);
+void rmm_volumes_free(GSList *);
+
+boolean_t rmm_hal_mount(LibHalContext *, const char *,
+ char **, int, char *, DBusError *);
+boolean_t rmm_hal_unmount(LibHalContext *, const char *, DBusError *);
+boolean_t rmm_hal_eject(LibHalContext *, const char *, DBusError *);
+boolean_t rmm_hal_closetray(LibHalContext *, const char *, DBusError *);
+boolean_t rmm_hal_rescan(LibHalContext *, const char *, DBusError *);
+boolean_t rmm_hal_claim_branch(LibHalContext *, const char *);
+boolean_t rmm_hal_unclaim_branch(LibHalContext *, const char *);
+
+boolean_t rmm_action(LibHalContext *, const char *name, action_t action,
+ struct action_arg *aap, char **, int, char *);
+boolean_t rmm_rescan(LibHalContext *, const char *, boolean_t);
+
+void rmm_update_vold_mountpoints(LibHalContext *, const char *,
+ struct action_arg *);
+
+boolean_t rmm_volume_aa_from_prop(LibHalContext *, const char *,
+ LibHalVolume *, struct action_arg *);
+void rmm_volume_aa_update_mountpoint(LibHalContext *, const char *,
+ struct action_arg *aap);
+void rmm_volume_aa_free(struct action_arg *);
+
+char *rmm_get_mnttab_mount_point(const char *);
+const char *rmm_strerror(DBusError *, int);
+void rmm_dbus_error_free(DBusError *);
+
+char *rmm_vold_convert_volume_label(const char *name, size_t len);
+int makepath(char *, mode_t);
+void dprintf(const char *, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMMON_H */
diff --git a/usr/src/cmd/rmvolmgr/rmvolmgr.c b/usr/src/cmd/rmvolmgr/rmvolmgr.c
new file mode 100644
index 0000000000..3c8a88b92c
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/rmvolmgr.c
@@ -0,0 +1,607 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * rmvolmgr daemon
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <errno.h>
+#include <libintl.h>
+#include <sys/syscall.h>
+#include <libscf.h>
+#include <priv_utils.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libhal.h>
+
+#include "rmm_common.h"
+
+char *progname = "rmvolmgr";
+
+#define RMVOLMGR_FMRI "svc:/system/filesystem/rmvolmgr:default"
+
+typedef struct managed_volume {
+ char *udi;
+ boolean_t my;
+ struct action_arg aa;
+} managed_volume_t;
+
+static GSList *managed_volumes;
+
+static GMainLoop *mainloop;
+static LibHalContext *hal_ctx;
+static int sigexit_pipe[2];
+static GIOChannel *sigexit_ioch;
+
+static boolean_t opt_c; /* disable CDE compatibility */
+static boolean_t opt_n; /* disable legacy mountpoint symlinks */
+static boolean_t opt_s; /* system instance */
+
+static void get_smf_properties();
+static int daemon(int nochdir, int noclose);
+static void rmm_device_added(LibHalContext *ctx, const char *udi);
+static void rmm_device_removed(LibHalContext *ctx, const char *udi);
+static void rmm_property_modified(LibHalContext *ctx, const char *udi,
+ const char *key, dbus_bool_t is_removed, dbus_bool_t is_added);
+static void rmm_mount_all();
+static void rmm_unmount_all();
+static void sigexit(int signo);
+static gboolean sigexit_ioch_func(GIOChannel *source, GIOCondition condition,
+ gpointer user_data);
+
+static void
+usage()
+{
+ (void) fprintf(stderr, gettext("\nusage: rmvolmgr [-v]\n"));
+}
+
+static int
+rmvolmgr(int argc, char **argv)
+{
+ const char *opts = "chnsv";
+ DBusError error;
+ boolean_t daemonize;
+ rmm_error_t rmm_error;
+ int c;
+
+ while ((c = getopt(argc, argv, opts)) != EOF) {
+ switch (c) {
+ case 'c':
+ opt_c = B_TRUE;
+ break;
+ case 'n':
+ opt_n = B_TRUE;
+ break;
+ case 's':
+ opt_s = B_TRUE;
+ break;
+ case 'v':
+ rmm_debug = 1;
+ break;
+ case '?':
+ case 'h':
+ usage();
+ return (0);
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ if (opt_s) {
+ if (geteuid() != 0) {
+ (void) fprintf(stderr,
+ gettext("system instance must have euid 0\n"));
+ return (1);
+ }
+
+ get_smf_properties();
+
+ if (opt_c) {
+ rmm_vold_actions_enabled = B_FALSE;
+ }
+ if (opt_n) {
+ rmm_vold_mountpoints_enabled = B_FALSE;
+ }
+
+
+ /*
+ * Drop unused privileges. Remain root for HAL interaction
+ * and to create legacy symlinks.
+ *
+ * Need PRIV_FILE_DAC_WRITE to write to users'
+ * /tmp/.removable/notify* files.
+ */
+ if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
+ 0, 0,
+ rmm_vold_actions_enabled ? PRIV_FILE_DAC_WRITE : NULL,
+ NULL) == -1) {
+ (void) fprintf(stderr,
+ gettext("failed to drop privileges"));
+ return (1);
+ }
+ /* basic privileges we don't need */
+ (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_PROC_EXEC,
+ PRIV_PROC_INFO, PRIV_FILE_LINK_ANY, PRIV_PROC_SESSION,
+ NULL);
+
+ } else {
+ if (opt_c) {
+ rmm_vold_actions_enabled = B_FALSE;
+ }
+ if (opt_n) {
+ rmm_vold_mountpoints_enabled = B_FALSE;
+ }
+ }
+
+ daemonize = (getenv("RMVOLMGR_NODAEMON") == NULL);
+
+ if (daemonize && daemon(0, 0) < 0) {
+ dprintf("daemonizing failed: %s", strerror(errno));
+ return (1);
+ }
+
+ if (opt_s) {
+ __fini_daemon_priv(PRIV_PROC_FORK, NULL);
+ }
+
+ /*
+ * signal mainloop integration using pipes
+ */
+ if (pipe(sigexit_pipe) != 0) {
+ dprintf("pipe failed %s\n", strerror(errno));
+ return (1);
+ }
+ sigexit_ioch = g_io_channel_unix_new(sigexit_pipe[0]);
+ if (sigexit_ioch == NULL) {
+ dprintf("g_io_channel_unix_new failed\n");
+ return (1);
+ }
+ g_io_add_watch(sigexit_ioch, G_IO_IN, sigexit_ioch_func, NULL);
+ signal(SIGTERM, sigexit);
+ signal(SIGINT, sigexit);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGUSR1, SIG_IGN);
+ signal(SIGUSR2, SIG_IGN);
+
+ if ((hal_ctx = rmm_hal_init(rmm_device_added, rmm_device_removed,
+ rmm_property_modified, &error, &rmm_error)) == NULL) {
+ dbus_error_free(&error);
+ return (1);
+ }
+
+ /* user instance should claim devices */
+ if (!opt_s) {
+ if (!rmm_hal_claim_branch(hal_ctx, HAL_BRANCH_LOCAL)) {
+ (void) fprintf(stderr,
+ gettext("cannot claim branch\n"));
+ return (1);
+ }
+ }
+
+ rmm_mount_all();
+
+ if ((mainloop = g_main_loop_new(NULL, B_FALSE)) == NULL) {
+ dprintf("Cannot create main loop\n");
+ return (1);
+ }
+
+ g_main_loop_run(mainloop);
+
+ return (0);
+}
+
+static void
+get_smf_properties()
+{
+ scf_simple_prop_t *prop;
+ uint8_t *val;
+
+ if ((prop = scf_simple_prop_get(NULL, RMVOLMGR_FMRI,
+ "rmvolmgr", "legacy_mountpoints")) != NULL) {
+ if ((val = scf_simple_prop_next_boolean(prop)) != NULL) {
+ rmm_vold_mountpoints_enabled = (*val != 0);
+ }
+ scf_simple_prop_free(prop);
+ }
+
+ if ((prop = scf_simple_prop_get(NULL, RMVOLMGR_FMRI,
+ "rmvolmgr", "cde_compatible")) != NULL) {
+ if ((val = scf_simple_prop_next_boolean(prop)) != NULL) {
+ rmm_vold_actions_enabled = (*val != 0);
+ }
+ scf_simple_prop_free(prop);
+ }
+}
+
+/* ARGSUSED */
+static void
+sigexit(int signo)
+{
+ dprintf("signal to exit %d\n", signo);
+
+ write(sigexit_pipe[1], "s", 1);
+}
+
+/* ARGSUSED */
+static gboolean
+sigexit_ioch_func(GIOChannel *source, GIOCondition condition,
+ gpointer user_data)
+{
+ gchar buf[1];
+ gsize bytes_read;
+ GError *error = NULL;
+
+ if (g_io_channel_read_chars(source, buf, 1, &bytes_read, &error) !=
+ G_IO_STATUS_NORMAL) {
+ dprintf("g_io_channel_read_chars failed %s", error->message);
+ g_error_free(error);
+ return (TRUE);
+ }
+
+ dprintf("signal to exit\n");
+
+ rmm_unmount_all();
+
+ g_main_loop_quit(mainloop);
+
+ return (TRUE);
+}
+
+static managed_volume_t *
+rmm_managed_alloc(LibHalContext *ctx, const char *udi)
+{
+ managed_volume_t *v;
+
+ if ((v = calloc(1, sizeof (managed_volume_t))) == NULL) {
+ return (NULL);
+ }
+ if ((v->udi = strdup(udi)) == NULL) {
+ free(v);
+ return (NULL);
+ }
+ if (!rmm_volume_aa_from_prop(ctx, udi, NULL, &v->aa)) {
+ free(v->udi);
+ free(v);
+ return (NULL);
+ }
+
+ return (v);
+}
+
+static void
+rmm_managed_free(managed_volume_t *v)
+{
+ rmm_volume_aa_free(&v->aa);
+ free(v->udi);
+ free(v);
+}
+
+static gint
+rmm_managed_compare_udi(gconstpointer a, gconstpointer b)
+{
+ const managed_volume_t *va = a;
+ const char *udi = b;
+
+ return (strcmp(va->udi, udi));
+}
+
+static boolean_t
+volume_should_mount(const char *udi)
+{
+ char *storage_device = NULL;
+ int ret = B_FALSE;
+
+ if (libhal_device_get_property_bool(hal_ctx, udi,
+ "volume.ignore", NULL)) {
+ goto out;
+ }
+
+ /* get the backing storage device */
+ if (!(storage_device = libhal_device_get_property_string(hal_ctx, udi,
+ "block.storage_device", NULL))) {
+ dprintf("cannot get block.storage_device\n");
+ goto out;
+ }
+
+ /* we handle either removable or hotpluggable */
+ if (!libhal_device_get_property_bool(hal_ctx, storage_device,
+ "storage.removable", NULL) &&
+ !libhal_device_get_property_bool(hal_ctx, storage_device,
+ "storage.hotpluggable", NULL)) {
+ goto out;
+ }
+
+ /* ignore if claimed by another volume manager */
+ if (libhal_device_get_property_bool(hal_ctx, storage_device,
+ "info.claimed", NULL)) {
+ goto out;
+ }
+
+ ret = B_TRUE;
+
+out:
+ libhal_free_string(storage_device);
+ return (ret);
+}
+
+static void
+volume_added(const char *udi)
+{
+ GSList *l;
+ managed_volume_t *v;
+
+ dprintf("volume added %s\n", udi);
+
+ l = g_slist_find_custom(managed_volumes, udi, rmm_managed_compare_udi);
+ v = (l != NULL) ? l->data : NULL;
+
+ if (v != NULL) {
+ dprintf("already managed %s\n", udi);
+ return;
+ }
+ if (!volume_should_mount(udi)) {
+ dprintf("should not mount %s\n", udi);
+ return;
+ }
+ if ((v = rmm_managed_alloc(hal_ctx, udi)) == NULL) {
+ return;
+ }
+ if (rmm_action(hal_ctx, udi, INSERT, &v->aa, 0, 0, 0)) {
+ v->my = B_TRUE;
+ managed_volumes = g_slist_prepend(managed_volumes, v);
+ } else {
+ dprintf("rmm_action failed %s\n", udi);
+ rmm_managed_free(v);
+ }
+}
+
+static void
+volume_removed(const char *udi)
+{
+ GSList *l;
+ managed_volume_t *v;
+
+ dprintf("volume removed %s\n", udi);
+
+ l = g_slist_find_custom(managed_volumes, udi, rmm_managed_compare_udi);
+ v = (l != NULL) ? l->data : NULL;
+ if (v == NULL) {
+ return;
+ }
+
+ /* HAL will unmount, just do the vold legacy stuff */
+ v->aa.aa_action = EJECT;
+ (void) vold_postprocess(hal_ctx, udi, &v->aa);
+
+ rmm_managed_free(v);
+ managed_volumes = g_slist_delete_link(managed_volumes, l);
+}
+
+/* ARGSUSED */
+static void
+rmm_device_added(LibHalContext *ctx, const char *udi)
+{
+ if (libhal_device_query_capability(hal_ctx, udi, "volume", NULL)) {
+ volume_added(udi);
+ }
+}
+
+/* ARGSUSED */
+static void
+rmm_device_removed(LibHalContext *ctx, const char *udi)
+{
+ if (libhal_device_query_capability(hal_ctx, udi, "volume", NULL)) {
+ volume_removed(udi);
+ }
+}
+
+/* ARGSUSED */
+static void
+rmm_property_modified(LibHalContext *ctx, const char *udi, const char *key,
+ dbus_bool_t is_removed, dbus_bool_t is_added)
+{
+ DBusError error;
+ GSList *l;
+ managed_volume_t *v;
+ boolean_t is_mounted;
+
+ if (strcmp(key, "volume.is_mounted") != 0) {
+ return;
+ }
+ is_mounted = libhal_device_get_property_bool(hal_ctx, udi, key, NULL);
+
+ l = g_slist_find_custom(managed_volumes, udi, rmm_managed_compare_udi);
+ v = (l != NULL) ? l->data : NULL;
+
+ if (is_mounted) {
+ dprintf("Mounted: %s\n", udi);
+
+ if (v != NULL) {
+ /* volume mounted by us is already taken care of */
+ if (v->my) {
+ return;
+ }
+ } else {
+ if ((v = rmm_managed_alloc(ctx, udi)) == NULL) {
+ return;
+ }
+ managed_volumes = g_slist_prepend(managed_volumes, v);
+ }
+
+ v->aa.aa_action = INSERT;
+ (void) vold_postprocess(hal_ctx, udi, &v->aa);
+
+ } else {
+ dprintf("Unmounted: %s\n", udi);
+
+ if (v == NULL) {
+ return;
+ }
+
+ v->aa.aa_action = EJECT;
+ (void) vold_postprocess(hal_ctx, udi, &v->aa);
+
+ rmm_managed_free(v);
+ managed_volumes = g_slist_delete_link(managed_volumes, l);
+ }
+}
+
+/*
+ * Mount all mountable volumes
+ */
+static void
+rmm_mount_all()
+{
+ DBusError error;
+ char **udis = NULL;
+ int num_udis;
+ int i;
+ managed_volume_t *v;
+
+ dbus_error_init(&error);
+
+ /* get all volumes */
+ if ((udis = libhal_find_device_by_capability(hal_ctx, "volume",
+ &num_udis, &error)) == NULL) {
+ dprintf("mount_all: no volumes found\n");
+ goto out;
+ }
+
+ for (i = 0; i < num_udis; i++) {
+ /* skip if already mounted */
+ if (libhal_device_get_property_bool(hal_ctx, udis[i],
+ "volume.is_mounted", NULL)) {
+ dprintf("mount_all: %s already mounted\n", udis[i]);
+ continue;
+ }
+ if (!volume_should_mount(udis[i])) {
+ continue;
+ }
+ if ((v = rmm_managed_alloc(hal_ctx, udis[i])) == NULL) {
+ continue;
+ }
+ if (rmm_action(hal_ctx, udis[i], INSERT, &v->aa, 0, 0, 0)) {
+ v->my = B_TRUE;
+ managed_volumes = g_slist_prepend(managed_volumes, v);
+ } else {
+ rmm_managed_free(v);
+ }
+ }
+
+out:
+ if (udis != NULL) {
+ libhal_free_string_array(udis);
+ }
+ rmm_dbus_error_free(&error);
+}
+
+/*
+ * Mount all volumes mounted by this program
+ */
+static void
+rmm_unmount_all()
+{
+ GSList *i;
+ managed_volume_t *v;
+
+ for (i = managed_volumes; i != NULL; i = managed_volumes) {
+ v = (managed_volume_t *)i->data;
+
+ if (v->my && libhal_device_get_property_bool(hal_ctx, v->udi,
+ "volume.is_mounted", NULL)) {
+ (void) rmm_action(hal_ctx, v->udi, UNMOUNT,
+ &v->aa, 0, 0, 0);
+ }
+
+ managed_volumes = g_slist_remove(managed_volumes, v);
+ rmm_managed_free(v);
+ }
+}
+
+static int
+daemon(int nochdir, int noclose)
+{
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ break;
+ default:
+ exit(0);
+ }
+
+ if (setsid() == -1)
+ return (-1);
+
+ if (!nochdir)
+ (void) chdir("/");
+
+ if (!noclose) {
+ struct stat64 st;
+
+ if (((fd = open("/dev/null", O_RDWR, 0)) != -1) &&
+ (fstat64(fd, &st) == 0)) {
+ if (S_ISCHR(st.st_mode) != 0) {
+ (void) dup2(fd, STDIN_FILENO);
+ (void) dup2(fd, STDOUT_FILENO);
+ (void) dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ (void) close(fd);
+ } else {
+ (void) close(fd);
+ (void) __set_errno(ENODEV);
+ return (-1);
+ }
+ } else {
+ (void) close(fd);
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+int
+main(int argc, char **argv)
+{
+ vold_init(argc, argv);
+
+ return (rmvolmgr(argc, argv));
+}
diff --git a/usr/src/cmd/rmvolmgr/rmvolmgr.xml b/usr/src/cmd/rmvolmgr/rmvolmgr.xml
new file mode 100644
index 0000000000..29906c03b0
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/rmvolmgr.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ ident "%Z%%M% %I% %E% SMI"
+
+ NOTE: This service manifest is not editable; its contents will
+ be overwritten by package or patch operations, including
+ operating system upgrade. Make customizations in a different
+ file.
+
+ Service manifest for rmvolmgr.
+-->
+
+<service_bundle type='manifest' name='SUNWrmvolmgrr:rmvolmgr'>
+
+<service
+ name='system/filesystem/rmvolmgr'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='false' />
+
+ <single_instance />
+
+ <dependency name='fs'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/local' />
+ </dependency>
+
+ <dependency name='dbus'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/dbus' />
+ </dependency>
+
+ <dependency name='hal'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/hal' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-rmvolmgr start'
+ timeout_seconds='30'/>
+
+ <!-- If device access problems keep rmvolmgr from stopping in
+ 30 seconds, customize this timeout to a higher value.
+ -->
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':kill'
+ timeout_seconds='30' />
+
+ <exec_method
+ type='method'
+ name='refresh'
+ exec='/lib/svc/method/svc-rmvolmgr refresh'
+ timeout_seconds='30' />
+
+ <property_group name='general' type='framework'>
+ <!-- to start stop service -->
+ <propval name='action_authorization' type='astring'
+ value='solaris.smf.manage.rmvolmgr' />
+ <!-- configure service -->
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.value.rmvolmgr' />
+ </property_group>
+
+ <property_group name='rmvolmgr' type='application'>
+ <propval name='legacy_mountpoints' type='boolean' value='true' />
+ <propval name='cde_compatible' type='boolean' value='true' />
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ removable volume manager
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='rmvolmgr' section='1M' manpath='/usr/man' />
+ </documentation>
+ </template>
+
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/rmvolmgr/svc-rmvolmgr b/usr/src/cmd/rmvolmgr/svc-rmvolmgr
new file mode 100644
index 0000000000..e46e5582a2
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/svc-rmvolmgr
@@ -0,0 +1,56 @@
+#!/sbin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+case "$1" in
+'start')
+ if smf_is_nonglobalzone; then
+ /usr/sbin/svcadm disable $SMF_FMRI
+ echo "$SMF_FMRI is not supported in a local zone"
+ sleep 5 &
+ exit $SMF_EXIT_OK
+ fi
+
+ [ ! -x /usr/lib/rmvolmgr ] && exit $SMF_EXIT_ERR_CONFIG
+
+ /usr/lib/rmvolmgr -s
+ err=$?
+ if [ $err -ne 0 ]; then
+ echo "rmvolmgr failed to start: error $err"
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+ ;;
+
+*)
+ echo "Usage: $0 { start }"
+ exit $SMF_EXIT_ERR_FATAL
+ ;;
+
+
+esac
+
+exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/rmvolmgr/vold.c b/usr/src/cmd/rmvolmgr/vold.c
new file mode 100644
index 0000000000..fec6be8e07
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/vold.c
@@ -0,0 +1,1089 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Vold compatibility for rmvolmgr: emulate old commands as well as
+ * action_filemgr.so to notify legacy apps via /tmp/.removable pipes.
+ * A lot of this code is copied verbatim from vold sources.
+ *
+ * Here's the original description of action_filemgr.so:
+ *
+ * action_filemgr.so - filemgr interface routines for rmmount
+ *
+ * This shared object allows rmmount to communicate with filemgr.
+ * This is done by communicating over a named pipe that filemgr
+ * creates in directory NOTIFY_DIR. The name of the pipe must
+ * begin with NOTIFY_NAME. This source file contains #define
+ * compiler directives set the values of NOTIFY_DIR and NOTIFY_NAME.
+ *
+ * After a partition on a medium has been mounted as a result of
+ * either insertion or remounting of the medium, the action()
+ * method creates a file named with the symbolic name of the
+ * device in which the medium is inserted and the partition name
+ * (e.g. "jaz0-s2") in NOTIFY_DIR. The file consists of one text
+ * line containing a string naming the mount point of the partition,
+ * a string giving the raw device path to the partition, and a
+ * string naming the file system type on the partition. The action()
+ * method then sends a single character ('i' for insertion, 'r' for
+ * remounting) through the named pipe NOTIFY_NAME to tell filemgr to
+ * look for new files in NOTIFY_DIR.
+ *
+ * If a medium containing no mountable partitions is inserted
+ * or remounted in a device, the action() method creates a file
+ * named with the symbolic name of the device in NOTIFY_DIR.
+ * The file consists of one text line containing a string
+ * giving the symbolic name of the device and a string naming
+ * the reason that the medium couldn't be mounted. The action
+ * method then sends either an 'i' or an 'r' through the named
+ * pipe to tell filemgr to look for new files in NOTIFY_DIR.
+ *
+ * When a medium is ejected or unmounted, the action() method
+ * removes the files that were created in NOTIFY_DIR when the medium
+ * was inserted or remounted and sends a single character ('e' for
+ * ejection, 'u' for unmounting) through the named pipe.
+ *
+ * The following environment variables must be set before calling action():
+ *
+ * VOLUME_ACTION action that occurred (e.g. "insert", "eject")
+ * VOLUME_SYMDEV symbolic name (e.g. "cdrom0", "floppy1")
+ * VOLUME_NAME volume name (e.g. "unnamed_cdrom", "s2")
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <strings.h>
+#include <dirent.h>
+#include <signal.h>
+#include <errno.h>
+#include <libintl.h>
+#include <zone.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dkio.h>
+#include <sys/cdio.h>
+#include <sys/vtoc.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <libcontract.h>
+#include <sys/contract/process.h>
+#include <sys/ctfs.h>
+#include <tsol/label.h>
+
+#include "vold.h"
+#include "rmm_common.h"
+
+int rmm_debug = 0;
+boolean_t rmm_vold_actions_enabled = B_FALSE;
+boolean_t rmm_vold_mountpoints_enabled = B_FALSE;
+
+static char *prog_name = NULL;
+static pid_t prog_pid = 0;
+static int system_labeled = 0;
+static uid_t mnt_uid = -1;
+static gid_t mnt_gid = -1;
+static zoneid_t mnt_zoneid = -1;
+static char mnt_zoneroot[MAXPATHLEN];
+static char mnt_userdir[MAXPATHLEN];
+
+/*
+ * Private attribute types and attributes.
+ */
+static const char notify_characters[] = {
+ 'e',
+ 'i',
+ 'r',
+ 'u'
+};
+
+static const char *result_strings[] = {
+ "FALSE",
+ "TRUE"
+};
+
+#define NOTIFY_DIR "/tmp/.removable" /* dir where filemgr looks */
+#define NOTIFY_NAME "notify" /* named pipe to talk over */
+
+static void volrmmount_usage();
+static void volcheck_usage();
+static int vold_action(struct action_arg *aap);
+static void vold_update_mountpoints(struct action_arg *aap);
+static char *not_mountable(struct action_arg *aa);
+static int create_one_notify_file(char *fstype,
+ char *mount_point,
+ char *notify_file,
+ char *raw_partitionp,
+ char *reason,
+ char *symdev);
+static int create_notify_files(struct action_arg **aa);
+static boolean_t notify_clients(action_t action, int do_notify);
+static void popdir(int fd);
+static int pushdir(const char *dir);
+static boolean_t remove_notify_files(struct action_arg **aa);
+
+/*
+ * should be called once from main()
+ */
+/* ARGSUSED */
+void
+vold_init(int argc, char **argv)
+{
+ system_labeled = is_system_labeled();
+}
+
+/*
+ * Old version of rmmount(1M)
+ */
+/* ARGSUSED */
+int
+vold_rmmount(int argc, char **argv)
+{
+ char *volume_action;
+ char *volume_mediatype;
+ char *volume_mount_mode;
+ char *volume_name;
+ char *volume_path;
+ char *volume_pcfs_id;
+ char *volume_symdev;
+ char *volume_zonename;
+ char *volume_user;
+ action_t action;
+ char mountpoint[MAXPATHLEN];
+ char *zonemountpoint;
+ char *arg_mountpoint = NULL;
+ LibHalContext *hal_ctx;
+ DBusError error;
+ rmm_error_t rmm_error;
+ int ret;
+
+ prog_name = argv[0];
+ prog_pid = getpid();
+
+ mnt_zoneroot[0] = '\0';
+ mnt_userdir[0] = '\0';
+
+ volume_action = getenv("VOLUME_ACTION");
+ volume_mediatype = getenv("VOLUME_MEDIATYPE");
+ volume_mount_mode = getenv("VOLUME_MOUNT_MODE");
+ volume_name = getenv("VOLUME_NAME");
+ volume_path = getenv("VOLUME_PATH");
+ volume_pcfs_id = getenv("VOLUME_PCFS_ID");
+ volume_symdev = getenv("VOLUME_SYMDEV");
+
+ if (system_labeled) {
+ volume_zonename = getenv("VOLUME_ZONE_NAME");
+ volume_user = getenv("VOLUME_USER");
+ }
+ if (volume_action == NULL) {
+ dprintf("%s(%ld): VOLUME_ACTION was null!!\n",
+ prog_name, prog_pid);
+ return (-1);
+ }
+ if (volume_mediatype == NULL) {
+ dprintf("%s(%ld): VOLUME_MEDIATYPE was null!!\n",
+ prog_name, prog_pid);
+ return (-1);
+ }
+ if (volume_mount_mode == NULL) {
+ volume_mount_mode = "rw";
+ }
+ if (volume_name == NULL) {
+ dprintf("%s(%ld): VOLUME_NAME was null!!\n",
+ prog_name, prog_pid);
+ return (-1);
+ }
+ if (volume_path == NULL) {
+ dprintf("%s(%ld): VOLUME_PATH was null!!\n",
+ prog_name, prog_pid);
+ return (-1);
+ }
+ if (volume_pcfs_id == NULL) {
+ volume_pcfs_id = "";
+ }
+ if (volume_symdev == NULL) {
+ dprintf("%s(%ld): VOLUME_SYMDEV was null!!\n",
+ prog_name, prog_pid);
+ return (-1);
+ }
+
+ if (system_labeled) {
+ if (volume_zonename != NULL &&
+ strcmp(volume_zonename, GLOBAL_ZONENAME) != 0) {
+ if ((mnt_zoneid =
+ getzoneidbyname(volume_zonename)) != -1) {
+ if (zone_getattr(mnt_zoneid, ZONE_ATTR_ROOT,
+ mnt_zoneroot, MAXPATHLEN) == -1) {
+ dprintf("%s(%ld): NO ZONEPATH!!\n",
+ prog_name, prog_pid);
+ return (-1);
+ }
+ }
+ } else {
+ mnt_zoneid = GLOBAL_ZONEID;
+ mnt_zoneroot[0] = '\0';
+ }
+ if (volume_user != NULL) {
+ struct passwd *pw;
+
+ if ((pw = getpwnam(volume_user)) == NULL) {
+ dprintf("%s(%ld) %s\n", prog_name, prog_pid,
+ ": VOLUME_USER was not a valid user!");
+ return (-1);
+ }
+ mnt_uid = pw->pw_uid;
+ mnt_gid = pw->pw_gid;
+
+ if (snprintf(mnt_userdir, sizeof (mnt_userdir),
+ "/%s-%s", volume_user, volume_symdev) >=
+ sizeof (mnt_userdir))
+ return (-1);
+ } else {
+ mnt_uid = 0;
+ mnt_userdir[0] = '\0';
+ }
+
+ rmm_vold_mountpoints_enabled = B_FALSE;
+ rmm_vold_actions_enabled = B_TRUE;
+ } else {
+ rmm_vold_mountpoints_enabled = B_TRUE;
+ rmm_vold_actions_enabled = B_TRUE;
+ }
+
+ if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) {
+ rmm_dbus_error_free(&error);
+
+ /* if HAL's not running, must be root */
+ if (geteuid() != 0) {
+ (void) fprintf(stderr,
+ gettext("%s(%ld) error: must be root to execute\n"),
+ prog_name, prog_pid);
+ return (-1);
+ }
+ }
+
+ if (strcmp(volume_action, "eject") == 0) {
+ action = EJECT;
+ } else if (strcmp(volume_action, "insert") == 0) {
+ action = INSERT;
+
+ if (system_labeled) {
+ /*
+ * create mount point
+ */
+ if (strlen(mnt_userdir) > 0) {
+ if (snprintf(mountpoint, MAXPATHLEN,
+ "%s/%s%s", mnt_zoneroot, volume_mediatype,
+ mnt_userdir) > MAXPATHLEN) {
+ return (-1);
+
+ }
+ (void) makepath(mountpoint, 0700);
+ (void) chown(mountpoint, mnt_uid, mnt_gid);
+ /*
+ * set the top level directory bits to 0755
+ * so user can access it.
+ */
+ if (snprintf(mountpoint, MAXPATHLEN,
+ "%s/%s", mnt_zoneroot,
+ volume_mediatype) <= MAXPATHLEN) {
+ (void) chmod(mountpoint, 0755);
+ }
+ }
+ if (snprintf(mountpoint, MAXPATHLEN,
+ "%s/%s%s/%s", mnt_zoneroot, volume_mediatype,
+ mnt_userdir, volume_name) > MAXPATHLEN) {
+ (void) fprintf(stderr,
+ gettext("%s(%ld) error: path too long\n"),
+ prog_name, prog_pid);
+ return (-1);
+ }
+
+ /* make our mountpoint */
+ (void) makepath(mountpoint, 0755);
+
+ arg_mountpoint = mountpoint;
+ }
+ } else if (strcmp(volume_action, "remount") == 0) {
+ action = REMOUNT;
+ } else if (strcmp(volume_action, "unmount") == 0) {
+ action = UNMOUNT;
+ }
+
+ ret = rmm_action(hal_ctx, volume_symdev, action, 0, 0, 0,
+ arg_mountpoint) ? 0 : 1;
+
+ if (hal_ctx != NULL) {
+ rmm_hal_fini(hal_ctx);
+ }
+
+ return (ret);
+}
+
+
+/*
+ * this should be called after rmm_hal_{mount,unmount,eject}
+ */
+int
+vold_postprocess(LibHalContext *hal_ctx, const char *udi,
+ struct action_arg *aap)
+{
+ int ret = 0;
+
+ /* valid mountpoint required */
+ if ((aap->aa_action == INSERT) || (aap->aa_action == REMOUNT)) {
+ rmm_volume_aa_update_mountpoint(hal_ctx, udi, aap);
+ if ((aap->aa_mountpoint == NULL) ||
+ (strlen(aap->aa_mountpoint) == 0)) {
+ return (1);
+ }
+ }
+
+ if (rmm_vold_mountpoints_enabled) {
+ vold_update_mountpoints(aap);
+ }
+ if (rmm_vold_actions_enabled) {
+ ret = vold_action(aap);
+ }
+
+ return (ret);
+}
+
+/*
+ * update legacy symlinks
+ *
+ * For cdrom:
+ *
+ * /cdrom/<name> -> original mountpoint
+ * /cdrom/cdrom0 -> ./<name>
+ * /cdrom/cdrom -> cdrom0 (only for cdrom0)
+ *
+ * If it's a slice or partition, /cdrom/<name> becomes a directory:
+ *
+ * /cdrom/<name>/s0
+ *
+ * Same for rmdisk and floppy.
+ *
+ * On labeled system (Trusted Solaris), links are in a user directory.
+ */
+static void
+vold_update_mountpoints(struct action_arg *aap)
+{
+ boolean_t is_partition;
+ char part_dir[2 * MAXNAMELEN];
+ char symname_mp[2 * MAXNAMELEN];
+ char symcontents_mp[MAXNAMELEN];
+ char symname[2 * MAXNAMELEN];
+ char symcontents[MAXNAMELEN];
+
+ is_partition = (aap->aa_partname != NULL);
+
+ if (!system_labeled) {
+ if (!is_partition) {
+ /* /cdrom/<name> -> original mountpoint */
+ (void) snprintf(symcontents_mp, sizeof (symcontents_mp),
+ "%s", aap->aa_mountpoint);
+ (void) snprintf(symname_mp, sizeof (symname_mp),
+ "/%s/%s", aap->aa_media, aap->aa_name);
+ } else {
+ /* /cdrom/<name>/slice -> original mountpoint */
+ (void) snprintf(part_dir, sizeof (part_dir),
+ "/%s/%s", aap->aa_media, aap->aa_name);
+ (void) snprintf(symcontents_mp, sizeof (symcontents_mp),
+ "%s", aap->aa_mountpoint);
+ (void) snprintf(symname_mp, sizeof (symname_mp),
+ "/%s/%s/%s", aap->aa_media, aap->aa_name,
+ aap->aa_partname);
+
+ }
+ /* /cdrom/cdrom0 -> ./<name> */
+ (void) snprintf(symcontents, sizeof (symcontents),
+ "./%s", aap->aa_name);
+ (void) snprintf(symname, sizeof (symname),
+ "/%s/%s", aap->aa_media, aap->aa_symdev);
+ } else {
+ if (!is_partition) {
+ /* /cdrom/<user>/<name> -> original mountpoint */
+ (void) snprintf(symcontents_mp, sizeof (symcontents_mp),
+ "%s", aap->aa_mountpoint);
+ (void) snprintf(symname_mp, sizeof (symname_mp),
+ "%s/%s/%s", mnt_zoneroot, aap->aa_media,
+ aap->aa_symdev);
+ } else {
+ /* /cdrom/<user>/<name>/slice -> original mountpoint */
+ (void) snprintf(symcontents_mp, sizeof (symcontents_mp),
+ "%s", aap->aa_mountpoint);
+ (void) snprintf(symname_mp, sizeof (symname_mp),
+ "%s/%s/%s", mnt_zoneroot, aap->aa_media,
+ aap->aa_symdev, aap->aa_partname);
+ }
+
+ /* /cdrom/<user>/cdrom0 -> ./<user>/<name> */
+ (void) snprintf(symcontents, sizeof (symcontents),
+ ".%s/%s", mnt_userdir, aap->aa_name);
+ (void) snprintf(symname, sizeof (symname), "%s/%s/%s",
+ mnt_zoneroot, aap->aa_media, aap->aa_symdev);
+ }
+
+ (void) unlink(symname);
+ (void) unlink(symname_mp);
+ if (is_partition) {
+ (void) rmdir(part_dir);
+ }
+
+ if ((aap->aa_action == INSERT) || (aap->aa_action == REMOUNT)) {
+ (void) mkdir(aap->aa_media, 0755);
+ if (is_partition) {
+ (void) mkdir(part_dir, 0755);
+ }
+ (void) symlink(symcontents_mp, symname_mp);
+ (void) symlink(symcontents, symname);
+ }
+}
+
+
+static int
+vold_action(struct action_arg *aap)
+{
+ action_t action;
+ int result;
+ int do_notify = FALSE;
+ action_t notify_act = EJECT;
+ struct action_arg *aa[2];
+ struct action_arg a1;
+
+ dprintf("%s[%d]: entering action()\n", __FILE__, __LINE__);
+
+ /*
+ * on Trusted Extensions, actions are executed in the user's zone
+ */
+ if (mnt_zoneid > GLOBAL_ZONEID) {
+ pid_t pid;
+ int status;
+ int ifx;
+ int tmpl_fd;
+ int err = 0;
+
+ tmpl_fd = open64(CTFS_ROOT "/process/template",
+ O_RDWR);
+ if (tmpl_fd == -1)
+ return (1);
+
+ /*
+ * Deliver no events, don't inherit,
+ * and allow it to be orphaned.
+ */
+ err |= ct_tmpl_set_critical(tmpl_fd, 0);
+ err |= ct_tmpl_set_informative(tmpl_fd, 0);
+ err |= ct_pr_tmpl_set_fatal(tmpl_fd,
+ CT_PR_EV_HWERR);
+ err |= ct_pr_tmpl_set_param(tmpl_fd,
+ CT_PR_PGRPONLY |
+ CT_PR_REGENT);
+ if (err || ct_tmpl_activate(tmpl_fd)) {
+ (void) close(tmpl_fd);
+ return (1);
+ }
+ switch (pid = fork1()) {
+ case 0:
+ (void) ct_tmpl_clear(tmpl_fd);
+ for (ifx = 0; ifx < _NFILE; ifx++)
+ (void) close(ifx);
+
+ if (zone_enter(mnt_zoneid) == -1)
+ _exit(0);
+
+ /* entered zone, proceed to action */
+ break;
+ case -1:
+ dprintf("fork1 failed \n ");
+ return (1);
+ default :
+ (void) ct_tmpl_clear(tmpl_fd);
+ (void) close(tmpl_fd);
+ if (waitpid(pid, &status, 0) < 0) {
+ dprintf("%s(%ld): waitpid() "
+ "failed (errno %d) \n",
+ prog_name, prog_pid, errno);
+ return (1);
+ }
+ }
+
+ }
+
+ /* only support one action at a time XXX */
+ a1.aa_path = NULL;
+ aa[0] = aap;
+ aa[1] = &a1;
+
+ action = aa[0]->aa_action;
+
+ if (action == CLEAR_MOUNTS) {
+ /*
+ * Remove the notifications files, but don't
+ * notify the client. The "clear_mounts" action
+ * simply clears all existing mounts of a medium's
+ * partitions after a medium has been repartitioned.
+ * Then vold builds a new file system that reflects
+ * the medium's new partition structure and mounts
+ * the new partitions by calling rmmount, and therefore
+ * action(), with the VOLUME_ACTION environment variable
+ * set to "remount".
+ */
+ result = remove_notify_files(aa);
+ result = TRUE;
+ } else if (action == EJECT) {
+ result = remove_notify_files(aa);
+ if (result == TRUE) {
+ do_notify = TRUE;
+ notify_act = EJECT;
+ }
+ } else if (action = INSERT) {
+ result = create_notify_files(aa);
+ if (result == TRUE) {
+ do_notify = TRUE;
+ notify_act = INSERT;
+ }
+ } else if (action == REMOUNT) {
+ result = create_notify_files(aa);
+ if (result == TRUE) {
+ do_notify = TRUE;
+ notify_act = REMOUNT;
+ }
+ } else if (action == UNMOUNT) {
+ result = remove_notify_files(aa);
+ if (result == TRUE) {
+ do_notify = TRUE;
+ notify_act = UNMOUNT;
+ }
+ } else {
+ dprintf("%s[%d]: action(): invalid action: %s\n",
+ __FILE__, __LINE__, action);
+ result = FALSE;
+ }
+
+ if (result == TRUE) {
+ result = notify_clients(notify_act, do_notify);
+ }
+
+ dprintf("%s[%d]: leaving action(), result = %s\n",
+ __FILE__, __LINE__, result_strings[result]);
+
+ if (mnt_zoneid > GLOBAL_ZONEID) {
+ /* exit forked local zone process */
+ _exit(0);
+ }
+
+ if (result == TRUE) {
+ /*
+ * File Manager is running. return 0.
+ * see man page rmmount.conf(4).
+ */
+ return (0);
+ } else {
+ return (1);
+ }
+}
+
+
+/*
+ * Returns NULL if a medium or partition is mountable
+ * and a string stating the reason the medium or partition
+ * can't be mounted if the medium or partition isn't mountable.
+ *
+ * If the volume_name of the medium or partition is one of the
+ * following, the medium or partition isn't mountable.
+ *
+ * unlabeled_<media_type>
+ * unknown_format
+ * password_protected
+ */
+/* ARGSUSED */
+static char *
+not_mountable(struct action_arg *aa)
+{
+ return (NULL);
+}
+
+static int
+create_notify_files(struct action_arg **aa)
+{
+ int ai;
+ char *fstype;
+ char *mount_point;
+ char notify_file[64];
+ char *raw_partitionp;
+ char *reason; /* Why the medium wasn't mounted */
+ int result;
+ char *symdev;
+
+ dprintf("%s[%d]: entering create_notify_files()\n", __FILE__, __LINE__);
+
+ ai = 0;
+ result = FALSE;
+ symdev = aa[ai]->aa_symdev;
+ while ((aa[ai] != NULL) && (aa[ai]->aa_path != NULL)) {
+ if (aa[ai]->aa_mountpoint != NULL) {
+ if (aa[ai]->aa_type) {
+ fstype = aa[ai]->aa_type;
+ } else {
+ fstype = "unknown";
+ }
+ mount_point = aa[ai]->aa_mountpoint;
+ if (aa[ai]->aa_partname != NULL) {
+ /*
+ * Is aa_partname ever NULL?
+ * When time permits, check.
+ * If it is, the action taken
+ * in the else clause could produce
+ * file name conflicts.
+ */
+ sprintf(notify_file, "%s-%s", symdev,
+ aa[ai]->aa_partname);
+ } else {
+ sprintf(notify_file, "%s-0", symdev);
+ }
+ reason = NULL;
+ } else {
+ /*
+ * The partition isn't mounted.
+ */
+ fstype = "none";
+ mount_point = "none";
+ reason = not_mountable(aa[ai]);
+ if (reason != NULL) {
+ sprintf(notify_file, "%s-0", symdev);
+ } else {
+ /*
+ * Either the partition is a backup slice, or
+ * rmmount tried to mount the partition, but
+ * idenf_fs couldn't identify the file system
+ * type; that can occur when rmmount is
+ * trying to mount all the slices in a Solaris
+ * VTOC, and one or more partitions don't have
+ * file systems in them.
+ */
+ if (aa[0]->aa_partname != NULL) {
+ /*
+ * Is aa_partname ever NULL?
+ * When time permits, check.
+ * If it is, the action taken
+ * in the else clause could produce
+ * file name conflicts.
+ */
+ sprintf(notify_file, "%s-%s", symdev,
+ aa[0]->aa_partname);
+ } else {
+ sprintf(notify_file, "%s-0", symdev);
+ }
+ if ((aa[0]->aa_type != NULL) &&
+ (strcmp(aa[0]->aa_type, "backup_slice")
+ == 0)) {
+ reason = "backup_slice";
+ } else {
+ reason = "unformatted_media";
+ }
+ /*
+ * "unformatted_media" should be
+ * changed to "unformmated_medium" for
+ * grammatical correctness, but
+ * "unformatted_media" is now specified
+ * in the interface to filemgr, so the
+ * change can't be made without the
+ * approval of the CDE group.
+ */
+ }
+ }
+ raw_partitionp = aa[0]->aa_rawpath;
+ result = create_one_notify_file(fstype,
+ mount_point,
+ notify_file,
+ raw_partitionp,
+ reason,
+ symdev);
+ ai++;
+ }
+ dprintf("%s[%d]: leaving create_notify_files(), result = %s\n",
+ __FILE__, __LINE__, result_strings[result]);
+ return (result);
+}
+
+static int
+create_one_notify_file(char *fstype,
+ char *mount_point,
+ char *notify_file,
+ char *raw_partitionp,
+ char *reason,
+ char *symdev)
+{
+ /*
+ * For a mounted partition, create a notification file
+ * indicating the mount point, the raw device pathname
+ * of the partition, and the partition's file system
+ * type. For an unmounted partition, create a
+ * notification file containing the reason that the
+ * partition wasn't mounted and the raw device pathname
+ * of the partition.
+ *
+ * Create the file as root in a world-writable
+ * directory that resides in a world-writable directory.
+ *
+ * Handle two possible race conditions that could
+ * allow security breaches.
+ */
+
+ int current_working_dir_fd;
+ int file_descriptor;
+ FILE *filep;
+ int result;
+
+ dprintf("%s[%d]:Entering create_one_notify_file()\n",
+ __FILE__, __LINE__);
+ dprintf("\tcreate_one_notify_file(): fstype = %s\n", fstype);
+ dprintf("\tcreate_one_notify_file(): mount_point = %s\n", mount_point);
+ dprintf("\tcreate_one_notify_file(): notify_file = %s\n", notify_file);
+ dprintf("\tcreate_one_notify_file(): raw_partitionp = %s\n",
+ raw_partitionp);
+ if (reason != NULL) {
+ dprintf("\tcreate_one_notify_file(): reason = %s\n", reason);
+ } else {
+ dprintf("\tcreate_one_notify_file(): reason = NULL\n");
+ }
+ dprintf("\tcreate_one_notify_file(): symdev = %s\n", symdev);
+
+ result = TRUE;
+ /*
+ * Handle Race Condition One:
+ *
+ * If NOTIFY_DIR exists, make sure it is not a symlink.
+ * if it is, remove it and try to create it. Check
+ * again to make sure NOTIFY_DIR isn't a symlink.
+ * If it is, remove it and return without creating
+ * a notification file. The condition can only occur if
+ * someone is trying to break into the system by running
+ * a program that repeatedly creates NOTIFY_DIR as a
+ * symlink. If NOTIFY_DIR exists and isn't a symlink,
+ * change the working directory to NOTIFY_DIR.
+ */
+ current_working_dir_fd = pushdir(NOTIFY_DIR);
+ if (current_working_dir_fd < 0) {
+ (void) makepath(NOTIFY_DIR, 0777);
+ current_working_dir_fd = pushdir(NOTIFY_DIR);
+ if (current_working_dir_fd < 0) {
+ result = FALSE;
+ }
+ }
+ /*
+ * Handle Race Condition Two:
+ *
+ * Create the notification file in NOTIFY_DIR.
+ * Remove any files with the same name that may already be
+ * there, using remove(), as it safely removes directories.
+ * Then open the file O_CREAT|O_EXCL, which doesn't follow
+ * symlinks and requires that the file not exist already,
+ * so the new file actually resides in the current working
+ * directory. Create the file with access mode 644, which
+ * renders it unusable by anyone trying to break into the
+ * system.
+ */
+ if (result == TRUE) {
+ /*
+ * The current working directory is now NOTIFY_DIR.
+ */
+ (void) remove(notify_file);
+ file_descriptor =
+ open(notify_file, O_CREAT|O_EXCL|O_WRONLY, 0644);
+ if (file_descriptor < 0) {
+ dprintf("%s[%d]: can't create %s/%s; %m\n",
+ __FILE__, __LINE__, NOTIFY_DIR, notify_file);
+ result = FALSE;
+ } else {
+ filep = fdopen(file_descriptor, "w");
+ if (filep != NULL) {
+ if (reason == NULL) {
+ (void) fprintf(filep, "%s %s %s",
+ mount_point,
+ raw_partitionp,
+ fstype);
+ (void) fclose(filep);
+ dprintf("%s[%d]: Just wrote %s %s %s to %s\n",
+ __FILE__,
+ __LINE__,
+ mount_point,
+ raw_partitionp,
+ fstype,
+ notify_file);
+ } else {
+ (void) fprintf(filep, "%s %s",
+ reason, raw_partitionp);
+ (void) fclose(filep);
+ dprintf("%s[%d]: Just wrote %s %s to %s\n",
+ __FILE__,
+ __LINE__,
+ reason,
+ raw_partitionp,
+ notify_file);
+ }
+ } else {
+ dprintf("%s[%d]: can't write %s/%s; %m\n",
+ __FILE__, __LINE__,
+ NOTIFY_DIR, notify_file);
+ (void) close(file_descriptor);
+ result = FALSE;
+ }
+ }
+ popdir(current_working_dir_fd);
+ }
+ dprintf("%s[%d]: leaving create_one_notify_file, result = %s\n",
+ __FILE__, __LINE__, result_strings[result]);
+ return (result);
+}
+
+static boolean_t
+notify_clients(action_t action, int do_notify)
+{
+ /*
+ * Notify interested applications of changes in the state
+ * of removable media. Interested applications are those
+ * that create a named pipe in NOTIFY_DIR with a name that
+ * begins with "notify". Open the pipe and write a
+ * character through it that indicates the type of state
+ * change = 'e' for ejections, 'i' for insertions, 'r'
+ * for remounts of the file systems on repartitioned media,
+ * and 'u' for unmounts of file systems.
+ */
+
+ int current_working_dir_fd;
+ DIR *dirp;
+ struct dirent *dir_entryp;
+ size_t len;
+ int fd;
+ char namebuf[MAXPATHLEN];
+ char notify_character;
+ void (*old_signal_handler)();
+ int result;
+ struct stat sb;
+
+ dprintf("%s[%d]: entering notify_clients()\n", __FILE__, __LINE__);
+
+ result = TRUE;
+ /*
+ * Use relative pathnames after changing the
+ * working directory to the notification directory.
+ * Check to make sure that each "notify" file is a
+ * named pipe to make sure that it hasn't changed
+ * its file type, which could mean that someone is
+ * trying to use "notify" files to break into the
+ * system.
+ */
+ if ((current_working_dir_fd = pushdir(NOTIFY_DIR)) < 0) {
+ result = FALSE;
+ }
+ if (result == TRUE) {
+ dirp = opendir(".");
+ if (dirp == NULL) {
+ dprintf("%s[%d]:opendir failed on '.'; %m\n",
+ __FILE__, __LINE__);
+ popdir(current_working_dir_fd);
+ result = FALSE;
+ }
+ }
+ if (result == TRUE) {
+ /*
+ * Read through the directory and write a notify
+ * character to all files whose names start with "notify".
+ */
+ result = FALSE;
+ old_signal_handler = signal(SIGPIPE, SIG_IGN);
+ len = strlen(NOTIFY_NAME);
+ while (dir_entryp = readdir(dirp)) {
+ if (strncmp(dir_entryp->d_name, NOTIFY_NAME, len)
+ != 0) {
+ continue;
+ }
+ result = TRUE;
+ if (do_notify != TRUE) {
+ continue;
+ }
+ (void) sprintf(namebuf, "%s/%s",
+ NOTIFY_DIR, dir_entryp->d_name);
+ if ((fd = open(namebuf, O_WRONLY|O_NDELAY)) < 0) {
+ dprintf("%s[%d]: open failed for %s; %m\n",
+ __FILE__, __LINE__, namebuf);
+ continue;
+ }
+ /*
+ * Check to be sure that the entry is a named pipe.
+ * That closes a small security hole that could
+ * enable unauthorized access to the system root.
+ */
+ if ((fstat(fd, &sb) < 0) || (!S_ISFIFO(sb.st_mode))) {
+ dprintf("%s[%d]: %s isn't a named pipe\n",
+ __FILE__, __LINE__, namebuf);
+
+ (void) close(fd);
+ continue;
+ }
+ notify_character = notify_characters[action];
+ if (write(fd, &notify_character, 1) < 0) {
+ dprintf("%s[%d]: write failed for %s; %m\n",
+ __FILE__, __LINE__, namebuf);
+ (void) close(fd);
+ continue;
+ }
+ (void) close(fd);
+ }
+ (void) closedir(dirp);
+ (void) signal(SIGPIPE, old_signal_handler);
+ popdir(current_working_dir_fd);
+ }
+ dprintf("%s[%d]: leaving notify_clients(), result = %s\n",
+ __FILE__, __LINE__, result_strings[result]);
+ return (result);
+}
+
+static void
+popdir(int fd)
+{
+ /*
+ * Change the current working directory to the directory
+ * specified by fd and close the fd. Exit the program
+ * on failure.
+ */
+ if (fchdir(fd) < 0) {
+ dprintf("%s[%d]: popdir() failed\n", __FILE__, __LINE__);
+ exit(1);
+ }
+ (void) close(fd);
+}
+
+static int
+pushdir(const char *dir)
+{
+ /*
+ * Change the current working directory to dir and
+ * return a file descriptor for the old working
+ * directory.
+ *
+ * Exception handling:
+ *
+ * If dir doesn't exist, leave the current working
+ * directory the same and return -1.
+ *
+ * If dir isn't a directory, remove it, leave the
+ * current working directory the same, and return -1.
+ *
+ * If open() fails on the current working directory
+ * or the chdir operation fails on dir, leave the
+ * current working directory the same and return -1.
+ */
+
+ int current_working_dir_fd;
+ struct stat stat_buf;
+
+ if (lstat(dir, &stat_buf) < 0) {
+ dprintf("%s[%d]: push_dir_and_check(): %s does not exist\n",
+ __FILE__, __LINE__, dir);
+ return (-1);
+ }
+
+ if (!(S_ISDIR(stat_buf.st_mode))) {
+ dprintf("%s[%d]: push_dir_and_check(): %s not a directory.\n",
+ __FILE__, __LINE__, dir);
+ (void) remove(dir);
+ return (-1);
+ }
+ if ((current_working_dir_fd = open(".", O_RDONLY)) < 0) {
+ dprintf("%s[%d]: push_dir_and_check(): can't open %s.\n",
+ __FILE__, __LINE__, dir);
+ return (-1);
+ }
+ if (chdir(dir) < 0) {
+ (void) close(current_working_dir_fd);
+ dprintf("%s[%d]: push_dir_and_check(): can't chdir() to %s.\n",
+ __FILE__, __LINE__, dir);
+ return (-1);
+ }
+ return (current_working_dir_fd);
+}
+
+static boolean_t
+remove_notify_files(struct action_arg **aa)
+{
+ int ai;
+ int current_working_dir_fd;
+ char notify_file[64];
+ int result;
+ char *symdev;
+
+ dprintf("%s[%d]: entering remove_notify_files()\n", __FILE__, __LINE__);
+
+ ai = 0;
+ result = TRUE;
+ symdev = aa[ai]->aa_symdev;
+ while ((result == TRUE) &&
+ (aa[ai] != NULL) &&
+ (aa[ai]->aa_path != NULL)) {
+
+ if (not_mountable(aa[ai])) {
+ sprintf(notify_file, "%s-0", symdev);
+ } else if (aa[ai]->aa_partname != NULL) {
+ /*
+ * Is aa_partname ever NULL?
+ * When time permits, check.
+ * If it is, the action taken
+ * in the else clause could produce
+ * file name conflicts.
+ */
+ sprintf(notify_file, "%s-%s",
+ symdev, aa[0]->aa_partname);
+ } else {
+ sprintf(notify_file, "%s-0", symdev);
+ }
+
+ current_working_dir_fd = pushdir(NOTIFY_DIR);
+ if (current_working_dir_fd < 0) {
+ result = FALSE;
+ }
+ if ((result == TRUE) && (remove(notify_file) < 0)) {
+ dprintf("%s[%d]: remove %s/%s; %m\n",
+ __FILE__, __LINE__, NOTIFY_DIR, notify_file);
+ result = FALSE;
+ }
+ if (current_working_dir_fd != -1) {
+ popdir(current_working_dir_fd);
+ }
+ ai++;
+ }
+ dprintf("%s[%d]: leaving remove_notify_files(), result = %s\n",
+ __FILE__, __LINE__, result_strings[result]);
+
+ return (result);
+}
diff --git a/usr/src/cmd/rmvolmgr/vold.h b/usr/src/cmd/rmvolmgr/vold.h
new file mode 100644
index 0000000000..5a291cdb54
--- /dev/null
+++ b/usr/src/cmd/rmvolmgr/vold.h
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _VOLD_H
+#define _VOLD_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libhal.h>
+
+typedef enum {
+ EJECT,
+ INSERT,
+ REMOUNT,
+ UNMOUNT,
+ CLEAR_MOUNTS,
+ CLOSETRAY
+} action_t;
+
+struct action_arg {
+ action_t aa_action; /* VOLUME_ACTION */
+ char *aa_symdev; /* VOLUME_SYMDEV */
+ char *aa_name; /* VOLUME_NAME */
+ char *aa_path; /* special device in question (block) */
+ char *aa_rawpath; /* special device in question (character) */
+ char *aa_type; /* file system type */
+ char *aa_media; /* type of media */
+ char *aa_partname; /* iff a partition, partition name */
+ char *aa_mountpoint; /* path this file system mounted on */
+};
+
+extern int rmm_debug;
+extern boolean_t rmm_vold_actions_enabled;
+extern boolean_t rmm_vold_mountpoints_enabled;
+
+void vold_init(int argc, char **argv);
+int vold_postprocess(LibHalContext *hal_ctx, const char *udi,
+ struct action_arg *aap);
+int vold_rmmount(int argc, char **argv);
+int volrmmount(int argc, char **argv);
+int volcheck(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VOLD_H */
diff --git a/usr/src/cmd/smserverd/smserver.xml b/usr/src/cmd/smserverd/smserver.xml
index c946d67159..0302d53ac9 100644
--- a/usr/src/cmd/smserverd/smserver.xml
+++ b/usr/src/cmd/smserverd/smserver.xml
@@ -1,15 +1,14 @@
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<!--
- Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
CDDL HEADER START
The contents of this file are subject to the terms of the
- Common Development and Distribution License, Version 1.0 only
- (the "License"). You may not use this file except in compliance
- with the License.
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
or http://www.opensolaris.org/os/licensing.
@@ -34,7 +33,7 @@
Service manifest for rpc.smserverd.
-->
-<service_bundle type='manifest' name='SUNWvolr:smserverd'>
+<service_bundle type='manifest' name='SUNWsmediar:smserverd'>
<service
name='network/rpc/smserver'
diff --git a/usr/src/cmd/svc/profile/generic_limited_net.xml b/usr/src/cmd/svc/profile/generic_limited_net.xml
index da9a4cc2da..1d22817c36 100644
--- a/usr/src/cmd/svc/profile/generic_limited_net.xml
+++ b/usr/src/cmd/svc/profile/generic_limited_net.xml
@@ -60,6 +60,9 @@
<service name='system/dbus' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
+ <service name='system/hal' version='1' type='service'>
+ <instance name='default' enabled='true'/>
+ </service>
<service name='system/identity' version='1' type='service'>
<instance name='domain' enabled='true'/>
</service>
@@ -127,7 +130,7 @@
<service name='system/filesystem/autofs' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
- <service name='system/filesystem/volfs' version='1' type='service'>
+ <service name='system/filesystem/rmvolmgr' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
<service name='system/power' version='1' type='service'>
diff --git a/usr/src/cmd/svc/profile/generic_open.xml b/usr/src/cmd/svc/profile/generic_open.xml
index f06cf8c861..542c759b64 100644
--- a/usr/src/cmd/svc/profile/generic_open.xml
+++ b/usr/src/cmd/svc/profile/generic_open.xml
@@ -57,6 +57,9 @@
<service name='system/dbus' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
+ <service name='system/hal' version='1' type='service'>
+ <instance name='default' enabled='true'/>
+ </service>
<service name='system/identity' version='1' type='service'>
<instance name='domain' enabled='true'/>
</service>
@@ -120,7 +123,7 @@
<service name='system/filesystem/autofs' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
- <service name='system/filesystem/volfs' version='1' type='service'>
+ <service name='system/filesystem/rmvolmgr' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
<service name='system/power' version='1' type='service'>
diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c
index 1963879b94..c83f33cd71 100644
--- a/usr/src/cmd/truss/codes.c
+++ b/usr/src/cmd/truss/codes.c
@@ -69,7 +69,6 @@
#include <sys/kstat.h>
#include <sys/audio.h>
#include <sys/mixer.h>
-#include <sys/vol.h>
#include <sys/cpc_impl.h>
#include <sys/devpoll.h>
#include <sys/strredir.h>
@@ -447,30 +446,6 @@ const struct ioc {
NULL },
{ (uint_t)AUDIO_MIXERCTL_SET_MODE, "AUDIO_MIXERCTL_SET_MODE",
NULL },
- /* volume management (control ioctls) */
- { (uint_t)VOLIOCMAP, "VOLIOCMAP", NULL },
- { (uint_t)VOLIOCUNMAP, "VOLIOCUNMAP", NULL },
- { (uint_t)VOLIOCEVENT, "VOLIOCEVENT", NULL },
- { (uint_t)VOLIOCEJECT, "VOLIOCEJECT", NULL },
- { (uint_t)VOLIOCDGATTR, "VOLIOCDGATTR", NULL },
- { (uint_t)VOLIOCDSATTR, "VOLIOCDSATTR", NULL },
- { (uint_t)VOLIOCDCHECK, "VOLIOCDCHECK", NULL },
- { (uint_t)VOLIOCDINUSE, "VOLIOCDINUSE", NULL},
- { (uint_t)VOLIOCDAEMON, "VOLIOCDAEMON", NULL },
- { (uint_t)VOLIOCFLAGS, "VOLIOCFLAGS", NULL },
- { (uint_t)VOLIOCDROOT, "VOLIOCDROOT", NULL },
- { (uint_t)VOLIOCDSYMNAME, "VOLIOCDSYMNAME", NULL },
- { (uint_t)VOLIOCDSYMDEV, "VOLIOCDSYMDEV", NULL },
- /* volume management (user ioctls) */
- { (uint_t)VOLIOCINUSE, "VOLIOCINUSE", NULL },
- { (uint_t)VOLIOCCHECK, "VOLIOCCHECK", NULL },
- { (uint_t)VOLIOCCANCEL, "VOLIOCCANCEL", NULL },
- { (uint_t)VOLIOCINFO, "VOLIOCINFO", NULL },
- { (uint_t)VOLIOCSATTR, "VOLIOCSATTR", NULL },
- { (uint_t)VOLIOCGATTR, "VOLIOCGATTR", NULL },
- { (uint_t)VOLIOCROOT, "VOLIOCROOT", NULL },
- { (uint_t)VOLIOCSYMNAME, "VOLIOCSYMNAME", NULL },
- { (uint_t)VOLIOCSYMDEV, "VOLIOCSYMDEV", NULL },
/* STREAMS redirection ioctls */
{ (uint_t)SRIOCSREDIR, "SRIOCSREDIR", NULL },
{ (uint_t)SRIOCISREDIR, "SRIOCISREDIR", NULL },
diff --git a/usr/src/cmd/volcheck/Makefile b/usr/src/cmd/volcheck/Makefile
new file mode 100644
index 0000000000..fb82067395
--- /dev/null
+++ b/usr/src/cmd/volcheck/Makefile
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = volcheck
+LOCAL_OBJS = volcheck.o
+RMVOLMGR_OBJS = rmm_common.o vold.o
+OBJS = $(LOCAL_OBJS) $(RMVOLMGR_OBJS)
+LOCAL_SRCS = $(LOCAL_OBJS:%.o=%.c)
+RMVOLGMR_SRCS = $(RMVOLMGR_OBJS:%.o=$(SRC)/cmd/rmvolmgr/%.c)
+SRCS = $(LOCAL_SRCS) $(RMVOLMGR_SRCS)
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/hal/Makefile.hal
+
+LDLIBS += -ldbus-1 -ldbus-glib-1 -lglib-2.0 -lhal -lhal-storage -lcontract
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal
+CPPFLAGS += -I$(SRC)/cmd/rmvolmgr
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTPROG)
+
+rmm_common.o: $(SRC)/cmd/rmvolmgr/rmm_common.c $(SRC)/cmd/rmvolmgr/rmm_common.h
+ $(COMPILE.c) -o $@ $(SRC)/cmd/rmvolmgr/rmm_common.c
+ $(POST_PROCESS_O)
+
+vold.o: $(SRC)/cmd/rmvolmgr/vold.c $(SRC)/cmd/rmvolmgr/vold.h
+ $(COMPILE.c) -o $@ $(SRC)/cmd/rmvolmgr/vold.c
+ $(POST_PROCESS_O)
+
+clean:
+ $(RM) $(OBJS)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/volcheck/volcheck.c b/usr/src/cmd/volcheck/volcheck.c
new file mode 100644
index 0000000000..f4aa7cfa05
--- /dev/null
+++ b/usr/src/cmd/volcheck/volcheck.c
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <strings.h>
+#include <signal.h>
+#include <errno.h>
+#include <libintl.h>
+#include <sys/types.h>
+
+#include "vold.h"
+#include "rmm_common.h"
+
+char *progname = "volcheck";
+
+static void
+usage()
+{
+ fprintf(stderr,
+ gettext("usage: %s [-t #secs -i #secs] [-v] [path | nickname]\n"),
+ progname);
+ fprintf(stderr,
+ gettext("If path is not supplied all media is checked\n"));
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *opts = "itv";
+ int c;
+ boolean_t opt_i = B_FALSE;
+ boolean_t opt_t = B_FALSE;
+ boolean_t opt_v = B_FALSE;
+ LibHalContext *hal_ctx;
+ DBusError error;
+ rmm_error_t rmm_error;
+ int ret = 0;
+
+ vold_init(argc, argv);
+
+ while ((c = getopt(argc, argv, opts)) != EOF) {
+ switch (c) {
+ case 'i':
+ opt_i = B_TRUE;
+ break;
+ case 't':
+ opt_t = B_TRUE;
+ break;
+ case 'v':
+ opt_v = B_TRUE;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("HAL initialization failed: %s\n"),
+ rmm_strerror(&error, rmm_error));
+ rmm_dbus_error_free(&error);
+ return (1);
+ }
+
+ if (optind == argc) {
+ /* no name provided, check all */
+ ret = rmm_rescan(hal_ctx, NULL, B_FALSE);
+ } else {
+ for (; optind < argc; optind++) {
+ if (rmm_rescan(hal_ctx, argv[optind], B_FALSE) != 0) {
+ ret = 1;
+ }
+ }
+ }
+
+ rmm_hal_fini(hal_ctx);
+
+ return (ret);
+}
diff --git a/usr/src/cmd/volmgt/util/eject.c b/usr/src/cmd/volmgt/util/eject.c
deleted file mode 100644
index 5e986a2d7c..0000000000
--- a/usr/src/cmd/volmgt/util/eject.c
+++ /dev/null
@@ -1,1275 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Program to eject one or more pieces of media.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <rpc/types.h>
-#include <sys/stat.h>
-#include <sys/fdio.h>
-#include <sys/dkio.h>
-#include <sys/param.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <locale.h>
-#include <libintl.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <volmgt.h>
-#include <sys/mnttab.h>
-#include <signal.h>
-
-
-
-static char *prog_name = NULL;
-static bool_t force_eject = FALSE;
-static bool_t do_query = FALSE;
-static bool_t no_popup = FALSE;
-static uid_t myuid;
-
-static int work(char *);
-static void usage(void);
-static char *getdefault(void);
-static int ejectit(char *, bool_t);
-static bool_t query(char *, bool_t);
-static bool_t winsysck(struct passwd *);
-static bool_t popup_msg(struct passwd *, char *);
-static bool_t floppy_in_drive(char *, int);
-static bool_t manually_ejectable(char *);
-static bool_t display_busy(char *, bool_t);
-static char *eject_getfullblkname(char *, bool_t);
-extern char *getfullrawname(char *);
-
-/*
- * ON-private libvolmgt routines
- */
-extern int _dev_mounted(char *);
-extern int _dev_unmount(char *);
-extern char *_media_oldaliases(char *);
-extern void _media_printaliases(void);
-
-
-/*
- * Hold over from old eject.
- * returns exit codes: (KEEP THESE - especially important for query)
- * 0 = -n, -d or eject operation was ok, -q = media in drive
- * 1 = -q only = media not in drive
- * 2 = various parameter errors, etc.
- * 3 = eject ioctl failed
- * New Value (2/94)
- * 4 = eject partially succeeded, but now manually remove media
- */
-
-#define EJECT_OK 0
-#define EJECT_NO_MEDIA 1
-#define EJECT_PARM_ERR 2
-#define EJECT_IOCTL_ERR 3
-#define EJECT_MAN_EJ 4
-
-#define CONSOLE "/dev/console"
-#define BIT_BUCKET "/dev/null"
-
-#define EJECT_POPUP_PATH "/usr/dt/lib/eject_popup"
-#define EJECT_POPUP "eject_popup"
-
-#define OW_WINSYSCK_PATH "/usr/openwin/bin/winsysck"
-#define OW_WINSYSCK "winsysck"
-#define OW_WINSYSCK_PROTOCOL "x11"
-
-#define AVAIL_MSG "%s is available\n"
-#define NOT_AVAIL_MSG "%s is not available\n"
-
-#define OK_TO_EJECT_MSG "%s can now be manually ejected\n"
-
-#define FLOPPY_MEDIA_TYPE "floppy"
-#define CDROM_MEDIA_TYPE "cdrom"
-
-#define MEJECT_PROP "s-mejectable"
-#define PROP_TRUE "true"
-
-/*
- * the call to winsysck() may hang if the xserver is running
- * and there are no x-protocalls to be identified. This
- * timeout is to break parent off of the waitpid() waiting on
- * return of winsysck() which will never arrive
- */
-#define TIMEOUT_ON_WAITPID 2
-
-
-int
-main(int argc, char **argv)
-{
- int c;
- const char *opts = "dqfnp";
- char *s;
- int excode;
- int res;
- bool_t err_seen = FALSE;
- bool_t man_eject_seen = FALSE;
- bool_t do_pdefault = FALSE;
- bool_t do_paliases = FALSE;
-
-
-
- (void) setlocale(LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
-
- (void) textdomain(TEXT_DOMAIN);
-
- myuid = getuid();
- (void) seteuid(myuid);
-
- prog_name = argv[0];
-
- /* process arguments */
- while ((c = getopt(argc, argv, opts)) != EOF) {
- switch (c) {
- case 'd':
- do_pdefault = TRUE;
- break;
- case 'q':
- do_query = TRUE;
- break;
- case 'n':
- do_paliases = TRUE;
- break;
- case 'f':
- force_eject = TRUE;
- break;
- case 'p':
- no_popup = TRUE;
- break;
- default:
- usage();
- exit(EJECT_PARM_ERR);
- }
- }
-
- if (do_pdefault) {
- s = getdefault();
- (void) fprintf(stderr,
- gettext("Default device is: %s\n"),
- ((s == NULL) ? gettext("nothing inserted") : s));
- exit(EJECT_OK);
- }
-
- if (do_paliases) {
- _media_printaliases();
- exit(EJECT_OK);
- }
-
- if (argc == optind) {
- /* no argument -- use the default */
- if ((s = getdefault()) == NULL) {
- (void) fprintf(stderr,
- gettext("No default media available\n"));
- exit(EJECT_NO_MEDIA);
- }
- /* (try to) eject default media */
- excode = work(s);
- } else {
- /* multiple things to eject */
- for (; optind < argc; optind++) {
- res = work(argv[optind]);
- if (res == 4) {
- man_eject_seen = TRUE;
- } else if (res != EJECT_OK) {
- err_seen = TRUE;
- }
- }
- if (err_seen) {
- if (do_query)
- excode = res;
- else
- excode = EJECT_IOCTL_ERR;
- } else if (man_eject_seen) {
- excode = EJECT_MAN_EJ;
- } else {
- excode = EJECT_OK;
- }
- }
-
- return (excode);
-}
-
-/*
- * eject's sig alarm
- * This is to knock the parent process off of waitpid(), because
- * if waitpid() fails to return within a couple seconds it never
- * will.
- * Therefor, we do nothing - just return...
- */
-static void
-ej_sig_alrm(int signo)
-{
-#ifdef lint
- signo = signo;
-#endif
- /* do nothing, return to interrupt the waitpid */
-}
-
-
-/*
- * given a directory name find the first char- or block-spcl device under
- * it
- *
- * return the supplied path if no spcl device found
- *
- * NOTE: return value points to a status area overwritten with
- * each call
- */
-static char *
-getrawpart0(char *path)
-{
- static char res[MAXPATHLEN+1];
- int len;
- char wbuf[MAXPATHLEN+1];
- int len_avail;
- char *wptr;
- DIR *dirp;
- struct dirent64 *dp;
- struct stat64 sb;
-
-
-
- /* set up the default and the work buffer */
- if ((len = strlen(path)) >= MAXPATHLEN) {
- return (NULL);
- }
- len_avail = (MAXPATHLEN - len) - 1;
- (void) strcpy(res, path);
- (void) strcpy(wbuf, path);
- wptr = wbuf + len;
- *wptr++ = '/';
-
- /* scan directory */
- if ((dirp = opendir(path)) != NULL) {
- while ((dp = readdir64(dirp)) != NULL) {
- if ((strcmp(dp->d_name, ".") == 0) ||
- (strcmp(dp->d_name, "..") == 0)) {
- continue;
- }
- if (strlen(dp->d_name) > len_avail) {
- /* XXX: just skip this entry?? */
- continue;
- }
- (void) strcpy(wptr, dp->d_name);
- if (stat64(wbuf, &sb) == 0) {
- if (S_ISCHR(sb.st_mode) ||
- S_ISBLK(sb.st_mode)) {
- /* success!! */
- (void) strcpy(res, wbuf);
- break;
- }
- }
- }
- (void) closedir(dirp);
- }
-
- return (res);
-
-}
-
-
-/*
- * the the real work of ejecting (and notifying)
- */
-static int
-work(char *arg)
-{
- char *name;
- char *name1;
- int excode = EJECT_OK;
- bool_t volmgt_is_running;
- struct stat64 sb;
-
-
-
- /* keep track of if vold is or isn't running */
- volmgt_is_running = (volmgt_running() != 0) ? TRUE : FALSE;
-
- /*
- * NOTE: media_findname (effectively) does a "volcheck all" if the
- * name passed in isn't an absolute pathname, or a name under
- * /vol/rdsk. This is not good when the user runs something
- * like "eject fd cd" on an intel, since the cd is "all but manually
- * ejected" (as it should be), but then "cd" is not found, so
- * a "volcheck all" is done, which remounts the floppy!
- *
- * So, we run media_olaliases() first, to try to find the name before
- * running volcheck.
- *
- * on the other hand, if vold is *not* running, then we *just* do the
- * old aliases
- */
-
- /* check to see if name is an alias (e.g. "fd" or "flopy") */
- if ((name1 = _media_oldaliases(arg)) == NULL) {
- name1 = arg;
- }
-
- if (volmgt_is_running) {
-
- /*
- * name is not an alias -- check for abs. path or
- * /vol/rdsk name
- */
- if ((name = media_findname(name1)) == NULL) {
- /*
- * name is not an alias, an absolute path, or a name
- * under /vol/rdsk -- let's just use the name given
- */
- name = name1;
- } else {
- /*
- * we have to check for a directory name being
- * returned from media_findname(), changing it
- * to a devname if it is
- */
- if (stat64(name, &sb) == 0) {
- if (S_ISDIR(sb.st_mode)) {
- if ((name1 = getrawpart0(name)) !=
- NULL) {
- name = name1;
- }
- }
- }
- }
-
- } else {
-
- /* vold *not* running -- try to do what we can */
- name = name1;
- }
-
- /*
- * Since eject is a suid root program, we must make sure
- * that the user running us is allowed to eject the media.
- * All a user has to do to issue the eject ioctl is open
- * the file for reading, so that's as restrictive as we'll be.
- */
-
- /*
- * Two cases for name. One is like "floppy", access() will fail
- * for sure. If do_query==1, we should return EJECT_NO_MEDIA instead
- * of EJECT_PARM_ERR. The other is like /vol/dev/rdiskette0 and
- * access() will be ok since it is a directory
- * in the schema of things for volmgmt, we should fail that the same
- * way too.
- */
- if (access(name, R_OK) != 0) {
- if (do_query) {
- (void) fprintf(stderr, gettext("%s: no media\n"), name);
- return (EJECT_NO_MEDIA);
- } else {
- perror(name);
- return (EJECT_PARM_ERR);
- }
- }
-
- if (do_query) {
- if ((stat64(name, &sb) == 0) && S_ISDIR(sb.st_mode)) {
- /* don' t let directory name go through query() code */
- (void) fprintf(stderr, gettext("%s: no media\n"), name);
- return (EJECT_NO_MEDIA);
- }
- if (!query(name, TRUE)) {
- excode = EJECT_NO_MEDIA;
- }
- } else {
- excode = ejectit(name, volmgt_is_running);
- }
- return (excode);
-}
-
-
-static void
-usage(void)
-{
- (void) fprintf(stderr,
- gettext("usage: %s [-fndq] [name | nickname]\n"),
- prog_name);
- (void) fprintf(stderr,
- gettext("options:\t-f force eject\n"));
- (void) fprintf(stderr,
- gettext("\t\t-n show nicknames\n"));
- (void) fprintf(stderr,
- gettext("\t\t-d show default device\n"));
- (void) fprintf(stderr,
- gettext("\t\t-q query for media present\n"));
- (void) fprintf(stderr,
- gettext("\t\t-p do not call eject_popup\n"));
-}
-
-
-static int
-ejectit(char *name, bool_t volmgt_is_running)
-{
- int fd, r;
- FILE *console_fp;
- bool_t mejectable = FALSE; /* manually ejectable */
- int result = EJECT_OK;
- struct passwd *pw = NULL;
- bool_t do_manual_console_message = FALSE;
- bool_t volume_is_not_managed;
- char path[MAXPATHLEN];
- char *absname = name;
-
- if (realpath(name, path) != NULL)
- absname = path;
-
- volume_is_not_managed = !volmgt_is_running ||
- (!volmgt_ownspath(absname) && volmgt_symname(name) == NULL);
-
- /*
- * If volume management is either not running or not being managed by
- * vold, and the device is mounted, we try to umount the device. If we
- * fail, we give up, unless he used the -f flag.
- */
-
- if (volume_is_not_managed && _dev_mounted(name)) {
- (void) seteuid(0);
- r = _dev_unmount(name);
- (void) seteuid(myuid);
- if (r == 0) {
- if (!force_eject) {
- (void) fprintf(stderr,
-gettext("WARNING: can not unmount %s, the file system is (probably) busy\n"),
- name);
- return (EJECT_PARM_ERR);
- } else {
- (void) fprintf(stderr,
-gettext("WARNING: %s has a mounted filesystem, ejecting anyway\n"),
- name);
- }
- }
- }
-
- /*
- * Require O_NDELAY for when floppy is not formatted
- * will still id floppy in drive
- */
-
- if (volume_is_not_managed) {
- /*
- * make sure we are dealing with a raw device
- *
- * XXX: NOTE: results from getfullrawname()
- * really should be free()d when no longer
- * in use
- */
- name = getfullrawname(name);
- }
-
- if ((fd = open(name, O_RDONLY | O_NDELAY)) < 0) {
- if (errno == EBUSY) {
- (void) fprintf(stderr,
-gettext("%s is busy (try 'eject floppy' or 'eject cdrom'?)\n"),
- name);
- return (EJECT_PARM_ERR);
- }
- perror(name);
- return (EJECT_PARM_ERR);
- }
-
- /* see if media is manually ejectable (i.e. we can't do it) */
- if (volume_is_not_managed == FALSE) {
- mejectable = manually_ejectable(name);
- }
-
- /* try to eject the volume */
- if (ioctl(fd, DKIOCEJECT, 0) < 0) {
-
- /* check on why eject failed */
-
- /* check for no floppy in manually ejectable drive */
- if ((errno == ENOSYS) && volume_is_not_managed &&
- !floppy_in_drive(name, fd)) {
- /* use code below to handle "not present" */
- errno = ENXIO;
- }
-
- /*
- * Dump this message to stderr. This handles the
- * case where the window system is not running
- * and also works in case the user has run this
- * via an rlogin to the remote volmgt console.
- */
- if (errno == ENOSYS || errno == ENOTSUP) {
- (void) fprintf(stderr, gettext(OK_TO_EJECT_MSG), name);
- }
-
- if ((errno == ENOSYS || errno == ENOTSUP) &&
- (volume_is_not_managed || mejectable)) {
- /*
- * Make sure we know who *really* fired up this
- * command. We'll need this information to connect
- * to the user X display.
- */
-
- pw = getpwuid(myuid);
-
-#ifdef DEBUG
- if (pw != NULL) {
- (void) fprintf(stderr,
- "DEBUG: ejectit: username = '%s'\n",
- pw->pw_name);
- (void) fprintf(stderr,
- "DEBUG: ejectit: uid = %d\n", pw->pw_uid);
- (void) fprintf(stderr,
- "DEBUG: ejectit: gid = %d\n", pw->pw_gid);
- (void) fprintf(stderr,
- "DEBUG: ejectit: euid = %ld\n", geteuid());
- (void) fprintf(stderr,
- "DEBUG: ejectit: egid = %ld\n", getegid());
- } else {
- (void) fprintf(stderr,
- "DEBUG: ejectit: getpwuid() failed\n");
- }
-#endif
-
- /* if user doesn't want popup then stop here */
- if (no_popup) {
- do_manual_console_message = TRUE;
- }
-
- /*
- * If user is running some X windows system
- * we'll display a popup to the console.
- * If not, dump message to console.
- *
- * (To keep from having to actually check for X
- * running, we'll just try to run the popup, assuming
- * it will fail if windows are not running.)
- */
- if (!do_manual_console_message) {
- if ((access(EJECT_POPUP_PATH, X_OK) != 0) ||
- (access(OW_WINSYSCK_PATH, X_OK) != 0) ||
- (pw == NULL)) {
- do_manual_console_message = TRUE;
- }
- }
-
- if (!do_manual_console_message) {
- if (!winsysck(pw)) {
- do_manual_console_message = TRUE;
- }
- }
-
- if (!do_manual_console_message) {
- if (!popup_msg(pw, name)) {
- do_manual_console_message = TRUE;
- }
- }
- /*
- * only output to console if requested and it's
- * not the same as stderr
- */
- if (do_manual_console_message) {
- char *ttynm = ttyname(fileno(stderr));
-
- if ((ttynm != NULL) &&
- (strcmp(ttynm, CONSOLE) != 0)) {
- (void) seteuid(0);
- console_fp = fopen(CONSOLE, "a");
- (void) seteuid(myuid);
- if (console_fp != NULL) {
- (void) fprintf(console_fp,
- gettext(OK_TO_EJECT_MSG),
- name);
- (void) fclose(console_fp);
- }
- }
- }
-
- /*
- * keep track of the fact that this is a manual
- * ejection
- */
- result = EJECT_MAN_EJ;
-
- } else if (errno == EBUSY) {
- /*
- * if our pathname is s slice (UFS is great) then
- * check to see what really is busy
- */
- if (!display_busy(name, volmgt_is_running)) {
- perror(name);
- }
- result = EJECT_IOCTL_ERR;
-
- } else if ((errno == EAGAIN) || (errno == ENODEV) ||
- (errno == ENXIO)) {
- (void) fprintf(stderr,
- gettext("%s not present in a drive\n"),
- name);
- result = EJECT_OK;
- } else {
- perror(name);
- result = EJECT_IOCTL_ERR;
- }
- }
-
- (void) close(fd);
- return (result);
-}
-
-
-/*
- * return TRUE if a floppy is in the drive, FALSE otherwise
- *
- * this routine assumes that the file descriptor passed in is for
- * a floppy disk. this works because it's only called if the device
- * is "manually ejectable", which only (currently) occurs for floppies.
- */
-static bool_t
-floppy_in_drive(char *name, int fd)
-{
- int ival = 0; /* ioctl return value */
- bool_t rval = FALSE; /* return value */
-
-
- if (ioctl(fd, FDGETCHANGE, &ival) >= 0) {
- if (!(ival & FDGC_CURRENT)) {
- rval = TRUE; /* floppy is present */
- }
- } else {
- /* oh oh -- the ioctl failed -- it's not a floppy */
- (void) fprintf(stderr, gettext("%s is not a floppy disk\n"),
- name);
- }
-
- return (rval);
-}
-
-
-/*
- * display a "busy" message for the supplied pathname
- *
- * if the pathname is not a slice, then just display a busy message
- * else if the pathname is some slice subdirectory then look for the
- * *real* culprits
- *
- * if this is not done then the user can get a message like
- * /vol/dev/rdsk/c0t6d0/solaris_2_5_sparc/s5: Device busy
- * when they try to eject "cdrom0", but "s0" (e.g.) may be the only busy
- * slice
- *
- * return TRUE iff we printed the appropriate error message, else
- * return FALSE (and caller will print error message itself)
- */
-static bool_t
-display_busy(char *path, bool_t vm_running)
-{
- int errno_save = errno; /* to save errno */
- char *blk; /* block name */
- FILE *fp = NULL; /* for scanning mnttab */
- struct mnttab mref; /* for scanning mnttab */
- struct mnttab mp; /* for scanning mnttab */
- bool_t res = FALSE; /* return value */
- char busy_base[MAXPATHLEN]; /* for keeping base dir name */
- uint_t bblen; /* busy_base string length */
- char *cp; /* for truncating path */
-
-
-
-#ifdef DEBUG
- (void) fprintf(stderr, "display_busy(\"%s\"): entering\n", path);
-#endif
-
- /*
- * get the block pathname.
- * eject_getfullblkname returns NULL or pathname which
- * has length < MAXPATHLEN.
- */
- blk = eject_getfullblkname(path, vm_running);
- if (blk == NULL)
- goto dun;
-
- /* open mnttab for scanning */
- if ((fp = fopen(MNTTAB, "r")) == NULL) {
- /* can't open mnttab!? -- give up */
- goto dun;
- }
-
- (void) memset((void *)&mref, '\0', sizeof (struct mnttab));
- mref.mnt_special = blk;
- if (getmntany(fp, &mp, &mref) == 0) {
- /* we found our entry -- we're done */
- goto dun;
- }
-
- /* perhaps we have a sub-slice (which is what we exist to test for) */
-
- /* create a base pathname */
- (void) strcpy(busy_base, blk);
- if ((cp = strrchr(busy_base, '/')) == NULL) {
- /* no last slash in pathname!!?? -- give up */
- goto dun;
- }
- *cp = '\0';
- bblen = strlen(busy_base);
- /* bblen = (uint)(cp - busy_base); */
-
- /* scan for matches */
- rewind(fp); /* rescan mnttab */
- while (getmntent(fp, &mp) == 0) {
- /*
- * work around problem where '-' in /etc/mnttab for
- * special device turns to NULL which isn't expected
- */
- if (mp.mnt_special == NULL)
- mp.mnt_special = "-";
- if (strncmp(busy_base, mp.mnt_special, bblen) == 0) {
- res = TRUE;
- (void) fprintf(stderr, "%s: %s\n", mp.mnt_special,
- strerror(EBUSY));
- }
- }
-
-dun:
- if (fp != NULL) {
- (void) fclose(fp);
- }
-#ifdef DEBUG
- (void) fprintf(stderr, "display_busy: returning %s\n",
- res ? "TRUE" : "FALSE");
-#endif
- errno = errno_save;
- return (res);
-}
-
-
-/*
- * In my experience with removable media drivers so far... the
- * most reliable way to tell if a piece of media is in a drive
- * is simply to open it. If the open works, there's something there,
- * if it fails, there's not. We check for two errnos which we
- * want to interpret for the user, ENOENT and EPERM. All other
- * errors are considered to be "media isn't there".
- *
- * return TRUE if media found, else FALSE (XXX: was 0 and -1)
- */
-static bool_t
-query(char *name, bool_t doprint)
-{
- int fd;
- int rval; /* FDGETCHANGE return value */
- enum dkio_state state;
-
- if ((fd = open(name, O_RDONLY|O_NONBLOCK)) < 0) {
- if ((errno == EPERM) || (errno == ENOENT)) {
- if (doprint) {
- perror(name);
- }
- } else {
- if (doprint) {
- (void) fprintf(stderr, gettext(NOT_AVAIL_MSG),
- name);
- }
- }
- return (FALSE);
- }
-
- rval = 0;
- if (ioctl(fd, FDGETCHANGE, &rval) >= 0) {
- /* hey, it worked, what a deal, it must be a floppy */
- (void) close(fd);
- if (!(rval & FDGC_CURRENT)) {
- if (doprint) {
- (void) fprintf(stderr, gettext(AVAIL_MSG),
- name);
- }
- return (TRUE);
- }
- if (rval & FDGC_CURRENT) {
- if (doprint) {
- (void) fprintf(stderr, gettext(NOT_AVAIL_MSG),
- name);
- }
- return (FALSE);
- }
- }
-
-again:
- state = DKIO_NONE;
- if (ioctl(fd, DKIOCSTATE, &state) >= 0) {
- /* great, the fancy ioctl is supported. */
- if (state == DKIO_INSERTED) {
- if (doprint) {
- (void) fprintf(stderr, gettext(AVAIL_MSG),
- name);
- }
- (void) close(fd);
- return (TRUE);
- }
- if (state == DKIO_EJECTED) {
- if (doprint) {
- (void) fprintf(stderr, gettext(NOT_AVAIL_MSG),
- name);
- }
- (void) close(fd);
- return (FALSE);
- }
- /*
- * Silly retry loop.
- */
- (void) sleep(1);
- goto again;
- }
- (void) close(fd);
-
- /*
- * Ok, we've tried the non-blocking/ioctl route. The
- * device doesn't support any of our nice ioctls, so
- * we'll just say that if it opens it's there, if it
- * doesn't, it's not.
- */
- if ((fd = open(name, O_RDONLY)) < 0) {
- if (doprint) {
- (void) fprintf(stderr, gettext(NOT_AVAIL_MSG), name);
- }
- return (FALSE);
- }
-
- (void) close(fd);
- if (doprint) {
- (void) fprintf(stderr, gettext(AVAIL_MSG), name);
- }
- return (TRUE); /* success */
-}
-
-
-/*
- * The assumption is that someone typed eject to eject some piece
- * of media that's currently in a drive. So, what we do is
- * check for floppy then cdrom. If there's nothing in either,
- * we just return NULL.
- */
-static char *
-getdefault(void)
-{
- char *s;
-
-
- /* if vold running then ask it about a floppy, then a cdrom */
- if (volmgt_running()) {
- if ((s = media_findname(FLOPPY_MEDIA_TYPE)) != NULL) {
- if (query(s, FALSE)) {
- return (s);
- }
- }
- if ((s = media_findname(CDROM_MEDIA_TYPE)) != NULL) {
- if (query(s, FALSE)) {
- return (s);
- }
- }
- }
-
- /* no match yet -- try non-volmgt guesses */
- if ((s = _media_oldaliases(FLOPPY_MEDIA_TYPE)) != NULL) {
- if (query(s, FALSE)) {
- return (s);
- }
- }
-
- /* no default device */
- return (NULL);
-}
-
-
-/*
- * Check to see if the specified device is manually ejectable, using
- * the media_getattr() call
- */
-static bool_t
-manually_ejectable(char *dev_path)
-{
- char *eprop;
-
-
- if ((eprop = media_getattr(dev_path, MEJECT_PROP)) == 0) {
- /* equivalent to FALSE ? */
- return (FALSE);
- }
-
- /* return result based on string returned */
- return ((strcmp(eprop, PROP_TRUE) == 0) ? TRUE : FALSE);
-
-}
-
-
-/*
- * Use a popup window to display the "manually ejectable"
- * message for X86 machines.
- *
- * return flase if the popup fails, else return TRUE
- */
-static bool_t
-popup_msg(struct passwd *pw, char *name)
-{
- pid_t pid;
- int exit_code = -1;
- bool_t ret_val = FALSE;
- int fd;
- char ld_lib_path[MAXPATHLEN];
- char *home_dir;
-
- /*
- * fork a simple X Windows program to display gui for
- * notifying the user that the specified media must be
- * manually removed.
- */
-
- if ((pid = fork()) < 0) {
- (void) fprintf(stderr,
- gettext("error: can't fork a process (errno %d)\n"),
- errno);
- goto dun;
- }
-
- if (pid == 0) {
-
- /*
- * Error messages to console
- */
-
- (void) seteuid(0);
- fd = open(CONSOLE, O_RDWR);
- (void) seteuid(myuid);
- if (fd >= 0) {
- (void) dup2(fd, fileno(stdin));
- (void) dup2(fd, fileno(stdout));
- (void) dup2(fd, fileno(stderr));
- }
-
- /*
- * Set up the users environment.
- */
-
- (void) putenv("DISPLAY=:0.0");
- (void) putenv("OPENWINHOME=/usr/openwin");
-
- (void) sprintf(ld_lib_path, "LD_LIBRARY_PATH=%s",
- "/usr/openwin/lib");
- (void) putenv(ld_lib_path);
-
- /*
- * We need to set $HOME so the users .Xauthority file
- * can be located. This is especially needed for a user
- * user MIT Magic Cookie authentication security.
- */
-
- home_dir = malloc(strlen(pw->pw_dir) + 6);
- if (home_dir == NULL) {
- perror("malloc");
- exit(1);
- }
- (void) strcpy(home_dir, "HOME=");
- (void) strcat(home_dir, pw->pw_dir);
- (void) putenv(home_dir);
-
- /*
- * We need the X application to be able to connect to
- * the user's display so we better run as if we are
- * the user (effectively).
- * Don't want x program doing anything nasty.
- *
- * Note - have to set gid stuff first as effective uid
- * must belong to root for this to work correctly.
- */
-
- (void) seteuid(0);
- (void) setgid(pw->pw_gid);
- (void) setegid(pw->pw_gid);
- (void) setuid(pw->pw_uid);
- (void) seteuid(pw->pw_uid);
-
-#ifdef DEBUG
- (void) fprintf(stderr,
- "DEBUG: \"%s\" being execl'ed with name = \"%s\"\n",
- EJECT_POPUP_PATH, name);
-#endif
-
- (void) execl(EJECT_POPUP_PATH, EJECT_POPUP, "-n", name, NULL);
-
- (void) fprintf(stderr,
- gettext("error: exec of \"%s\" failed (errno = %d)\n"),
- EJECT_POPUP_PATH, errno);
- exit(-1);
-
- }
-
- /* the parent -- wait for the child */
- if (waitpid(pid, &exit_code, 0) == pid) {
- if (WIFEXITED(exit_code)) {
- if (WEXITSTATUS(exit_code) == 0) {
- ret_val = TRUE;
- }
- }
- }
-
-dun:
- /* all done */
-#ifdef DEBUG
- (void) fprintf(stderr, "DEBUG: popup_msg() returning %s\n",
- ret_val ? "TRUE" : "FALSE");
-#endif
- return (ret_val);
-}
-
-/*
- * Use a popup window to display the "manually ejectable"
- * message for X86 machines.
- *
- * return flase if the popup fails, else return TRUE
- */
-static bool_t
-winsysck(struct passwd *pw)
-{
- pid_t pid;
- int exit_code = -1;
- bool_t ret_val = FALSE;
- int fd;
- char *home_dir;
- char ld_lib_path[MAXPATHLEN];
-
- if ((pid = fork()) < 0) {
- (void) fprintf(stderr,
- gettext("error: can't fork a process (errno %d)\n"),
- errno);
- goto dun;
- }
-
- if (pid == 0) {
-
- /*
- * error messages to console
- */
-
-#ifndef DEBUG
- if ((fd = open(BIT_BUCKET, O_RDWR)) >= 0) {
- (void) dup2(fd, fileno(stdin));
- (void) dup2(fd, fileno(stdout));
- (void) dup2(fd, fileno(stderr));
- }
-#endif
-
- /*
- * set up the users environment
- */
- (void) putenv("DISPLAY=:0.0");
- (void) putenv("OPENWINHOME=/usr/openwin");
-
- (void) sprintf(ld_lib_path, "LD_LIBRARY_PATH=%s",
- "/usr/openwin/lib");
- (void) putenv(ld_lib_path);
-
- /*
- * we need to set $HOME so the users .Xauthority file
- * can be located. This is especially needed for a user
- * user MIT Magic Cookie authentication security
- */
- home_dir = malloc(strlen(pw->pw_dir) + 6);
- if (home_dir == NULL) {
- perror("malloc");
- exit(-1);
- }
- (void) strcpy(home_dir, "HOME=");
- (void) strcat(home_dir, pw->pw_dir);
- (void) putenv(home_dir);
-
- /*
- * We need the X application to be able to connect to
- * the user's display so we better run as if we are
- * the user (effectively).
- * Don't want x program doing anything nasty.
- *
- * Note - have to set gid stuff first as effective uid
- * must belong to root for this to work correctly.
- */
- (void) seteuid(0);
- (void) setgid(pw->pw_gid);
- (void) setegid(pw->pw_gid);
- (void) setuid(pw->pw_uid);
- (void) seteuid(pw->pw_uid);
-
-#ifdef DEBUG
- (void) fprintf(stderr,
- "DEBUG: \"%s\" being execl'ed with protocol = \"%s\"\n",
- OW_WINSYSCK_PATH, OW_WINSYSCK_PROTOCOL);
-#endif
-
- (void) execl(OW_WINSYSCK_PATH, OW_WINSYSCK,
- OW_WINSYSCK_PROTOCOL, NULL);
-
- (void) fprintf(stderr,
- gettext("error: exec of \"%s\" failed (errno = %d)\n"),
- OW_WINSYSCK_PATH, errno);
- exit(-1);
-
- }
-
- /*
- * parent:
- * set up an alarm because the child may block forever
- * when an x-protocol cannot be identified. This can
- * happen on headless darwins (because they have a
- * video board intergrated into its mother board).
- */
- /* LINTED */
- if (signal(SIGALRM, ej_sig_alrm) == SIG_ERR) {
- perror("signal(SIGALRM) error ");
- return (ret_val);
- }
-
- alarm(TIMEOUT_ON_WAITPID);
-
- /* the parent -- wait for the child or the alarm */
- if (waitpid(pid, &exit_code, 0) == pid) {
- alarm(0);
- if (WIFEXITED(exit_code)) {
- if (WEXITSTATUS(exit_code) == 0) {
- ret_val = TRUE;
- }
- }
- } else {
- /* alarm went off, kill pid */
- if (kill(pid, SIGKILL) != 0) {
- perror("kill(pid, SIGKILL) failed:\n");
- }
- }
-
-dun:
- /* all done */
-#ifdef DEBUG
- (void) fprintf(stderr, "DEBUG: winsysck() returning %s\n",
- ret_val ? "TRUE" : "FALSE");
-#endif
- return (ret_val);
-}
-
-
-/*
- * this routine will return the volmgt block name given the volmgt
- * raw (char spcl) name
- *
- * if anything but a volmgt raw pathname is supplied that pathname will
- * be returned
- *
- * NOTE: non-null return value will point to static data, overwritten with
- * each call
- *
- * e.g. names starting with "/vol/r" will be changed to start with "/vol/",
- * and names starting with "vol/dev/r" will be changed to start with
- * "/vol/dev/"
- */
-static char *
-eject_getfullblkname(char *path, bool_t vm_running)
-{
- char raw_root[MAXPATHLEN];
- const char *vm_root;
- static char res_buf[MAXPATHLEN];
- uint_t raw_root_len;
-
-#ifdef DEBUG
- (void) fprintf(stderr, "eject_getfullblkname(\"%s\", %s): entering\n",
- path, vm_running ? "TRUE" : "FALSE");
-#endif
- /*
- * try different strategies based on whether or not vold is running
- */
- if (vm_running) {
-
- /* vold IS running -- look in /vol (or its alternate) */
-
- /* get vm root dir */
- vm_root = volmgt_root();
-
- /* get first volmgt root dev directory (and its length) */
- (void) sprintf(raw_root, "%s/r", vm_root);
- raw_root_len = strlen(raw_root);
-
- /* see if we have a raw volmgt pathname (e.g. "/vol/r*") */
- if (strncmp(path, raw_root, raw_root_len) == 0) {
- if (snprintf(res_buf, sizeof (res_buf), "%s/%s",
- vm_root, path + raw_root_len) >= sizeof (res_buf)) {
- return (NULL);
- }
- goto dun; /* found match in /vol */
- }
-
- /* get second volmgt root dev directory (and its length) */
- (void) sprintf(raw_root, "%s/dev/r", vm_root);
- raw_root_len = strlen(raw_root);
-
- /* see if we have a raw volmgt pathname (e.g. "/vol/dev/r*") */
- if (strncmp(path, raw_root, raw_root_len) == 0) {
- if (snprintf(res_buf, sizeof (res_buf), "%s/dev/%s",
- vm_root, path + raw_root_len) >= sizeof (res_buf)) {
- return (NULL);
- }
- goto dun; /* found match in /vol/dev */
- }
-
- } else {
-
- /* vold is NOT running -- look in /dev */
-
- (void) strcpy(raw_root, "/dev/r");
- raw_root_len = strlen(raw_root);
- if (strncmp(path, raw_root, raw_root_len) == 0) {
- if (snprintf(res_buf, sizeof (res_buf), "/dev/%s",
- path + raw_root_len) >= sizeof (res_buf)) {
- return (NULL);
- }
- goto dun; /* found match in /dev */
- }
- }
-
- /* no match -- return what we got */
- (void) strcpy(res_buf, path);
-
-dun:
-#ifdef DEBUG
- (void) fprintf(stderr, "eject_getfullblkname: returning %s\n",
- res_buf ? res_buf : "<null ptr>");
-#endif
- return (res_buf);
-}
diff --git a/usr/src/cmd/volmgt/util/volcheck.c b/usr/src/cmd/volmgt/util/volcheck.c
deleted file mode 100644
index 06400f335c..0000000000
--- a/usr/src/cmd/volmgt/util/volcheck.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Program to kick volume management so it can check to see
- * if media has been inserted.
- *
- * Exit codes:
- * -1 - error
- * 0 - no media found
- * 1 - media found
- *
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <locale.h>
-#include <fcntl.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/vol.h>
-
-char *prog_name;
-void usage();
-
-#define MAX_TIME 28800 /* 8 hours */
-#define MIN_INTVL 1
-#define DEFAULT_INTVL 2
-
-int poll_time; /* total number of seconds to poll the device */
-int poll_interval = DEFAULT_INTVL; /* interval to poll (seconds) */
-int verbose;
-
-int work(int, char **);
-
-
-int
-main(int argc, char **argv)
-{
- extern char *optarg;
- extern int optind;
- int c;
- char *av[1];
- int rval;
-
- (void) setlocale(LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
-
- (void) textdomain(TEXT_DOMAIN);
-
- prog_name = argv[0];
-
- /* process arguments */
- while ((c = getopt(argc, argv, "t:i:v")) != EOF) {
- switch (c) {
- case 't':
- poll_time = atoi(optarg);
- if (poll_time > MAX_TIME) {
- fprintf(stderr, gettext(
- "Maximum time allowed is %d seconds\n"),
- MAX_TIME);
- exit(-1);
- }
- break;
- case 'i':
- poll_interval = atoi(optarg);
- if (poll_interval < MIN_INTVL) {
- fprintf(stderr, gettext(
- "Minimum interval is %d seconds\n"),
- MIN_INTVL);
- exit(-1);
- }
- break;
- case 'v':
- verbose = 1;
- break;
- default:
- usage();
- exit(-1);
- }
- }
-
- if (argc == optind) {
- /*
- * If there's no argument, use the default
- * device for checking.
- */
- av[0] = NULL;
- rval = work(1, av);
- } else {
- rval = work(argc - optind, &argv[optind]);
- }
-
- return (rval);
-}
-
-void
-usage()
-{
- fprintf(stderr,
- gettext("usage: %s [-t #secs -i #secs] [-v] [path]\n"), prog_name);
- fprintf(stderr,
- gettext("If path is not supplied all media is checked\n"));
-}
-
-/*
- * Open the volume management control device and send the dev_t of
- * the device the user has named.
- *
- * It might be nice to someday parse the /etc/vold.conf file and
- * let the user specify "symbolic" device names. We don't do
- * that yet.
- */
-int
-work(int ac, char **av)
-{
- extern int volmgt_check(char *);
-
- int i;
- int rval;
-
-
-
- if (poll_time > 0) {
-
- /* this is the time'd case. */
- while (poll_time > 0) {
- for (i = 0; i < ac; i++) {
-
- rval = volmgt_check(av[i]);
- if (verbose && av[i]) {
- if (rval) {
- printf(gettext(
- "%s has media\n"), av[i]);
- } else {
- printf(gettext(
- "%s has no media\n"),
- av[i]);
- }
- }
- if (verbose && (av[i] == NULL)) {
- if (rval) {
- printf(gettext(
- "media was found\n"));
- } else {
- printf(gettext(
- "no media was found\n"));
- }
- }
- }
- sleep(poll_interval);
- poll_time -= poll_interval;
- }
- rval = 0; /* doesn't really make sense in the timed case */
- } else {
-
- /* this is the one-shot case */
- for (i = 0; i < ac; i++) {
- rval = volmgt_check(av[i]);
- if (verbose && av[i]) {
- if (rval) {
- printf(gettext(
- "%s has media\n"), av[i]);
- } else {
- printf(gettext(
- "%s has no media\n"),
- av[i]);
- }
- }
- if (verbose && (av[i] == NULL)) {
- if (rval) {
- printf(gettext(
- "media was found\n"));
- } else {
- printf(gettext(
- "no media was found\n"));
- }
- }
- }
- }
- return (rval);
-}
diff --git a/usr/src/cmd/volrmmount/Makefile b/usr/src/cmd/volrmmount/Makefile
new file mode 100644
index 0000000000..0c0b6c7fdb
--- /dev/null
+++ b/usr/src/cmd/volrmmount/Makefile
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = volrmmount
+LOCAL_OBJS = volrmmount.o
+RMVOLMGR_OBJS = rmm_common.o vold.o
+OBJS = $(LOCAL_OBJS) $(RMVOLMGR_OBJS)
+LOCAL_SRCS = $(LOCAL_OBJS:%.o=%.c)
+RMVOLGMR_SRCS = $(RMVOLMGR_OBJS:%.o=$(SRC)/cmd/rmvolmgr/%.c)
+SRCS = $(LOCAL_SRCS) $(RMVOLMGR_SRCS)
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/hal/Makefile.hal
+
+LDLIBS += -ldbus-1 -ldbus-glib-1 -lglib-2.0 -lhal -lhal-storage -lcontract
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal
+CPPFLAGS += -I$(SRC)/cmd/rmvolmgr
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTPROG)
+
+rmm_common.o: $(SRC)/cmd/rmvolmgr/rmm_common.c $(SRC)/cmd/rmvolmgr/rmm_common.h
+ $(COMPILE.c) -o $@ $(SRC)/cmd/rmvolmgr/rmm_common.c
+ $(POST_PROCESS_O)
+
+vold.o: $(SRC)/cmd/rmvolmgr/vold.c $(SRC)/cmd/rmvolmgr/vold.h
+ $(COMPILE.c) -o $@ $(SRC)/cmd/rmvolmgr/vold.c
+ $(POST_PROCESS_O)
+
+clean:
+ $(RM) $(OBJS)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/volrmmount/volrmmount.c b/usr/src/cmd/volrmmount/volrmmount.c
new file mode 100644
index 0000000000..217ebd9124
--- /dev/null
+++ b/usr/src/cmd/volrmmount/volrmmount.c
@@ -0,0 +1,153 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <strings.h>
+#include <dirent.h>
+#include <signal.h>
+#include <errno.h>
+#include <libintl.h>
+#include <sys/types.h>
+
+#include "vold.h"
+#include "rmm_common.h"
+
+char *progname = "volrmmount";
+
+static void
+usage()
+{
+ (void) fprintf(stderr,
+ gettext(
+ "\nusage: %s [-i | -e] [DEVICE | NICKNAME]\n"),
+ progname);
+ (void) fprintf(stderr,
+ gettext("or: %s -d\n"), progname);
+ (void) fprintf(stderr,
+ gettext(
+ "options:\t-i simulate volume being put in/inserted\n"));
+ (void) fprintf(stderr,
+ gettext(
+ "options:\t-e simulate volume being taken out/ejected\n"));
+ (void) fprintf(stderr,
+ gettext("options:\t-d show default device\n"));
+ (void) fprintf(stderr,
+ gettext(
+ "\nThis command is deprecated. Use rmmount(1) instead.\n"));
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *opts = "ied";
+ int c;
+ boolean_t opt_insert = B_FALSE;
+ boolean_t opt_eject = B_FALSE;
+ boolean_t opt_default = B_FALSE;
+ action_t action;
+ LibHalContext *hal_ctx;
+ DBusError error;
+ rmm_error_t rmm_error;
+ LibHalDrive *d;
+ GSList *volumes;
+ const char *default_name;
+ int ret = 0;
+
+ while ((c = getopt(argc, argv, opts)) != EOF) {
+ switch (c) {
+ case 'i':
+ opt_insert = B_TRUE;
+ action = REMOUNT;
+ break;
+ case 'e':
+ opt_eject = B_TRUE;
+ action = UNMOUNT;
+ break;
+ case 'd':
+ opt_default = B_TRUE;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+ if ((opt_insert && opt_eject) ||
+ (!opt_insert && !opt_eject && !opt_default)) {
+ usage();
+ return (1);
+ }
+
+ if ((hal_ctx = rmm_hal_init(0, 0, 0, &error, &rmm_error)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("HAL initialization failed: %s\n"),
+ rmm_strerror(&error, rmm_error));
+ rmm_dbus_error_free(&error);
+ return (1);
+ }
+
+ if (opt_default) {
+ /* -d: print default name and exit */
+ if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
+ &default_name, &volumes)) == NULL) {
+ default_name = "nothing inserted";
+ } else {
+ rmm_volumes_free(volumes);
+ libhal_drive_free(d);
+ }
+ (void) printf(gettext("Default device is: %s\n"), default_name);
+ } else if (optind == argc) {
+ /* no name provided, use default */
+ if ((d = rmm_hal_volume_find_default(hal_ctx, &error,
+ &default_name, &volumes)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("No default media available\n"));
+ ret = 1;
+ } else {
+ rmm_volumes_free(volumes);
+ libhal_drive_free(d);
+ if (!rmm_action(hal_ctx, default_name, action,
+ 0, 0, 0, 0)) {
+ ret = 1;
+ }
+ }
+ } else {
+ for (; optind < argc; optind++) {
+ if (rmm_action(hal_ctx, argv[optind], action,
+ 0, 0, 0, 0) != 0) {
+ ret = 1;
+ }
+ }
+ }
+
+ rmm_hal_fini(hal_ctx);
+
+ return (ret);
+}
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile
index 2c7ee4ce4e..2d111dd9b3 100644
--- a/usr/src/head/Makefile
+++ b/usr/src/head/Makefile
@@ -142,7 +142,6 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \
resolv.h \
rje.h \
rtld_db.h \
- rmmount.h \
sac.h \
sched.h \
schedctl.h \
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index a18075620b..14b189482c 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -221,6 +221,8 @@ SUBDIRS += \
libzfs_jni \
libmapid \
brand \
+ policykit \
+ hal \
$($(MACH)_SUBDIRS)
sparc_SUBDIRS= .WAIT \
@@ -372,6 +374,8 @@ HDRSUBDIRS= \
libzfs \
libzfs_jni \
libzoneinfo \
+ hal \
+ policykit \
lvm \
openssl \
pkcs11 \
diff --git a/usr/src/lib/hal/Makefile b/usr/src/lib/hal/Makefile
new file mode 100644
index 0000000000..b98e17dc17
--- /dev/null
+++ b/usr/src/lib/hal/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.lib
+include $(SRC)/cmd/hal/Makefile.hal
+
+SUBDIRS = libhal libhal-storage
+HDRSUBDIRS = libhal libhal-storage
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+install_h := TARGET= install_h
+
+.KEEP_STATE:
+
+all clean clobber install: $(SUBDIRS)
+
+install_h: $(ROOTHDRDIR) $(ROOTHDRS) $(SUBDIRS)
+
+#
+# Don't check 3rd party code
+#
+check:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/lib/hal/Makefile.com b/usr/src/lib/hal/Makefile.com
new file mode 100644
index 0000000000..426528f6e1
--- /dev/null
+++ b/usr/src/lib/hal/Makefile.com
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/cmd/hal/Makefile.hal
+
+CPPFLAGS = $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(CPPFLAGS.master)
+
+ROOTLIBPCDIR = $(ROOT)/usr/lib/pkgconfig
+ROOTLIBPC = $(LIBPCSRC:%=$(ROOTLIBPCDIR)/%)
+
+CLOBBERFILES += $(LIBPCSRC)
+
+#
+# Ensure `all' is the default target.
+#
+all:
+
+# no lint for 3rd party code
+lint:
+
+$(ROOTLIBPCDIR):
+ $(INS.dir)
+
+$(ROOTLIBPC): $(ROOTLIBPCDIR) $(LIBPCSRC)
+ $(INS.file) $(LIBPCSRC)
+
+$(LIBPCSRC): ../common/$(LIBPCSRC).in
+ $(SED) -e "s@__VERSION__@$(HAL_VERSION)@" \
+ < ../common/$(LIBPCSRC).in > $(LIBPCSRC)
+
diff --git a/usr/src/lib/hal/libhal-storage/Makefile b/usr/src/lib/hal/libhal-storage/Makefile
new file mode 100644
index 0000000000..b7bffe3fac
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/Makefile
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+include ../../Makefile.lib
+include ../Makefile.com
+
+HDRS = libhal-storage.h
+HDRDIR = common
+ROOTHDRDIR = $(ROOT)/usr/include/hal
+
+SUBDIRS= $(MACH)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+
+.KEEP_STATE:
+
+all clean clobber install: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/hal/libhal-storage/Makefile.com b/usr/src/lib/hal/libhal-storage/Makefile.com
new file mode 100644
index 0000000000..27faf43cc0
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/Makefile.com
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# usr/src/lib/hal/libhal-storage/Makefile.com
+#
+
+LIBRARY = libhal-storage.a
+VERS = .1.0.0
+VERS_MAJ = .1
+OBJECTS = libhal-storage.o
+LIBPCSRC = hal-storage.pc
+
+include ../../Makefile.com
+
+LIBS = $(DYNLIB) $(LINTLIB)
+LDLIBS += -lc -ldbus-1 -lhal
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+
+CFLAGS += $(CCVERBOSE)
+CFLAGS += -_gcc=-Wno-deprecated-declarations
+CPPFLAGS += -DGETTEXT_PACKAGE=\"$(HAL_GETTEXT_PACKAGE)\" -DENABLE_NLS
+CPPFLAGS += -DPACKAGE_LOCALE_DIR=\"/usr/lib/locale\"
+CPPFLAGS += -I$(ROOT)/usr/include/hal
+
+ROOTMAJLINK = $(ROOTLIBDIR)/$(LIBRARY:.a=.so)$(VERS_MAJ)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+$(ROOTMAJLINK):
+ -$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in b/usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in
new file mode 100644
index 0000000000..8915793c62
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/common/hal-storage.pc.in
@@ -0,0 +1,19 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Licensed under the Academic Free License version 2.1
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: hal-storage
+Description: hal library for storage devices and volumes
+Version: __VERSION__
+Requires: dbus-1 hal
+Libs: -L${libdir} -lhal-storage
+Cflags: -DDBUS_API_SUBJECT_TO_CHANGE -I${includedir}/hal
diff --git a/usr/src/lib/hal/libhal-storage/common/libhal-storage.c b/usr/src/lib/hal/libhal-storage/common/libhal-storage.c
new file mode 100644
index 0000000000..39bdc53735
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/common/libhal-storage.c
@@ -0,0 +1,2037 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * libhal-storage.c : HAL convenience library for storage devices and volumes
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dbus/dbus.h>
+
+#include <libhal.h>
+#include "libhal-storage.h"
+
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) dgettext (GETTEXT_PACKAGE, String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+typedef struct IconMappingEntry_s {
+ LibHalStoragePolicyIcon icon;
+ char *path;
+ struct IconMappingEntry_s *next;
+} IconMappingEntry;
+
+struct LibHalStoragePolicy_s {
+ IconMappingEntry *icon_mappings;
+};
+
+LibHalStoragePolicy *
+libhal_storage_policy_new ()
+{
+ LibHalStoragePolicy *p;
+
+ p = malloc (sizeof (LibHalStoragePolicy));
+ if (p == NULL)
+ goto out;
+
+ p->icon_mappings = NULL;
+out:
+ return p;
+}
+
+void
+libhal_storage_policy_free (LibHalStoragePolicy *policy)
+{
+ IconMappingEntry *i;
+ IconMappingEntry *j;
+
+ /* free all icon mappings */
+ for (i = policy->icon_mappings; i != NULL; i = j) {
+ j = i->next;
+ free (i->path);
+ free (i);
+ }
+
+ free (policy);
+}
+
+void
+libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon, const char *path)
+{
+ IconMappingEntry *i;
+
+ /* see if it already exist */
+ for (i = policy->icon_mappings; i != NULL; i = i->next) {
+ if (i->icon == icon) {
+ free (i->path);
+ i->path = strdup (path);
+ goto out;
+ }
+ }
+
+ i = malloc (sizeof (IconMappingEntry));
+ if (i == NULL)
+ goto out;
+ i->icon = icon;
+ i->path = strdup (path);
+ i->next = policy->icon_mappings;
+ policy->icon_mappings = i;
+
+out:
+ return;
+}
+
+void
+libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy, LibHalStoragePolicyIconPair *pairs)
+{
+ LibHalStoragePolicyIconPair *i;
+
+ for (i = pairs; i->icon != 0x00; i++) {
+ libhal_storage_policy_set_icon_path (policy, i->icon, i->icon_path);
+ }
+}
+
+const char *
+libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy, LibHalStoragePolicyIcon icon)
+{
+ IconMappingEntry *i;
+ const char *path;
+
+ path = NULL;
+ for (i = policy->icon_mappings; i != NULL; i = i->next) {
+ if (i->icon == icon) {
+ path = i->path;
+ goto out;
+ }
+ }
+out:
+ return path;
+}
+
+
+#define MAX_STRING_SZ 256
+
+char *
+libhal_volume_policy_compute_size_as_string (LibHalVolume *volume)
+{
+ dbus_uint64_t size;
+ char *result;
+ char* sizes_str[] = {"K", "M", "G", "T", NULL};
+ dbus_uint64_t cur = 1000L;
+ dbus_uint64_t base = 10L;
+ dbus_uint64_t step = 10L*10L*10L;
+ int cur_str = 0;
+ char buf[MAX_STRING_SZ];
+
+ result = NULL;
+
+ size = libhal_volume_get_size (volume);
+
+ do {
+ if (sizes_str[cur_str+1] == NULL || size < cur*step) {
+ /* found the unit, display a comma number if result is a single digit */
+ if (size < cur*base) {
+ snprintf (buf, MAX_STRING_SZ, "%.01f%s",
+ ((double)size)/((double)cur), sizes_str[cur_str]);
+ result = strdup (buf);
+ } else {
+ snprintf (buf, MAX_STRING_SZ, "%llu%s", (long long unsigned int) size / cur, sizes_str[cur_str]);
+ result = strdup (buf);
+ }
+ goto out;
+ }
+
+ cur *= step;
+ cur_str++;
+ } while (1);
+
+out:
+ return result;
+}
+
+static void
+fixup_string (char *s)
+{
+ /* TODO: first strip leading and trailing whitespace */
+ /*g_strstrip (s);*/
+
+ /* TODO: could do nice things on all-upper case strings */
+}
+
+/* volume may be NULL (e.g. if drive supports removable media) */
+char *
+libhal_drive_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ char *name;
+ char *size_str;
+ char *vendormodel_str;
+ const char *model;
+ const char *vendor;
+ LibHalDriveType drive_type;
+ dbus_bool_t drive_is_hotpluggable;
+ dbus_bool_t drive_is_removable;
+ LibHalDriveCdromCaps drive_cdrom_caps;
+ char buf[MAX_STRING_SZ];
+
+ model = libhal_drive_get_model (drive);
+ vendor = libhal_drive_get_vendor (drive);
+ drive_type = libhal_drive_get_type (drive);
+ drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive);
+ drive_is_removable = libhal_drive_uses_removable_media (drive);
+ drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive);
+
+ if (volume != NULL)
+ size_str = libhal_volume_policy_compute_size_as_string (volume);
+ else
+ size_str = NULL;
+
+ if (vendor == NULL || strlen (vendor) == 0) {
+ if (model == NULL || strlen (model) == 0)
+ vendormodel_str = strdup ("");
+ else
+ vendormodel_str = strdup (model);
+ } else {
+ if (model == NULL || strlen (model) == 0)
+ vendormodel_str = strdup (vendor);
+ else {
+ snprintf (buf, MAX_STRING_SZ, "%s %s", vendor, model);
+ vendormodel_str = strdup (buf);
+ }
+ }
+
+ fixup_string (vendormodel_str);
+
+ if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) {
+
+ /* Optical drive handling */
+ char *first;
+ char *second;
+
+
+ first = "CD-ROM";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDR)
+ first = "CD-R";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_CDRW)
+ first = "CD-RW";
+
+ second = "";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM)
+ second = "/DVD-ROM";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)
+ second = "/DVD+R";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)
+ second = "/DVD+RW";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR)
+ second = "/DVD-R";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW)
+ second = "/DVD-RW";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRAM)
+ second = "/DVD-RAM";
+ if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR) &&
+ (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR)) {
+ if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL)
+ second = "/DVD±R DL";
+ else
+ second = "/DVD±R";
+ }
+ if ((drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDRW) &&
+ (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW)) {
+ if(drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL ||
+ drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL)
+ second = "/DVD±RW DL";
+ else
+ second = "/DVD±RW";
+ }
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDROM)
+ second = "/BD-ROM";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDR)
+ second = "/BD-R";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_BDRE)
+ second = "/BD-RE";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM)
+ second = "/HD DVD-ROM";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_HDDVDR)
+ second = "/HD DVD-R";
+ if (drive_cdrom_caps & LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW)
+ second = "/HD DVD-RW";
+
+ if (drive_is_hotpluggable) {
+ snprintf (buf, MAX_STRING_SZ, _("External %s%s Drive"), first, second);
+ name = strdup (buf);
+ } else {
+ snprintf (buf, MAX_STRING_SZ, _("%s%s Drive"), first, second);
+ name = strdup (buf);
+ }
+
+ } else if (drive_type==LIBHAL_DRIVE_TYPE_FLOPPY) {
+
+ /* Floppy Drive handling */
+
+ if (drive_is_hotpluggable)
+ name = strdup (_("External Floppy Drive"));
+ else
+ name = strdup (_("Floppy Drive"));
+ } else if (drive_type==LIBHAL_DRIVE_TYPE_DISK && !drive_is_removable) {
+
+ /* Harddisks */
+
+ if (size_str != NULL) {
+ if (drive_is_hotpluggable) {
+ snprintf (buf, MAX_STRING_SZ, _("%s External Hard Drive"), size_str);
+ name = strdup (buf);
+ } else {
+ snprintf (buf, MAX_STRING_SZ, _("%s Hard Drive"), size_str);
+ name = strdup (buf);
+ }
+ } else {
+ if (drive_is_hotpluggable)
+ name = strdup (_("External Hard Drive"));
+ else
+ name = strdup (_("Hard Drive"));
+ }
+ } else {
+
+ /* The rest - includes drives with removable Media */
+
+ if (strlen (vendormodel_str) > 0)
+ name = strdup (vendormodel_str);
+ else
+ name = strdup (_("Drive"));
+ }
+
+ free (vendormodel_str);
+ free (size_str);
+
+ return name;
+}
+
+char *
+libhal_volume_policy_compute_display_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ char *name;
+ char *size_str;
+ const char *volume_label;
+ const char *model;
+ const char *vendor;
+ LibHalDriveType drive_type;
+ dbus_bool_t drive_is_hotpluggable;
+ dbus_bool_t drive_is_removable;
+ LibHalDriveCdromCaps drive_cdrom_caps;
+ char buf[MAX_STRING_SZ];
+
+ volume_label = libhal_volume_get_label (volume);
+ model = libhal_drive_get_model (drive);
+ vendor = libhal_drive_get_vendor (drive);
+ drive_type = libhal_drive_get_type (drive);
+ drive_is_hotpluggable = libhal_drive_is_hotpluggable (drive);
+ drive_is_removable = libhal_drive_uses_removable_media (drive);
+ drive_cdrom_caps = libhal_drive_get_cdrom_caps (drive);
+
+ size_str = libhal_volume_policy_compute_size_as_string (volume);
+
+ /* If the volume label is available use that
+ *
+ * TODO: If label is a fully-qualified UNIX path don't use that
+ */
+ if (volume_label != NULL) {
+ name = strdup (volume_label);
+ goto out;
+ }
+
+ /* Handle media in optical drives */
+ if (drive_type==LIBHAL_DRIVE_TYPE_CDROM) {
+ switch (libhal_volume_get_disc_type (volume)) {
+
+ default:
+ /* explict fallthrough */
+ case LIBHAL_VOLUME_DISC_TYPE_CDROM:
+ name = strdup (_("CD-ROM "));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_CDR:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank CD-R"));
+ else
+ name = strdup (_("CD-R"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_CDRW:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank CD-RW"));
+ else
+ name = strdup (_("CD-RW"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDROM:
+ name = strdup (_("DVD-ROM"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDRAM:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank DVD-RAM"));
+ else
+ name = strdup (_("DVD-RAM"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDR:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank DVD-R"));
+ else
+ name = strdup (_("DVD-R"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDRW:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank DVD-RW"));
+ else
+ name = strdup (_("DVD-RW"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank DVD+R"));
+ else
+ name = strdup (_("DVD+R"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank DVD+RW"));
+ else
+ name = strdup (_("DVD+RW"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank DVD+R Dual-Layer"));
+ else
+ name = strdup (_("DVD+R Dual-Layer"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_BDROM:
+ name = strdup (_("BD-ROM"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_BDR:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank BD-R"));
+ else
+ name = strdup (_("BD-R"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_BDRE:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank BD-RE"));
+ else
+ name = strdup (_("BD-RE"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_HDDVDROM:
+ name = strdup (_("HD DVD-ROM"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_HDDVDR:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank HD DVD-R"));
+ else
+ name = strdup (_("HD DVD-R"));
+ break;
+
+ case LIBHAL_VOLUME_DISC_TYPE_HDDVDRW:
+ if (libhal_volume_disc_is_blank (volume))
+ name = strdup (_("Blank HD DVD-RW"));
+ else
+ name = strdup (_("HD DVD-RW"));
+ break;
+
+ }
+
+ /* Special case for pure audio disc */
+ if (libhal_volume_disc_has_audio (volume) && !libhal_volume_disc_has_data (volume)) {
+ free (name);
+ name = strdup (_("Audio CD"));
+ }
+
+ goto out;
+ }
+
+ /* Fallback: size of media */
+ if (drive_is_removable) {
+ snprintf (buf, MAX_STRING_SZ, _("%s Removable Media"), size_str);
+ name = strdup (buf);
+ } else {
+ snprintf (buf, MAX_STRING_SZ, _("%s Media"), size_str);
+ name = strdup (buf);
+ }
+
+ /* Fallback: Use drive name */
+ /*name = libhal_drive_policy_compute_display_name (drive, volume);*/
+
+out:
+ free (size_str);
+ return name;
+}
+
+char *
+libhal_drive_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ const char *name;
+ LibHalDriveBus bus;
+ LibHalDriveType drive_type;
+
+ bus = libhal_drive_get_bus (drive);
+ drive_type = libhal_drive_get_type (drive);
+
+ /* by design, the enums are laid out so we can do easy computations */
+
+ switch (drive_type) {
+ case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK:
+ case LIBHAL_DRIVE_TYPE_DISK:
+ case LIBHAL_DRIVE_TYPE_CDROM:
+ case LIBHAL_DRIVE_TYPE_FLOPPY:
+ name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100 + bus);
+ break;
+
+ default:
+ name = libhal_storage_policy_lookup_icon (policy, 0x10000 + drive_type*0x100);
+ }
+
+ if (name != NULL)
+ return strdup (name);
+ else
+ return NULL;
+}
+
+char *
+libhal_volume_policy_compute_icon_name (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ const char *name;
+ LibHalDriveBus bus;
+ LibHalDriveType drive_type;
+ LibHalVolumeDiscType disc_type;
+
+ /* by design, the enums are laid out so we can do easy computations */
+
+ if (libhal_volume_is_disc (volume)) {
+ disc_type = libhal_volume_get_disc_type (volume);
+ name = libhal_storage_policy_lookup_icon (policy, 0x30000 + disc_type);
+ goto out;
+ }
+
+ if (drive == NULL) {
+ name = libhal_storage_policy_lookup_icon (policy, LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK);
+ goto out;
+ }
+
+ bus = libhal_drive_get_bus (drive);
+ drive_type = libhal_drive_get_type (drive);
+
+ switch (drive_type) {
+ case LIBHAL_DRIVE_TYPE_REMOVABLE_DISK:
+ case LIBHAL_DRIVE_TYPE_DISK:
+ case LIBHAL_DRIVE_TYPE_CDROM:
+ case LIBHAL_DRIVE_TYPE_FLOPPY:
+ name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100 + bus);
+ break;
+
+ default:
+ name = libhal_storage_policy_lookup_icon (policy, 0x20000 + drive_type*0x100);
+ }
+out:
+ if (name != NULL)
+ return strdup (name);
+ else
+ return NULL;
+}
+
+/** Policy function to determine if a volume should be visible in a desktop
+ * environment. This is useful to hide certain system volumes as bootstrap
+ * partitions, the /usr partition, swap partitions and other volumes that
+ * a unprivileged desktop user shouldn't know even exists.
+ *
+ * @param drive Drive that the volume is stemming from
+ * @param volume Volume
+ * @param policy Policy object
+ * @param target_mount_point The mount point that the volume is expected to
+ * be mounted at if not already mounted. This may
+ * e.g. stem from /etc/fstab. If this is NULL the
+ * then mount point isn't taking into account when
+ * evaluating whether the volume should be visible
+ * @return Whether the volume should be shown in a desktop
+ * environment.
+ */
+dbus_bool_t
+libhal_volume_policy_should_be_visible (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy,
+ const char *target_mount_point)
+{
+ unsigned int i;
+ dbus_bool_t is_visible;
+ const char *label;
+ const char *mount_point;
+ const char *fstype;
+ const char *fhs23_toplevel_mount_points[] = {
+ "/",
+ "/bin",
+ "/boot",
+ "/dev",
+ "/etc",
+ "/home",
+ "/lib",
+ "/lib64",
+ "/media",
+ "/mnt",
+ "/opt",
+ "/root",
+ "/sbin",
+ "/srv",
+ "/tmp",
+ "/usr",
+ "/var",
+ "/proc",
+ "/sbin",
+ NULL
+ };
+
+ is_visible = FALSE;
+
+ /* skip if hal says it's not used as a filesystem */
+ if (libhal_volume_get_fsusage (volume) != LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM)
+ goto out;
+
+ label = libhal_volume_get_label (volume);
+ mount_point = libhal_volume_get_mount_point (volume);
+ fstype = libhal_volume_get_fstype (volume);
+
+ /* use target mount point if we're not mounted yet */
+ if (mount_point == NULL)
+ mount_point = target_mount_point;
+
+ /* bail out if we don't know the filesystem */
+ if (fstype == NULL)
+ goto out;
+
+ /* blacklist fhs2.3 top level mount points */
+ if (mount_point != NULL) {
+ for (i = 0; fhs23_toplevel_mount_points[i] != NULL; i++) {
+ if (strcmp (mount_point, fhs23_toplevel_mount_points[i]) == 0)
+ goto out;
+ }
+ }
+
+ /* blacklist partitions with name 'bootstrap' of type HFS (Apple uses that) */
+ if (label != NULL && strcmp (label, "bootstrap") == 0 && strcmp (fstype, "hfs") == 0)
+ goto out;
+
+ /* only the real lucky mount points will make it this far :-) */
+ is_visible = TRUE;
+
+out:
+ return is_visible;
+}
+
+/*************************************************************************/
+
+#define MOUNT_OPTIONS_SIZE 256
+
+struct LibHalDrive_s {
+ char *udi;
+
+ int device_major;
+ int device_minor;
+ char *device_file;
+
+ LibHalDriveBus bus;
+ char *vendor; /* may be "", is never NULL */
+ char *model; /* may be "", is never NULL */
+ dbus_bool_t is_hotpluggable;
+ dbus_bool_t is_removable;
+ dbus_bool_t is_media_detected;
+ dbus_bool_t requires_eject;
+
+ LibHalDriveType type;
+ char *type_textual;
+
+ char *physical_device; /* UDI of physical device, e.g. the
+ * IDE, USB, IEEE1394 device */
+
+ char *dedicated_icon_drive;
+ char *dedicated_icon_volume;
+
+ char *serial;
+ char *firmware_version;
+ LibHalDriveCdromCaps cdrom_caps;
+
+ char *desired_mount_point;
+ char *mount_filesystem;
+ dbus_bool_t should_mount;
+
+ dbus_bool_t no_partitions_hint;
+
+ dbus_uint64_t drive_size;
+ dbus_uint64_t drive_media_size;
+ char *partition_scheme;
+
+ LibHalContext *hal_ctx;
+
+ char **capabilities;
+
+ char mount_options[MOUNT_OPTIONS_SIZE];
+};
+
+struct LibHalVolume_s {
+ char *udi;
+
+ int device_major;
+ int device_minor;
+ char *device_file;
+ char *volume_label; /* may be NULL, is never "" */
+ dbus_bool_t is_mounted;
+ dbus_bool_t is_mounted_read_only; /* TRUE iff is_mounted and r/o fs */
+ char *mount_point; /* NULL iff !is_mounted */
+ char *fstype; /* NULL iff !is_mounted or unknown */
+ char *fsversion;
+ char *uuid;
+ char *storage_device;
+
+ LibHalVolumeUsage fsusage;
+
+ dbus_bool_t is_partition;
+ unsigned int partition_number;
+ char *partition_scheme;
+ char *partition_type;
+ char *partition_label;
+ char *partition_uuid;
+ char **partition_flags;
+
+ int msdos_part_table_type;
+ dbus_uint64_t msdos_part_table_start;
+ dbus_uint64_t msdos_part_table_size;
+
+ dbus_bool_t is_disc;
+ LibHalVolumeDiscType disc_type;
+ dbus_bool_t disc_has_audio;
+ dbus_bool_t disc_has_data;
+ dbus_bool_t disc_is_appendable;
+ dbus_bool_t disc_is_blank;
+ dbus_bool_t disc_is_rewritable;
+
+ unsigned int block_size;
+ unsigned int num_blocks;
+
+ char *desired_mount_point;
+ char *mount_filesystem;
+ dbus_bool_t should_mount;
+
+ dbus_bool_t ignore_volume;
+
+ char *crypto_backing_volume;
+
+ char mount_options[MOUNT_OPTIONS_SIZE];
+
+ dbus_uint64_t volume_size;
+ dbus_uint64_t disc_capacity;
+
+ dbus_uint64_t partition_start_offset;
+ dbus_uint64_t partition_media_size;
+};
+
+const char *
+libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive)
+{
+ return drive->dedicated_icon_drive;
+}
+
+const char *
+libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive)
+{
+ return drive->dedicated_icon_volume;
+}
+
+/** Free all resources used by a LibHalDrive object.
+ *
+ * @param drive Object to free
+ */
+void
+libhal_drive_free (LibHalDrive *drive)
+{
+ if (drive == NULL )
+ return;
+
+ free (drive->udi);
+ libhal_free_string (drive->device_file);
+ libhal_free_string (drive->vendor);
+ libhal_free_string (drive->model);
+ libhal_free_string (drive->type_textual);
+ libhal_free_string (drive->physical_device);
+ libhal_free_string (drive->dedicated_icon_drive);
+ libhal_free_string (drive->dedicated_icon_volume);
+ libhal_free_string (drive->serial);
+ libhal_free_string (drive->firmware_version);
+ libhal_free_string (drive->desired_mount_point);
+ libhal_free_string (drive->mount_filesystem);
+ libhal_free_string_array (drive->capabilities);
+ libhal_free_string (drive->partition_scheme);
+
+ free (drive);
+}
+
+
+/** Free all resources used by a LibHalVolume object.
+ *
+ * @param vol Object to free
+ */
+void
+libhal_volume_free (LibHalVolume *vol)
+{
+ if (vol == NULL )
+ return;
+
+ free (vol->udi);
+ libhal_free_string (vol->device_file);
+ libhal_free_string (vol->volume_label);
+ libhal_free_string (vol->fstype);
+ libhal_free_string (vol->mount_point);
+ libhal_free_string (vol->fsversion);
+ libhal_free_string (vol->uuid);
+ libhal_free_string (vol->desired_mount_point);
+ libhal_free_string (vol->mount_filesystem);
+ libhal_free_string (vol->crypto_backing_volume);
+ libhal_free_string (vol->storage_device);
+
+ libhal_free_string (vol->partition_scheme);
+ libhal_free_string (vol->partition_type);
+ libhal_free_string (vol->partition_label);
+ libhal_free_string (vol->partition_uuid);
+ libhal_free_string_array (vol->partition_flags);
+
+ free (vol);
+}
+
+
+static char **
+my_strvdup (char **strv)
+{
+ unsigned int num_elems;
+ unsigned int i;
+ char **res;
+
+ for (num_elems = 0; strv[num_elems] != NULL; num_elems++)
+ ;
+
+ res = calloc (num_elems + 1, sizeof (char*));
+ if (res == NULL)
+ goto out;
+
+ for (i = 0; i < num_elems; i++)
+ res[i] = strdup (strv[i]);
+ res[i] = NULL;
+
+out:
+ return res;
+}
+
+/* ok, hey, so this is a bit ugly */
+
+#define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE)
+#define LIBHAL_PROP_EXTRACT_END ;
+#define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it)
+#define LIBHAL_PROP_EXTRACT_UINT64(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_UINT64) _where_ = libhal_psi_get_uint64 (&it)
+#define LIBHAL_PROP_EXTRACT_STRING(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRING) _where_ = (libhal_psi_get_string (&it) != NULL && strlen (libhal_psi_get_string (&it)) > 0) ? strdup (libhal_psi_get_string (&it)) : NULL
+#define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it)
+#define LIBHAL_PROP_EXTRACT_BOOL_BITFIELD(_property_, _where_, _field_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ |= libhal_psi_get_bool (&it) ? _field_ : 0
+#define LIBHAL_PROP_EXTRACT_STRLIST(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRLIST) _where_ = my_strvdup (libhal_psi_get_strlist (&it))
+
+/** Given a UDI for a HAL device of capability 'storage', this
+ * function retrieves all the relevant properties into convenient
+ * in-process data structures.
+ *
+ * @param hal_ctx libhal context
+ * @param udi HAL UDI
+ * @return LibHalDrive object or NULL if UDI is invalid
+ */
+LibHalDrive *
+libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi)
+{
+ char *bus_textual;
+ LibHalDrive *drive;
+ LibHalPropertySet *properties;
+ LibHalPropertySetIterator it;
+ DBusError error;
+ unsigned int i;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ drive = NULL;
+ properties = NULL;
+ bus_textual = NULL;
+
+ dbus_error_init (&error);
+ if (!libhal_device_query_capability (hal_ctx, udi, "storage", &error))
+ goto error;
+
+ drive = malloc (sizeof (LibHalDrive));
+ if (drive == NULL)
+ goto error;
+ memset (drive, 0x00, sizeof (LibHalDrive));
+
+ drive->hal_ctx = hal_ctx;
+
+ drive->udi = strdup (udi);
+ if (drive->udi == NULL)
+ goto error;
+
+ properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
+ if (properties == NULL)
+ goto error;
+
+ /* we can count on hal to give us all these properties */
+ for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
+ int type;
+ char *key;
+
+ type = libhal_psi_get_type (&it);
+ key = libhal_psi_get_key (&it);
+
+ LIBHAL_PROP_EXTRACT_BEGIN;
+
+ LIBHAL_PROP_EXTRACT_INT ("block.minor", drive->device_minor);
+ LIBHAL_PROP_EXTRACT_INT ("block.major", drive->device_major);
+ LIBHAL_PROP_EXTRACT_STRING ("block.device", drive->device_file);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.bus", bus_textual);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.vendor", drive->vendor);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.model", drive->model);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.drive_type", drive->type_textual);
+ LIBHAL_PROP_EXTRACT_UINT64 ("storage.size", drive->drive_size);
+
+ LIBHAL_PROP_EXTRACT_STRING ("storage.icon.drive", drive->dedicated_icon_drive);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.icon.volume", drive->dedicated_icon_volume);
+
+ LIBHAL_PROP_EXTRACT_BOOL ("storage.hotpluggable", drive->is_hotpluggable);
+ LIBHAL_PROP_EXTRACT_BOOL ("storage.removable", drive->is_removable);
+ LIBHAL_PROP_EXTRACT_BOOL ("storage.removable.media_available", drive->is_media_detected);
+ LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive->drive_media_size);
+ LIBHAL_PROP_EXTRACT_BOOL ("storage.requires_eject", drive->requires_eject);
+
+ LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive->partition_scheme);
+
+ LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device", drive->physical_device);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version", drive->firmware_version);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.serial", drive->serial);
+
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDR);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_CDRW);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDROM);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrwdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdplusrdl", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDR);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRW);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.dvdram", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_DVDRAM);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDROM);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDR);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.bdre", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_BDRE);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvd", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdr", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDR);
+ LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.hddvdrw", drive->cdrom_caps, LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW);
+
+ LIBHAL_PROP_EXTRACT_BOOL ("storage.policy.should_mount", drive->should_mount);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.policy.desired_mount_point", drive->desired_mount_point);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.policy.mount_filesystem", drive->mount_filesystem);
+
+ LIBHAL_PROP_EXTRACT_BOOL ("storage.no_partitions_hint", drive->no_partitions_hint);
+
+ LIBHAL_PROP_EXTRACT_STRLIST ("info.capabilities", drive->capabilities);
+
+ LIBHAL_PROP_EXTRACT_END;
+ }
+
+ if (drive->type_textual != NULL) {
+ if (strcmp (drive->type_textual, "cdrom") == 0) {
+ drive->cdrom_caps |= LIBHAL_DRIVE_CDROM_CAPS_CDROM;
+ drive->type = LIBHAL_DRIVE_TYPE_CDROM;
+ } else if (strcmp (drive->type_textual, "floppy") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_FLOPPY;
+ } else if (strcmp (drive->type_textual, "disk") == 0) {
+ if (drive->is_removable)
+ drive->type = LIBHAL_DRIVE_TYPE_REMOVABLE_DISK;
+ else
+ drive->type = LIBHAL_DRIVE_TYPE_DISK;
+ } else if (strcmp (drive->type_textual, "tape") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_TAPE;
+ } else if (strcmp (drive->type_textual, "compact_flash") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_COMPACT_FLASH;
+ } else if (strcmp (drive->type_textual, "memory_stick") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_MEMORY_STICK;
+ } else if (strcmp (drive->type_textual, "smart_media") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_SMART_MEDIA;
+ } else if (strcmp (drive->type_textual, "sd_mmc") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_SD_MMC;
+ } else if (strcmp (drive->type_textual, "zip") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_ZIP;
+ } else if (strcmp (drive->type_textual, "jaz") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_JAZ;
+ } else if (strcmp (drive->type_textual, "flashkey") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_FLASHKEY;
+ } else {
+ drive->type = LIBHAL_DRIVE_TYPE_DISK;
+ }
+
+ }
+
+ if (drive->capabilities != NULL) {
+ for (i = 0; drive->capabilities[i] != NULL; i++) {
+ if (strcmp (drive->capabilities[i], "portable_audio_player") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER;
+ break;
+ } else if (strcmp (drive->capabilities[i], "camera") == 0) {
+ drive->type = LIBHAL_DRIVE_TYPE_CAMERA;
+ break;
+ }
+ }
+ }
+
+ if (bus_textual != NULL) {
+ if (strcmp (bus_textual, "usb") == 0) {
+ drive->bus = LIBHAL_DRIVE_BUS_USB;
+ } else if (strcmp (bus_textual, "ieee1394") == 0) {
+ drive->bus = LIBHAL_DRIVE_BUS_IEEE1394;
+ } else if (strcmp (bus_textual, "ide") == 0) {
+ drive->bus = LIBHAL_DRIVE_BUS_IDE;
+ } else if (strcmp (bus_textual, "scsi") == 0) {
+ drive->bus = LIBHAL_DRIVE_BUS_SCSI;
+ } else if (strcmp (bus_textual, "ccw") == 0) {
+ drive->bus = LIBHAL_DRIVE_BUS_CCW;
+ }
+ }
+
+ libhal_free_string (bus_textual);
+ libhal_free_property_set (properties);
+
+ return drive;
+
+error:
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ libhal_free_string (bus_textual);
+ libhal_free_property_set (properties);
+ libhal_drive_free (drive);
+ return NULL;
+}
+
+const char *
+libhal_volume_get_storage_device_udi (LibHalVolume *volume)
+{
+ return volume->storage_device;
+}
+
+const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive)
+{
+ return drive->physical_device;
+}
+
+dbus_bool_t
+libhal_drive_requires_eject (LibHalDrive *drive)
+{
+ return drive->requires_eject;
+}
+
+/** Given a UDI for a LIBHAL device of capability 'volume', this
+ * function retrieves all the relevant properties into convenient
+ * in-process data structures.
+ *
+ * @param hal_ctx libhal context
+ * @param udi HAL UDI
+ * @return LibHalVolume object or NULL if UDI is invalid
+ */
+LibHalVolume *
+libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi)
+{
+ char *disc_type_textual;
+ char *vol_fsusage_textual;
+ LibHalVolume *vol;
+ LibHalPropertySet *properties;
+ LibHalPropertySetIterator it;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ vol = NULL;
+ properties = NULL;
+ disc_type_textual = NULL;
+ vol_fsusage_textual = NULL;
+
+ dbus_error_init (&error);
+ if (!libhal_device_query_capability (hal_ctx, udi, "volume", &error))
+ goto error;
+
+ vol = malloc (sizeof (LibHalVolume));
+ if (vol == NULL)
+ goto error;
+ memset (vol, 0x00, sizeof (LibHalVolume));
+
+ vol->udi = strdup (udi);
+
+ properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
+ if (properties == NULL)
+ goto error;
+
+ /* we can count on hal to give us all these properties */
+ for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
+ int type;
+ char *key;
+
+ type = libhal_psi_get_type (&it);
+ key = libhal_psi_get_key (&it);
+
+ LIBHAL_PROP_EXTRACT_BEGIN;
+
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.is_partition", vol->is_partition);
+ LIBHAL_PROP_EXTRACT_INT ("volume.partition.number", vol->partition_number);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.scheme", vol->partition_scheme);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.type", vol->partition_type);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.label", vol->partition_label);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.uuid", vol->partition_uuid);
+ LIBHAL_PROP_EXTRACT_STRLIST ("volume.partition.flags", vol->partition_flags);
+
+ LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.start", vol->partition_start_offset);
+ LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.media_size", vol->partition_media_size);
+ LIBHAL_PROP_EXTRACT_INT ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type);
+ LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_start", vol->msdos_part_table_start);
+ LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.msdos_part_table_size", vol->msdos_part_table_size);
+
+ LIBHAL_PROP_EXTRACT_INT ("block.minor", vol->device_minor);
+ LIBHAL_PROP_EXTRACT_INT ("block.major", vol->device_major);
+ LIBHAL_PROP_EXTRACT_STRING ("block.device", vol->device_file);
+
+ LIBHAL_PROP_EXTRACT_STRING ("block.storage_device", vol->storage_device);
+
+ LIBHAL_PROP_EXTRACT_STRING ("volume.crypto_luks.clear.backing_volume", vol->crypto_backing_volume);
+
+ LIBHAL_PROP_EXTRACT_INT ("volume.block_size", vol->block_size);
+ LIBHAL_PROP_EXTRACT_INT ("volume.num_blocks", vol->num_blocks);
+ LIBHAL_PROP_EXTRACT_UINT64 ("volume.size", vol->volume_size);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.label", vol->volume_label);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.mount_point", vol->mount_point);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.fstype", vol->fstype);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.fsversion", vol->fsversion);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted", vol->is_mounted);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.is_mounted_read_only", vol->is_mounted_read_only);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.fsusage", vol_fsusage_textual);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.uuid", vol->uuid);
+
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.ignore", vol->ignore_volume);
+
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.is_disc", vol->is_disc);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.disc.type", disc_type_textual);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_audio", vol->disc_has_audio);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.has_data", vol->disc_has_data);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_appendable", vol->disc_is_appendable);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_blank", vol->disc_is_blank);
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.disc.is_rewritable", vol->disc_is_rewritable);
+ LIBHAL_PROP_EXTRACT_UINT64 ("volume.disc.capacity", vol->disc_capacity);
+
+ LIBHAL_PROP_EXTRACT_BOOL ("volume.policy.should_mount", vol->should_mount);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.policy.desired_mount_point", vol->desired_mount_point);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.policy.mount_filesystem", vol->mount_filesystem);
+
+ LIBHAL_PROP_EXTRACT_END;
+ }
+
+ if (disc_type_textual != NULL) {
+ if (strcmp (disc_type_textual, "cd_rom") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDROM;
+ } else if (strcmp (disc_type_textual, "cd_r") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDR;
+ } else if (strcmp (disc_type_textual, "cd_rw") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_CDRW;
+ } else if (strcmp (disc_type_textual, "dvd_rom") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDROM;
+ } else if (strcmp (disc_type_textual, "dvd_ram") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRAM;
+ } else if (strcmp (disc_type_textual, "dvd_r") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDR;
+ } else if (strcmp (disc_type_textual, "dvd_rw") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDRW;
+ } else if (strcmp (disc_type_textual, "dvd_plus_r") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR;
+ } else if (strcmp (disc_type_textual, "dvd_plus_rw") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW;
+ } else if (strcmp (disc_type_textual, "dvd_plus_r_dl") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL;
+ } else if (strcmp (disc_type_textual, "bd_rom") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDROM;
+ } else if (strcmp (disc_type_textual, "bd_r") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDR;
+ } else if (strcmp (disc_type_textual, "bd_re") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_BDRE;
+ } else if (strcmp (disc_type_textual, "hddvd_rom") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDROM;
+ } else if (strcmp (disc_type_textual, "hddvd_r") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDR;
+ } else if (strcmp (disc_type_textual, "hddvd_rw") == 0) {
+ vol->disc_type = LIBHAL_VOLUME_DISC_TYPE_HDDVDRW;
+ }
+ }
+
+ vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN;
+ if (vol_fsusage_textual != NULL) {
+ if (strcmp (vol_fsusage_textual, "filesystem") == 0) {
+ vol->fsusage = LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM;
+ } else if (strcmp (vol_fsusage_textual, "partitiontable") == 0) {
+ vol->fsusage = LIBHAL_VOLUME_USAGE_PARTITION_TABLE;
+ } else if (strcmp (vol_fsusage_textual, "raid") == 0) {
+ vol->fsusage = LIBHAL_VOLUME_USAGE_RAID_MEMBER;
+ } else if (strcmp (vol_fsusage_textual, "crypto") == 0) {
+ vol->fsusage = LIBHAL_VOLUME_USAGE_CRYPTO;
+ } else if (strcmp (vol_fsusage_textual, "other") == 0) {
+ vol->fsusage = LIBHAL_VOLUME_USAGE_OTHER;
+ } else {
+ vol->fsusage = LIBHAL_VOLUME_USAGE_UNKNOWN;
+ }
+ }
+
+ libhal_free_string (vol_fsusage_textual);
+ libhal_free_string (disc_type_textual);
+ libhal_free_property_set (properties);
+ return vol;
+error:
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ }
+ libhal_free_string (vol_fsusage_textual);
+ libhal_free_string (disc_type_textual);
+ libhal_free_property_set (properties);
+ libhal_volume_free (vol);
+ return NULL;
+}
+
+
+/** If the volume is on a drive with a MSDOS style partition table, return
+ * the partition table id.
+ *
+ * @param volume Volume object
+ * @return The partition type or -1 if volume is not
+ * a partition or the media the volume stems from
+ * isn't partition with a MS DOS style table
+ */
+int
+libhal_volume_get_msdos_part_table_type (LibHalVolume *volume)
+{
+ return volume->msdos_part_table_type;
+}
+
+/** If the volume is on a drive with a MSDOS style partition table, return
+ * the partition start offset according to the partition table.
+ *
+ * @param volume Volume object
+ * @return The partition start offset or -1 if volume isnt
+ * a partition or the media the volume stems from
+ * isn't partition with a MS DOS style table
+ */
+dbus_uint64_t
+libhal_volume_get_msdos_part_table_start (LibHalVolume *volume)
+{
+ return volume->msdos_part_table_start;
+}
+
+/** If the volume is on a drive with a MSDOS style partition table, return
+ * the partition size according to the partition table.
+ *
+ * @param volume Volume object
+ * @return The partition size or -1 if volume is not
+ * a partition or the media the volume stems from
+ * isn't partition with a MS DOS style table
+ */
+dbus_uint64_t
+libhal_volume_get_msdos_part_table_size (LibHalVolume *volume)
+{
+ return volume->msdos_part_table_size;
+}
+
+/***********************************************************************/
+
+/** Get the drive object that either is (when given e.g. /dev/sdb) or contains
+ * (when given e.g. /dev/sdb1) the given device file.
+ *
+ * @param hal_ctx libhal context to use
+ * @param device_file Name of special device file, e.g. '/dev/hdc'
+ * @return LibHalDrive object or NULL if it doesn't exist
+ */
+LibHalDrive *
+libhal_drive_from_device_file (LibHalContext *hal_ctx, const char *device_file)
+{
+ int i;
+ char **hal_udis;
+ int num_hal_udis;
+ LibHalDrive *result;
+ char *found_udi;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ result = NULL;
+ found_udi = NULL;
+
+ dbus_error_init (&error);
+ if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device",
+ device_file, &num_hal_udis, &error)) == NULL) {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ goto out;
+ }
+
+ for (i = 0; i < num_hal_udis; i++) {
+ char *udi;
+ char *storage_udi;
+ DBusError err1;
+ DBusError err2;
+ udi = hal_udis[i];
+
+ dbus_error_init (&err1);
+ dbus_error_init (&err2);
+ if (libhal_device_query_capability (hal_ctx, udi, "volume", &err1)) {
+
+ storage_udi = libhal_device_get_property_string (hal_ctx, udi, "block.storage_device", &err1);
+ if (storage_udi == NULL)
+ continue;
+ found_udi = strdup (storage_udi);
+ libhal_free_string (storage_udi);
+ break;
+ } else if (libhal_device_query_capability (hal_ctx, udi, "storage", &err2)) {
+ found_udi = strdup (udi);
+ }
+ LIBHAL_FREE_DBUS_ERROR(&err1);
+ LIBHAL_FREE_DBUS_ERROR(&err2);
+ }
+
+ libhal_free_string_array (hal_udis);
+
+ if (found_udi != NULL)
+ result = libhal_drive_from_udi (hal_ctx, found_udi);
+
+ free (found_udi);
+out:
+ return result;
+}
+
+
+/** Get the volume object for a given device file.
+ *
+ * @param hal_ctx libhal context to use
+ * @param device_file Name of special device file, e.g. '/dev/hda5'
+ * @return LibHalVolume object or NULL if it doesn't exist
+ */
+LibHalVolume *
+libhal_volume_from_device_file (LibHalContext *hal_ctx, const char *device_file)
+{
+ int i;
+ char **hal_udis;
+ int num_hal_udis;
+ LibHalVolume *result;
+ char *found_udi;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ result = NULL;
+ found_udi = NULL;
+
+ dbus_error_init (&error);
+ if ((hal_udis = libhal_manager_find_device_string_match (hal_ctx, "block.device",
+ device_file, &num_hal_udis, &error)) == NULL)
+ goto out;
+
+ for (i = 0; i < num_hal_udis; i++) {
+ char *udi;
+ udi = hal_udis[i];
+ if (libhal_device_query_capability (hal_ctx, udi, "volume", &error)) {
+ found_udi = strdup (udi);
+ break;
+ }
+ }
+
+ libhal_free_string_array (hal_udis);
+
+ if (found_udi != NULL)
+ result = libhal_volume_from_udi (hal_ctx, found_udi);
+
+ free (found_udi);
+out:
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ return result;
+}
+
+dbus_uint64_t
+libhal_volume_get_size (LibHalVolume *volume)
+{
+ if (volume->volume_size > 0)
+ return volume->volume_size;
+ else
+ return ((dbus_uint64_t)volume->block_size) * ((dbus_uint64_t)volume->num_blocks);
+}
+
+dbus_uint64_t
+libhal_volume_get_disc_capacity (LibHalVolume *volume)
+{
+ return volume->disc_capacity;
+}
+
+
+dbus_bool_t
+libhal_drive_is_hotpluggable (LibHalDrive *drive)
+{
+ return drive->is_hotpluggable;
+}
+
+dbus_bool_t
+libhal_drive_uses_removable_media (LibHalDrive *drive)
+{
+ return drive->is_removable;
+}
+
+dbus_bool_t
+libhal_drive_is_media_detected (LibHalDrive *drive)
+{
+ return drive->is_media_detected;
+}
+
+dbus_uint64_t
+libhal_drive_get_size (LibHalDrive *drive)
+{
+ return drive->drive_size;
+}
+
+dbus_uint64_t
+libhal_drive_get_media_size (LibHalDrive *drive)
+{
+ return drive->drive_media_size;
+}
+
+const char *
+libhal_drive_get_partition_scheme (LibHalDrive *drive)
+{
+ return drive->partition_scheme;
+}
+
+
+LibHalDriveType
+libhal_drive_get_type (LibHalDrive *drive)
+{
+ return drive->type;
+}
+
+LibHalDriveBus
+libhal_drive_get_bus (LibHalDrive *drive)
+{
+ return drive->bus;
+}
+
+LibHalDriveCdromCaps
+libhal_drive_get_cdrom_caps (LibHalDrive *drive)
+{
+ return drive->cdrom_caps;
+}
+
+unsigned int
+libhal_drive_get_device_major (LibHalDrive *drive)
+{
+ return drive->device_major;
+}
+
+unsigned int
+libhal_drive_get_device_minor (LibHalDrive *drive)
+{
+ return drive->device_minor;
+}
+
+const char *
+libhal_drive_get_type_textual (LibHalDrive *drive)
+{
+ return drive->type_textual;
+}
+
+const char *
+libhal_drive_get_device_file (LibHalDrive *drive)
+{
+ return drive->device_file;
+}
+
+const char *
+libhal_drive_get_udi (LibHalDrive *drive)
+{
+ return drive->udi;
+}
+
+const char *
+libhal_drive_get_serial (LibHalDrive *drive)
+{
+ return drive->serial;
+}
+
+const char *
+libhal_drive_get_firmware_version (LibHalDrive *drive)
+{
+ return drive->firmware_version;
+}
+
+const char *
+libhal_drive_get_model (LibHalDrive *drive)
+{
+ return drive->model;
+}
+
+const char *
+libhal_drive_get_vendor (LibHalDrive *drive)
+{
+ return drive->vendor;
+}
+
+/*****************************************************************************/
+
+const char *
+libhal_volume_get_udi (LibHalVolume *volume)
+{
+ return volume->udi;
+}
+
+const char *
+libhal_volume_get_device_file (LibHalVolume *volume)
+{
+ return volume->device_file;
+}
+
+unsigned int libhal_volume_get_device_major (LibHalVolume *volume)
+{
+ return volume->device_major;
+}
+
+unsigned int libhal_volume_get_device_minor (LibHalVolume *volume)
+{
+ return volume->device_minor;
+}
+
+const char *
+libhal_volume_get_fstype (LibHalVolume *volume)
+{
+ return volume->fstype;
+}
+
+const char *
+libhal_volume_get_fsversion (LibHalVolume *volume)
+{
+ return volume->fsversion;
+}
+
+LibHalVolumeUsage
+libhal_volume_get_fsusage (LibHalVolume *volume)
+{
+ return volume->fsusage;
+}
+
+dbus_bool_t
+libhal_volume_is_mounted (LibHalVolume *volume)
+{
+ return volume->is_mounted;
+}
+
+dbus_bool_t
+libhal_volume_is_mounted_read_only (LibHalVolume *volume)
+{
+ return volume->is_mounted_read_only;
+}
+
+dbus_bool_t
+libhal_volume_is_partition (LibHalVolume *volume)
+{
+ return volume->is_partition;
+}
+
+dbus_bool_t
+libhal_volume_is_disc (LibHalVolume *volume)
+{
+ return volume->is_disc;
+}
+
+unsigned int
+libhal_volume_get_partition_number (LibHalVolume *volume)
+{
+ return volume->partition_number;
+}
+
+const char *
+libhal_volume_get_partition_scheme (LibHalVolume *volume)
+{
+ return volume->partition_scheme;
+}
+
+const char *
+libhal_volume_get_partition_type (LibHalVolume *volume)
+{
+ return volume->partition_type;
+}
+
+const char *
+libhal_volume_get_partition_label (LibHalVolume *volume)
+{
+ return volume->partition_label;
+}
+
+const char *
+libhal_volume_get_partition_uuid (LibHalVolume *volume)
+{
+ return volume->partition_uuid;
+}
+
+const char **
+libhal_volume_get_partition_flags (LibHalVolume *volume)
+{
+ return (const char **) volume->partition_flags;
+}
+
+
+dbus_uint64_t
+libhal_volume_get_partition_start_offset (LibHalVolume *volume)
+{
+ return volume->partition_start_offset;
+}
+
+dbus_uint64_t
+libhal_volume_get_partition_media_size (LibHalVolume *volume)
+{
+ return volume->partition_media_size;
+}
+
+const char *
+libhal_volume_get_label (LibHalVolume *volume)
+{
+ return volume->volume_label;
+}
+
+const char *
+libhal_volume_get_mount_point (LibHalVolume *volume)
+{
+ return volume->mount_point;
+}
+
+const char *
+libhal_volume_get_uuid (LibHalVolume *volume)
+{
+ return volume->uuid;
+}
+
+dbus_bool_t
+libhal_volume_disc_has_audio (LibHalVolume *volume)
+{
+ return volume->disc_has_audio;
+}
+
+dbus_bool_t
+libhal_volume_disc_has_data (LibHalVolume *volume)
+{
+ return volume->disc_has_data;
+}
+
+dbus_bool_t
+libhal_volume_disc_is_blank (LibHalVolume *volume)
+{
+ return volume->disc_is_blank;
+}
+
+dbus_bool_t
+libhal_volume_disc_is_rewritable (LibHalVolume *volume)
+{
+ return volume->disc_is_rewritable;
+}
+
+dbus_bool_t
+libhal_volume_disc_is_appendable (LibHalVolume *volume)
+{
+ return volume->disc_is_appendable;
+}
+
+LibHalVolumeDiscType
+libhal_volume_get_disc_type (LibHalVolume *volume)
+{
+ return volume->disc_type;
+}
+
+dbus_bool_t
+libhal_volume_should_ignore (LibHalVolume *volume)
+{
+ return volume->ignore_volume;
+}
+
+char **
+libhal_drive_find_all_volumes (LibHalContext *hal_ctx, LibHalDrive *drive, int *num_volumes)
+{
+ int i;
+ char **udis;
+ int num_udis;
+ const char *drive_udi;
+ char **result;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ udis = NULL;
+ result = NULL;
+ *num_volumes = 0;
+
+ drive_udi = libhal_drive_get_udi (drive);
+ if (drive_udi == NULL)
+ goto out;
+
+ /* get initial list... */
+ dbus_error_init (&error);
+ if ((udis = libhal_manager_find_device_string_match (hal_ctx, "block.storage_device",
+ drive_udi, &num_udis, &error)) == NULL) {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ goto out;
+ }
+
+ result = malloc (sizeof (char *) * num_udis);
+ if (result == NULL)
+ goto out;
+
+ /* ...and filter out the single UDI that is the drive itself */
+ for (i = 0; i < num_udis; i++) {
+ if (strcmp (udis[i], drive_udi) == 0)
+ continue;
+ result[*num_volumes] = strdup (udis[i]);
+ *num_volumes = (*num_volumes) + 1;
+ }
+ /* set last element (above removed UDI) to NULL for libhal_free_string_array()*/
+ result[*num_volumes] = NULL;
+
+out:
+ libhal_free_string_array (udis);
+ return result;
+}
+
+const char *
+libhal_volume_crypto_get_backing_volume_udi (LibHalVolume *volume)
+{
+ return volume->crypto_backing_volume;
+}
+
+char *
+libhal_volume_crypto_get_clear_volume_udi (LibHalContext *hal_ctx, LibHalVolume *volume)
+{
+ DBusError error;
+ char **clear_devices;
+ int num_clear_devices;
+ char *result;
+
+ result = NULL;
+
+ LIBHAL_CHECK_LIBHALCONTEXT (hal_ctx, NULL);
+
+ dbus_error_init (&error);
+ clear_devices = libhal_manager_find_device_string_match (hal_ctx,
+ "volume.crypto_luks.clear.backing_volume",
+ volume->udi,
+ &num_clear_devices,
+ &error);
+ if (clear_devices != NULL) {
+
+ if (num_clear_devices >= 1) {
+ result = strdup (clear_devices[0]);
+ }
+ libhal_free_string_array (clear_devices);
+ }
+
+ return result;
+}
+
+
+/*************************************************************************/
+
+char *
+libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx)
+{
+ char *result;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ dbus_error_init (&error);
+ if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
+ "storage.policy.default.mount_root", &error)) == NULL)
+ LIBHAL_FREE_DBUS_ERROR(&error);
+
+ return result;
+}
+
+dbus_bool_t
+libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx)
+{
+ dbus_bool_t result;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, FALSE);
+
+ dbus_error_init (&error);
+ if ((result = libhal_device_get_property_bool (hal_ctx, "/org/freedesktop/Hal/devices/computer",
+ "storage.policy.default.use_managed_keyword", &error)) == FALSE)
+ LIBHAL_FREE_DBUS_ERROR(&error);
+
+ return result;
+}
+
+char *
+libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx)
+{
+ char *result;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ dbus_error_init (&error);
+ if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
+ "storage.policy.default.managed_keyword.primary", &error)) == NULL)
+ LIBHAL_FREE_DBUS_ERROR(&error);
+
+ return result;
+}
+
+char *
+libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx)
+{
+ char *result;
+ DBusError error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(hal_ctx, NULL);
+
+ dbus_error_init (&error);
+ if ((result = libhal_device_get_property_string (hal_ctx, "/org/freedesktop/Hal/devices/computer",
+ "storage.policy.default.managed_keyword.secondary", &error)) == NULL)
+ LIBHAL_FREE_DBUS_ERROR(&error);
+
+ return result;
+}
+
+/*************************************************************************/
+
+dbus_bool_t
+libhal_drive_policy_is_mountable (LibHalDrive *drive, LibHalStoragePolicy *policy)
+{
+ printf ("should_mount=%d, no_partitions_hint=%d\n", drive->should_mount, drive->no_partitions_hint);
+
+ return drive->should_mount && drive->no_partitions_hint;
+}
+
+const char *
+libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive, LibHalStoragePolicy *policy)
+{
+ return drive->desired_mount_point;
+}
+
+/* safely strcat() at most the remaining space in 'dst' */
+#define strcat_len(dst, src, dstmaxlen) do { \
+ dst[dstmaxlen - 1] = '\0'; \
+ strncat (dst, src, dstmaxlen - strlen (dst) - 1); \
+} while(0)
+
+
+static void
+mopts_collect (LibHalContext *hal_ctx, const char *namespace, int namespace_len,
+ const char *udi, char *options_string, size_t options_max_len, dbus_bool_t only_collect_imply_opts)
+{
+ LibHalPropertySet *properties;
+ LibHalPropertySetIterator it;
+ DBusError error;
+
+ if(hal_ctx == 0) {
+ fprintf (stderr,"%s %d : LibHalContext *ctx is NULL\n",__FILE__, __LINE__);
+ return;
+ }
+
+ dbus_error_init (&error);
+
+ /* first collect from root computer device */
+ properties = libhal_device_get_all_properties (hal_ctx, udi, &error);
+ if (properties == NULL ) {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ return;
+ }
+
+ for (libhal_psi_init (&it, properties); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
+ int type;
+ char *key;
+
+ type = libhal_psi_get_type (&it);
+ key = libhal_psi_get_key (&it);
+ if (libhal_psi_get_type (&it) == LIBHAL_PROPERTY_TYPE_BOOLEAN &&
+ strncmp (key, namespace, namespace_len - 1) == 0) {
+ const char *option = key + namespace_len - 1;
+ char *location;
+ dbus_bool_t is_imply_opt;
+
+ is_imply_opt = FALSE;
+ if (strcmp (option, "user") == 0 ||
+ strcmp (option, "users") == 0 ||
+ strcmp (option, "defaults") == 0 ||
+ strcmp (option, "pamconsole") == 0)
+ is_imply_opt = TRUE;
+
+
+ if (only_collect_imply_opts) {
+ if (!is_imply_opt)
+ continue;
+ } else {
+ if (is_imply_opt)
+ continue;
+ }
+
+ if (libhal_psi_get_bool (&it)) {
+ /* see if option is already there */
+ location = strstr (options_string, option);
+ if (location == NULL) {
+ if (strlen (options_string) > 0)
+ strcat_len (options_string, ",", options_max_len);
+ strcat_len (options_string, option, options_max_len);
+ }
+ } else {
+ /* remove option if already there */
+ location = strstr (options_string, option);
+ if (location != NULL) {
+ char *end;
+
+ end = strchr (location, ',');
+ if (end == NULL) {
+ location[0] = '\0';
+ } else {
+ strcpy (location, end + 1); /* skip the extra comma */
+ }
+ }
+
+ }
+ }
+ }
+
+ libhal_free_property_set (properties);
+}
+
+
+const char *
+libhal_drive_policy_get_mount_options (LibHalDrive *drive, LibHalStoragePolicy *policy)
+{
+ const char *result;
+ char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
+ char stor_mount_option_begin[] = "storage.policy.mount_option.";
+
+ result = NULL;
+ drive->mount_options[0] = '\0';
+
+ /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */
+ mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
+ "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
+ mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
+ drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
+ /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
+ mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
+ "/org/freedesktop/Hal/devices/computer", drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
+ mopts_collect (drive->hal_ctx, stor_mount_option_begin, sizeof (stor_mount_option_begin),
+ drive->udi, drive->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
+
+ result = drive->mount_options;
+
+ return result;
+}
+
+const char *
+libhal_drive_policy_get_mount_fs (LibHalDrive *drive, LibHalStoragePolicy *policy)
+{
+ return drive->mount_filesystem;
+}
+
+
+dbus_bool_t
+libhal_volume_policy_is_mountable (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ return drive->should_mount && volume->should_mount;
+}
+
+const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ return volume->desired_mount_point;
+}
+
+const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ const char *result;
+ char stor_mount_option_default_begin[] = "storage.policy.default.mount_option.";
+ char vol_mount_option_begin[] = "volume.policy.mount_option.";
+
+ result = NULL;
+ volume->mount_options[0] = '\0';
+
+ /* ensure ('pamconsole', 'user', 'users', 'defaults' options that imply other options), are first */
+ mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
+ "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
+ mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
+ volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, TRUE);
+ /* collect options != ('pamconsole', 'user', 'users', 'defaults' options that imply other options) */
+ mopts_collect (drive->hal_ctx, stor_mount_option_default_begin, sizeof (stor_mount_option_default_begin),
+ "/org/freedesktop/Hal/devices/computer", volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
+ mopts_collect (drive->hal_ctx, vol_mount_option_begin, sizeof (vol_mount_option_begin),
+ volume->udi, volume->mount_options, MOUNT_OPTIONS_SIZE, FALSE);
+
+ result = volume->mount_options;
+
+ return result;
+}
+
+const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive, LibHalVolume *volume, LibHalStoragePolicy *policy)
+{
+ return volume->mount_filesystem;
+}
+
+dbus_bool_t
+libhal_drive_no_partitions_hint (LibHalDrive *drive)
+{
+ return drive->no_partitions_hint;
+}
+
+/** @} */
diff --git a/usr/src/lib/hal/libhal-storage/common/libhal-storage.h b/usr/src/lib/hal/libhal-storage/common/libhal-storage.h
new file mode 100644
index 0000000000..c88a389feb
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/common/libhal-storage.h
@@ -0,0 +1,362 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * libhal-storage.h : HAL convenience library for storage devices and volumes
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author: David Zeuthen <davidz@redhat.com>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LIBHAL_STORAGE_H
+#define LIBHAL_STORAGE_H
+
+#include <libhal.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#if 0
+} /* shut up emacs indenting */
+#endif
+#endif
+
+struct LibHalDrive_s;
+typedef struct LibHalDrive_s LibHalDrive;
+struct LibHalVolume_s;
+typedef struct LibHalVolume_s LibHalVolume;
+struct LibHalStoragePolicy_s;
+typedef struct LibHalStoragePolicy_s LibHalStoragePolicy;
+
+
+typedef enum {
+ LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK = 0x10000,
+ LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_IDE = 0x10001,
+ LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_SCSI = 0x10002,
+ LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_USB = 0x10003,
+ LIBHAL_STORAGE_ICON_DRIVE_REMOVABLE_DISK_IEEE1394 = 0x10004,
+ LIBHAL_STORAGE_ICON_DRIVE_DISK = 0x10100,
+ LIBHAL_STORAGE_ICON_DRIVE_DISK_IDE = 0x10101,
+ LIBHAL_STORAGE_ICON_DRIVE_DISK_SCSI = 0x10102,
+ LIBHAL_STORAGE_ICON_DRIVE_DISK_USB = 0x10103,
+ LIBHAL_STORAGE_ICON_DRIVE_DISK_IEEE1394 = 0x10104,
+ LIBHAL_STORAGE_ICON_DRIVE_CDROM = 0x10200,
+ LIBHAL_STORAGE_ICON_DRIVE_CDROM_IDE = 0x10201,
+ LIBHAL_STORAGE_ICON_DRIVE_CDROM_SCSI = 0x10202,
+ LIBHAL_STORAGE_ICON_DRIVE_CDROM_USB = 0x10203,
+ LIBHAL_STORAGE_ICON_DRIVE_CDROM_IEEE1394 = 0x10204,
+ LIBHAL_STORAGE_ICON_DRIVE_FLOPPY = 0x10300,
+ LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_IDE = 0x10301,
+ LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_SCSI = 0x10302,
+ LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_USB = 0x10303,
+ LIBHAL_STORAGE_ICON_DRIVE_FLOPPY_IEEE1394 = 0x10304,
+ LIBHAL_STORAGE_ICON_DRIVE_TAPE = 0x10400,
+ LIBHAL_STORAGE_ICON_DRIVE_COMPACT_FLASH = 0x10500,
+ LIBHAL_STORAGE_ICON_DRIVE_MEMORY_STICK = 0x10600,
+ LIBHAL_STORAGE_ICON_DRIVE_SMART_MEDIA = 0x10700,
+ LIBHAL_STORAGE_ICON_DRIVE_SD_MMC = 0x10800,
+ LIBHAL_STORAGE_ICON_DRIVE_CAMERA = 0x10900,
+ LIBHAL_STORAGE_ICON_DRIVE_PORTABLE_AUDIO_PLAYER = 0x10a00,
+ LIBHAL_STORAGE_ICON_DRIVE_ZIP = 0x10b00,
+ LIBHAL_STORAGE_ICON_DRIVE_JAZ = 0x10c00,
+ LIBHAL_STORAGE_ICON_DRIVE_FLASH_KEY = 0x10d00,
+
+ LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK = 0x20000,
+ LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_IDE = 0x20001,
+ LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_SCSI = 0x20002,
+ LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_USB = 0x20003,
+ LIBHAL_STORAGE_ICON_VOLUME_REMOVABLE_DISK_IEEE1394 = 0x20004,
+ LIBHAL_STORAGE_ICON_VOLUME_DISK = 0x20100,
+ LIBHAL_STORAGE_ICON_VOLUME_DISK_IDE = 0x20101,
+ LIBHAL_STORAGE_ICON_VOLUME_DISK_SCSI = 0x20102,
+ LIBHAL_STORAGE_ICON_VOLUME_DISK_USB = 0x20103,
+ LIBHAL_STORAGE_ICON_VOLUME_DISK_IEEE1394 = 0x20104,
+ LIBHAL_STORAGE_ICON_VOLUME_CDROM = 0x20200,
+ LIBHAL_STORAGE_ICON_VOLUME_CDROM_IDE = 0x20201,
+ LIBHAL_STORAGE_ICON_VOLUME_CDROM_SCSI = 0x20202,
+ LIBHAL_STORAGE_ICON_VOLUME_CDROM_USB = 0x20203,
+ LIBHAL_STORAGE_ICON_VOLUME_CDROM_IEEE1394 = 0x20204,
+ LIBHAL_STORAGE_ICON_VOLUME_FLOPPY = 0x20300,
+ LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_IDE = 0x20301,
+ LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_SCSI = 0x20302,
+ LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_USB = 0x20303,
+ LIBHAL_STORAGE_ICON_VOLUME_FLOPPY_IEEE1394 = 0x20304,
+ LIBHAL_STORAGE_ICON_VOLUME_TAPE = 0x20400,
+ LIBHAL_STORAGE_ICON_VOLUME_COMPACT_FLASH = 0x20500,
+ LIBHAL_STORAGE_ICON_VOLUME_MEMORY_STICK = 0x20600,
+ LIBHAL_STORAGE_ICON_VOLUME_SMART_MEDIA = 0x20700,
+ LIBHAL_STORAGE_ICON_VOLUME_SD_MMC = 0x20800,
+ LIBHAL_STORAGE_ICON_VOLUME_CAMERA = 0x20900,
+ LIBHAL_STORAGE_ICON_VOLUME_PORTABLE_AUDIO_PLAYER = 0x20a00,
+ LIBHAL_STORAGE_ICON_VOLUME_ZIP = 0x20b00,
+ LIBHAL_STORAGE_ICON_VOLUME_JAZ = 0x20c00,
+ LIBHAL_STORAGE_ICON_VOLUME_FLASH_KEY = 0x20d00,
+
+ LIBHAL_STORAGE_ICON_DISC_CDROM = 0x30000,
+ LIBHAL_STORAGE_ICON_DISC_CDR = 0x30001,
+ LIBHAL_STORAGE_ICON_DISC_CDRW = 0x30002,
+ LIBHAL_STORAGE_ICON_DISC_DVDROM = 0x30003,
+ LIBHAL_STORAGE_ICON_DISC_DVDRAM = 0x30004,
+ LIBHAL_STORAGE_ICON_DISC_DVDR = 0x30005,
+ LIBHAL_STORAGE_ICON_DISC_DVDRW = 0x30006,
+ LIBHAL_STORAGE_ICON_DISC_DVDPLUSR = 0x30007,
+ LIBHAL_STORAGE_ICON_DISC_DVDPLUSRW = 0x30008,
+ LIBHAL_STORAGE_ICON_DISC_DVDPLUSRWDL = 0x30009,
+ LIBHAL_STORAGE_ICON_DISC_BDROM = 0x3000a,
+ LIBHAL_STORAGE_ICON_DISC_BDR = 0x3000b,
+ LIBHAL_STORAGE_ICON_DISC_BDRE = 0x3000c,
+ LIBHAL_STORAGE_ICON_DISC_HDDVDROM = 0x3000d,
+ LIBHAL_STORAGE_ICON_DISC_HDDVDR = 0x3000e,
+ LIBHAL_STORAGE_ICON_DISC_HDDVDRW = 0x3000f
+} LibHalStoragePolicyIcon;
+
+typedef struct {
+ LibHalStoragePolicyIcon icon;
+ const char *icon_path;
+} LibHalStoragePolicyIconPair;
+
+LibHalStoragePolicy *libhal_storage_policy_new (void) LIBHAL_DEPRECATED;
+void libhal_storage_policy_free (LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+
+void libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy,
+ LibHalStoragePolicyIcon icon,
+ const char *path) LIBHAL_DEPRECATED;
+
+void libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy,
+ LibHalStoragePolicyIconPair *pairs) LIBHAL_DEPRECATED;
+const char *libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy,
+ LibHalStoragePolicyIcon icon) LIBHAL_DEPRECATED;
+
+typedef enum {
+ LIBHAL_DRIVE_BUS_UNKNOWN = 0x00,
+ LIBHAL_DRIVE_BUS_IDE = 0x01,
+ LIBHAL_DRIVE_BUS_SCSI = 0x02,
+ LIBHAL_DRIVE_BUS_USB = 0x03,
+ LIBHAL_DRIVE_BUS_IEEE1394 = 0x04,
+ LIBHAL_DRIVE_BUS_CCW = 0x05
+} LibHalDriveBus;
+
+typedef enum {
+ LIBHAL_DRIVE_TYPE_REMOVABLE_DISK = 0x00,
+ LIBHAL_DRIVE_TYPE_DISK = 0x01,
+ LIBHAL_DRIVE_TYPE_CDROM = 0x02,
+ LIBHAL_DRIVE_TYPE_FLOPPY = 0x03,
+ LIBHAL_DRIVE_TYPE_TAPE = 0x04,
+ LIBHAL_DRIVE_TYPE_COMPACT_FLASH = 0x05,
+ LIBHAL_DRIVE_TYPE_MEMORY_STICK = 0x06,
+ LIBHAL_DRIVE_TYPE_SMART_MEDIA = 0x07,
+ LIBHAL_DRIVE_TYPE_SD_MMC = 0x08,
+ LIBHAL_DRIVE_TYPE_CAMERA = 0x09,
+ LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER = 0x0a,
+ LIBHAL_DRIVE_TYPE_ZIP = 0x0b,
+ LIBHAL_DRIVE_TYPE_JAZ = 0x0c,
+ LIBHAL_DRIVE_TYPE_FLASHKEY = 0x0d
+} LibHalDriveType;
+
+typedef enum {
+ LIBHAL_DRIVE_CDROM_CAPS_CDROM = 0x00001,
+ LIBHAL_DRIVE_CDROM_CAPS_CDR = 0x00002,
+ LIBHAL_DRIVE_CDROM_CAPS_CDRW = 0x00004,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDRAM = 0x00008,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDROM = 0x00010,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDR = 0x00020,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDRW = 0x00040,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR = 0x00080,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW = 0x00100,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL = 0x00200,
+ LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL = 0x00400,
+ LIBHAL_DRIVE_CDROM_CAPS_BDROM = 0x00800,
+ LIBHAL_DRIVE_CDROM_CAPS_BDR = 0x01000,
+ LIBHAL_DRIVE_CDROM_CAPS_BDRE = 0x02000,
+ LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM = 0x04000,
+ LIBHAL_DRIVE_CDROM_CAPS_HDDVDR = 0x08000,
+ LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW = 0x10000
+} LibHalDriveCdromCaps;
+
+LibHalDrive *libhal_drive_from_udi (LibHalContext *hal_ctx,
+ const char *udi);
+LibHalDrive *libhal_drive_from_device_file (LibHalContext *hal_ctx,
+ const char *device_file);
+void libhal_drive_free (LibHalDrive *drive);
+
+dbus_bool_t libhal_drive_is_hotpluggable (LibHalDrive *drive);
+dbus_bool_t libhal_drive_uses_removable_media (LibHalDrive *drive);
+dbus_bool_t libhal_drive_is_media_detected (LibHalDrive *drive);
+dbus_uint64_t libhal_drive_get_size (LibHalDrive *drive);
+dbus_uint64_t libhal_drive_get_media_size (LibHalDrive *drive);
+const char *libhal_drive_get_partition_scheme (LibHalDrive *drive);
+dbus_bool_t libhal_drive_no_partitions_hint (LibHalDrive *drive);
+dbus_bool_t libhal_drive_requires_eject (LibHalDrive *drive);
+LibHalDriveType libhal_drive_get_type (LibHalDrive *drive);
+LibHalDriveBus libhal_drive_get_bus (LibHalDrive *drive);
+LibHalDriveCdromCaps libhal_drive_get_cdrom_caps (LibHalDrive *drive);
+unsigned int libhal_drive_get_device_major (LibHalDrive *drive);
+unsigned int libhal_drive_get_device_minor (LibHalDrive *drive);
+const char *libhal_drive_get_type_textual (LibHalDrive *drive);
+const char *libhal_drive_get_device_file (LibHalDrive *drive);
+const char *libhal_drive_get_udi (LibHalDrive *drive);
+const char *libhal_drive_get_serial (LibHalDrive *drive);
+const char *libhal_drive_get_firmware_version (LibHalDrive *drive);
+const char *libhal_drive_get_model (LibHalDrive *drive);
+const char *libhal_drive_get_vendor (LibHalDrive *drive);
+const char *libhal_drive_get_physical_device_udi (LibHalDrive *drive);
+
+const char *libhal_drive_get_dedicated_icon_drive (LibHalDrive *drive);
+const char *libhal_drive_get_dedicated_icon_volume (LibHalDrive *drive);
+
+char *libhal_drive_policy_compute_display_name (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+char *libhal_drive_policy_compute_icon_name (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+
+dbus_bool_t libhal_drive_policy_is_mountable (LibHalDrive *drive,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+const char *libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+const char *libhal_drive_policy_get_mount_options (LibHalDrive *drive,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+const char *libhal_drive_policy_get_mount_fs (LibHalDrive *drive,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+
+char **libhal_drive_find_all_volumes (LibHalContext *hal_ctx,
+ LibHalDrive *drive,
+ int *num_volumes);
+
+
+char *libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+dbus_bool_t libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+char *libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+char *libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+
+
+typedef enum {
+ LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM,
+ LIBHAL_VOLUME_USAGE_PARTITION_TABLE,
+ LIBHAL_VOLUME_USAGE_RAID_MEMBER,
+ LIBHAL_VOLUME_USAGE_CRYPTO,
+ LIBHAL_VOLUME_USAGE_UNKNOWN,
+ LIBHAL_VOLUME_USAGE_OTHER
+} LibHalVolumeUsage;
+
+typedef enum {
+ LIBHAL_VOLUME_DISC_TYPE_CDROM = 0x00,
+ LIBHAL_VOLUME_DISC_TYPE_CDR = 0x01,
+ LIBHAL_VOLUME_DISC_TYPE_CDRW = 0x02,
+ LIBHAL_VOLUME_DISC_TYPE_DVDROM = 0x03,
+ LIBHAL_VOLUME_DISC_TYPE_DVDRAM = 0x04,
+ LIBHAL_VOLUME_DISC_TYPE_DVDR = 0x05,
+ LIBHAL_VOLUME_DISC_TYPE_DVDRW = 0x06,
+ LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR = 0x07,
+ LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW = 0x08,
+ LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL = 0x09,
+ LIBHAL_VOLUME_DISC_TYPE_BDROM = 0x0a,
+ LIBHAL_VOLUME_DISC_TYPE_BDR = 0x0b,
+ LIBHAL_VOLUME_DISC_TYPE_BDRE = 0x0c,
+ LIBHAL_VOLUME_DISC_TYPE_HDDVDROM = 0x0d,
+ LIBHAL_VOLUME_DISC_TYPE_HDDVDR = 0x0e,
+ LIBHAL_VOLUME_DISC_TYPE_HDDVDRW = 0x0f
+} LibHalVolumeDiscType;
+
+LibHalVolume *libhal_volume_from_udi (LibHalContext *hal_ctx,
+ const char *udi);
+LibHalVolume *libhal_volume_from_device_file (LibHalContext *hal_ctx,
+ const char *device_file);
+void libhal_volume_free (LibHalVolume *volume);
+dbus_uint64_t libhal_volume_get_size (LibHalVolume *volume);
+dbus_uint64_t libhal_volume_get_disc_capacity (LibHalVolume *volume);
+
+const char *libhal_volume_get_udi (LibHalVolume *volume);
+const char *libhal_volume_get_device_file (LibHalVolume *volume);
+unsigned int libhal_volume_get_device_major (LibHalVolume *volume);
+unsigned int libhal_volume_get_device_minor (LibHalVolume *volume);
+const char *libhal_volume_get_fstype (LibHalVolume *volume);
+const char *libhal_volume_get_fsversion (LibHalVolume *volume);
+LibHalVolumeUsage libhal_volume_get_fsusage (LibHalVolume *volume);
+dbus_bool_t libhal_volume_is_mounted (LibHalVolume *volume);
+dbus_bool_t libhal_volume_is_mounted_read_only (LibHalVolume *volume);
+dbus_bool_t libhal_volume_is_partition (LibHalVolume *volume);
+dbus_bool_t libhal_volume_is_disc (LibHalVolume *volume);
+
+const char *libhal_volume_get_partition_scheme (LibHalVolume *volume);
+const char *libhal_volume_get_partition_type (LibHalVolume *volume);
+const char *libhal_volume_get_partition_label (LibHalVolume *volume);
+const char *libhal_volume_get_partition_uuid (LibHalVolume *volume);
+const char **libhal_volume_get_partition_flags (LibHalVolume *volume);
+unsigned int libhal_volume_get_partition_number (LibHalVolume *volume);
+dbus_uint64_t libhal_volume_get_partition_start_offset (LibHalVolume *volume);
+dbus_uint64_t libhal_volume_get_partition_media_size (LibHalVolume *volume);
+
+const char *libhal_volume_get_label (LibHalVolume *volume);
+const char *libhal_volume_get_mount_point (LibHalVolume *volume);
+const char *libhal_volume_get_uuid (LibHalVolume *volume);
+const char *libhal_volume_get_storage_device_udi (LibHalVolume *volume);
+
+const char *libhal_volume_crypto_get_backing_volume_udi (LibHalVolume *volume);
+char *libhal_volume_crypto_get_clear_volume_udi (LibHalContext *hal_ctx, LibHalVolume *volume);
+
+
+dbus_bool_t libhal_volume_disc_has_audio (LibHalVolume *volume);
+dbus_bool_t libhal_volume_disc_has_data (LibHalVolume *volume);
+dbus_bool_t libhal_volume_disc_is_blank (LibHalVolume *volume);
+dbus_bool_t libhal_volume_disc_is_rewritable (LibHalVolume *volume);
+dbus_bool_t libhal_volume_disc_is_appendable (LibHalVolume *volume);
+LibHalVolumeDiscType libhal_volume_get_disc_type (LibHalVolume *volume);
+
+int libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) LIBHAL_DEPRECATED;
+dbus_uint64_t libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) LIBHAL_DEPRECATED;
+dbus_uint64_t libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) LIBHAL_DEPRECATED;
+
+
+dbus_bool_t libhal_volume_should_ignore (LibHalVolume *volume);
+
+char *libhal_volume_policy_compute_size_as_string (LibHalVolume *volume) LIBHAL_DEPRECATED;
+
+char *libhal_volume_policy_compute_display_name (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+char *libhal_volume_policy_compute_icon_name (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+
+dbus_bool_t libhal_volume_policy_should_be_visible (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy,
+ const char *target_mount_point) LIBHAL_DEPRECATED;
+
+dbus_bool_t libhal_volume_policy_is_mountable (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive,
+ LibHalVolume *volume,
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* LIBHAL_STORAGE_H */
diff --git a/usr/src/lib/hal/libhal-storage/common/llib-lhal-storage b/usr/src/lib/hal/libhal-storage/common/llib-lhal-storage
new file mode 100644
index 0000000000..93af701653
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/common/llib-lhal-storage
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <hal/libhal-storage.h>
diff --git a/usr/src/lib/hal/libhal-storage/common/mapfile-vers b/usr/src/lib/hal/libhal-storage/common/mapfile-vers
new file mode 100644
index 0000000000..329b75b641
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/common/mapfile-vers
@@ -0,0 +1,120 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUNW_1.1 {
+ global:
+ libhal_storage_policy_new;
+ libhal_storage_policy_free;
+ libhal_storage_policy_set_icon_path;
+ libhal_storage_policy_set_icon_mapping;
+ libhal_storage_policy_lookup_icon;
+ libhal_drive_from_udi;
+ libhal_drive_from_device_file;
+ libhal_drive_free;
+ libhal_drive_is_hotpluggable;
+ libhal_drive_uses_removable_media;
+ libhal_drive_no_partitions_hint;
+ libhal_drive_requires_eject;
+ libhal_drive_get_type;
+ libhal_drive_get_bus;
+ libhal_drive_get_cdrom_caps;
+ libhal_drive_get_device_major;
+ libhal_drive_get_device_minor;
+ libhal_drive_get_type_textual;
+ libhal_drive_get_device_file;
+ libhal_drive_get_udi;
+ libhal_drive_get_serial;
+ libhal_drive_get_firmware_version;
+ libhal_drive_get_model;
+ libhal_drive_get_vendor;
+ libhal_drive_get_physical_device_udi;
+ libhal_drive_get_dedicated_icon_drive;
+ libhal_drive_get_dedicated_icon_volume;
+ libhal_drive_get_partition_scheme;
+ libhal_drive_policy_compute_display_name;
+ libhal_drive_policy_compute_icon_name;
+ libhal_drive_policy_is_mountable;
+ libhal_drive_policy_get_desired_mount_point;
+ libhal_drive_policy_get_mount_options;
+ libhal_drive_policy_get_mount_fs;
+ libhal_drive_find_all_volumes;
+ libhal_drive_policy_default_get_mount_root;
+ libhal_drive_policy_default_use_managed_keyword;
+ libhal_drive_policy_default_get_managed_keyword_primary;
+ libhal_drive_policy_default_get_managed_keyword_secondary;
+ libhal_volume_from_udi;
+ libhal_volume_from_device_file;
+ libhal_volume_free;
+ libhal_volume_get_size;
+ libhal_volume_get_disc_capacity;
+ libhal_volume_get_udi;
+ libhal_volume_get_device_file;
+ libhal_volume_get_device_major;
+ libhal_volume_get_device_minor;
+ libhal_volume_get_fstype;
+ libhal_volume_get_fsversion;
+ libhal_volume_get_fsusage;
+ libhal_volume_is_mounted;
+ libhal_volume_is_mounted_read_only;
+ libhal_volume_is_partition;
+ libhal_volume_is_disc;
+ libhal_volume_get_partition_number;
+ libhal_volume_get_label;
+ libhal_volume_get_mount_point;
+ libhal_volume_get_uuid;
+ libhal_volume_get_storage_device_udi;
+ libhal_volume_crypto_get_backing_volume_udi;
+ libhal_volume_crypto_get_clear_volume_udi;
+ libhal_volume_disc_has_audio;
+ libhal_volume_disc_has_data;
+ libhal_volume_disc_is_blank;
+ libhal_volume_disc_is_rewritable;
+ libhal_volume_disc_is_appendable;
+ libhal_volume_get_disc_type;
+ libhal_volume_get_msdos_part_table_type;
+ libhal_volume_get_partition_scheme;
+ libhal_volume_get_partition_type;
+ libhal_volume_get_partition_label;
+ libhal_volume_get_partition_uuid;
+ libhal_volume_get_partition_flags;
+ libhal_volume_should_ignore;
+ libhal_volume_policy_compute_size_as_string;
+ libhal_volume_policy_compute_display_name;
+ libhal_volume_policy_compute_icon_name;
+ libhal_volume_policy_should_be_visible;
+ libhal_volume_policy_is_mountable;
+ libhal_volume_policy_get_desired_mount_point;
+ libhal_volume_policy_get_mount_options;
+ libhal_volume_policy_get_mount_fs;
+};
+
+SUNWprivate_1.1 {
+ global:
+ SUNWprivate_1.1;
+ local:
+ *;
+};
diff --git a/usr/src/lib/hal/libhal-storage/i386/Makefile b/usr/src/lib/hal/libhal-storage/i386/Makefile
new file mode 100644
index 0000000000..8643a8305f
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK)
diff --git a/usr/src/lib/hal/libhal-storage/sparc/Makefile b/usr/src/lib/hal/libhal-storage/sparc/Makefile
new file mode 100644
index 0000000000..8643a8305f
--- /dev/null
+++ b/usr/src/lib/hal/libhal-storage/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK)
diff --git a/usr/src/lib/hal/libhal/Makefile b/usr/src/lib/hal/libhal/Makefile
new file mode 100644
index 0000000000..b90c784c0d
--- /dev/null
+++ b/usr/src/lib/hal/libhal/Makefile
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+include ../../Makefile.lib
+include ../Makefile.com
+
+HDRS = libhal.h
+HDRDIR = common
+ROOTHDRDIR = $(ROOT)/usr/include/hal
+
+SUBDIRS= $(MACH)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+
+.KEEP_STATE:
+
+all clean clobber install: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/hal/libhal/Makefile.com b/usr/src/lib/hal/libhal/Makefile.com
new file mode 100644
index 0000000000..9741f9de72
--- /dev/null
+++ b/usr/src/lib/hal/libhal/Makefile.com
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# usr/src/lib/hal/libhal/Makefile.com
+#
+
+LIBRARY = libhal.a
+VERS = .1.0.0
+VERS_MAJ = .1
+OBJECTS = libhal.o
+LIBPCSRC = hal.pc
+
+include ../../Makefile.com
+
+LIBS = $(DYNLIB) $(LINTLIB)
+LDLIBS += -lc -ldbus-1
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -DGETTEXT_PACKAGE=\"$(HAL_GETTEXT_PACKAGE)\" -DENABLE_NLS
+
+ROOTMAJLINK = $(ROOTLIBDIR)/$(LIBRARY:.a=.so)$(VERS_MAJ)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+$(ROOTMAJLINK):
+ -$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/hal/libhal/common/hal.pc.in b/usr/src/lib/hal/libhal/common/hal.pc.in
new file mode 100644
index 0000000000..e814f914e1
--- /dev/null
+++ b/usr/src/lib/hal/libhal/common/hal.pc.in
@@ -0,0 +1,19 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Licensed under the Academic Free License version 2.1
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: hal
+Description: Free desktop hardware abstraction layer
+Version: __VERSION__
+Requires: dbus-1
+Libs: -L${libdir} -lhal
+Cflags: -DDBUS_API_SUBJECT_TO_CHANGE -I${includedir}/hal
diff --git a/usr/src/lib/hal/libhal/common/libhal.c b/usr/src/lib/hal/libhal/common/libhal.c
new file mode 100644
index 0000000000..e88ca3d869
--- /dev/null
+++ b/usr/src/lib/hal/libhal/common/libhal.c
@@ -0,0 +1,3992 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * libhal.c : HAL daemon C convenience library
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dbus/dbus.h>
+
+#include "libhal.h"
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) dgettext (GETTEXT_PACKAGE, String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String)
+# define N_(String) (String)
+#endif
+
+static char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements);
+
+static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter);
+
+
+
+/**
+ * libhal_free_string_array:
+ * @str_array: the array to be freed
+ *
+ * Frees a NULL-terminated array of strings. If passed NULL, does nothing.
+ */
+void
+libhal_free_string_array (char **str_array)
+{
+ if (str_array != NULL) {
+ int i;
+
+ for (i = 0; str_array[i] != NULL; i++) {
+ free (str_array[i]);
+ str_array[i] = NULL;
+ }
+ free (str_array);
+ str_array = NULL;
+ }
+}
+
+
+/**
+ * libhal_get_string_array_from_iter:
+ * @iter: the message iterator to extract the strings from
+ * @num_elements: pointer to an integer where to store number of elements (can be NULL)
+ *
+ * Creates a NULL terminated array of strings from a dbus message iterator.
+ *
+ * Returns: pointer to the string array
+ */
+static char **
+libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements)
+{
+ int count;
+ char **buffer;
+
+ count = 0;
+ buffer = (char **)malloc (sizeof (char *) * 8);
+
+ if (buffer == NULL)
+ goto oom;
+
+ buffer[0] = NULL;
+ while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) {
+ const char *value;
+ char *str;
+
+ if ((count % 8) == 0 && count != 0) {
+ buffer = realloc (buffer, sizeof (char *) * (count + 8));
+ if (buffer == NULL)
+ goto oom;
+ }
+
+ dbus_message_iter_get_basic (iter, &value);
+ str = strdup (value);
+ if (str == NULL)
+ goto oom;
+
+ buffer[count] = str;
+
+ dbus_message_iter_next(iter);
+ count++;
+ }
+
+ if ((count % 8) == 0) {
+ buffer = realloc (buffer, sizeof (char *) * (count + 1));
+ if (buffer == NULL)
+ goto oom;
+ }
+
+ buffer[count] = NULL;
+ if (num_elements != NULL)
+ *num_elements = count;
+ return buffer;
+
+oom:
+ fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
+ return NULL;
+
+}
+
+/**
+ * libhal_free_string:
+ * @str: the nul-terminated sting to free
+ *
+ * Used to free strings returned by libhal.
+ */
+void
+libhal_free_string (char *str)
+{
+ if (str != NULL) {
+ free (str);
+ str = NULL;
+ }
+}
+
+
+/**
+ * LibHalPropertySet:
+ *
+ * Represents a set of properties. Opaque; use the
+ * libhal_property_set_*() family of functions to access it.
+ */
+struct LibHalPropertySet_s {
+ unsigned int num_properties; /**< Number of properties in set */
+ LibHalProperty *properties_head;
+ /**< Pointer to first property or NULL
+ * if there are no properties */
+};
+
+/**
+ * LibHalProperty:
+ *
+ * Represents a property. Opaque.
+ */
+struct LibHalProperty_s {
+ int type; /**< Type of property */
+ char *key; /**< ASCII string */
+
+ /** Possible values of the property */
+ union {
+ char *str_value; /**< UTF-8 zero-terminated string */
+ dbus_int32_t int_value;
+ /**< 32-bit signed integer */
+ dbus_uint64_t uint64_value;
+ /**< 64-bit unsigned integer */
+ double double_value; /**< IEEE754 double precision float */
+ dbus_bool_t bool_value;
+ /**< Truth value */
+
+ char **strlist_value; /**< List of UTF-8 zero-terminated strings */
+ } v;
+
+ LibHalProperty *next; /**< Next property or NULL if this is
+ * the last */
+};
+
+/**
+ * LibHalContext:
+ *
+ * Context for connection to the HAL daemon. Opaque, use the
+ * libhal_ctx_*() family of functions to access it.
+ */
+struct LibHalContext_s {
+ DBusConnection *connection; /**< D-BUS connection */
+ dbus_bool_t is_initialized; /**< Are we initialised */
+ dbus_bool_t is_shutdown; /**< Have we been shutdown */
+ dbus_bool_t cache_enabled; /**< Is the cache enabled */
+ dbus_bool_t is_direct; /**< Whether the connection to hald is direct */
+
+ /** Device added */
+ LibHalDeviceAdded device_added;
+
+ /** Device removed */
+ LibHalDeviceRemoved device_removed;
+
+ /** Device got a new capability */
+ LibHalDeviceNewCapability device_new_capability;
+
+ /** Device got a new capability */
+ LibHalDeviceLostCapability device_lost_capability;
+
+ /** A property of a device changed */
+ LibHalDevicePropertyModified device_property_modified;
+
+ /** A non-continous event on the device occured */
+ LibHalDeviceCondition device_condition;
+
+ void *user_data; /**< User data */
+};
+
+/**
+ * libhal_ctx_set_user_data:
+ * @ctx: the context for the connection to hald
+ * @user_data: user data
+ *
+ * Set user data for the context.
+ *
+ * Returns: TRUE if user data was successfully set, FALSE if otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_user_data(LibHalContext *ctx, void *user_data)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+ ctx->user_data = user_data;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_get_user_data:
+ * @ctx: the context for the connection to hald
+ *
+ * Get user data for the context.
+ *
+ * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set.
+ */
+void*
+libhal_ctx_get_user_data(LibHalContext *ctx)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+ return ctx->user_data;
+}
+
+
+/**
+ * libhal_property_fill_value_from_variant:
+ * @p: the property to fill in
+ * @var_iter: variant iterator to extract the value from
+ *
+ * Fills in the value for the LibHalProperty given a variant iterator.
+ *
+ * Returns: Whether the value was put in.
+ */
+static dbus_bool_t
+libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter)
+{
+ DBusMessageIter iter_array;
+ switch (p->type) {
+ case DBUS_TYPE_ARRAY:
+ if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING)
+ return FALSE;
+
+ dbus_message_iter_recurse (var_iter, &iter_array);
+ p->v.strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL);
+
+ p->type = LIBHAL_PROPERTY_TYPE_STRLIST;
+
+ break;
+ case DBUS_TYPE_STRING:
+ {
+ const char *v;
+
+ dbus_message_iter_get_basic (var_iter, &v);
+
+ p->v.str_value = strdup (v);
+ if (p->v.str_value == NULL)
+ return FALSE;
+ p->type = LIBHAL_PROPERTY_TYPE_STRING;
+
+ break;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t v;
+
+ dbus_message_iter_get_basic (var_iter, &v);
+
+ p->v.int_value = v;
+ p->type = LIBHAL_PROPERTY_TYPE_INT32;
+
+ break;
+ }
+ case DBUS_TYPE_UINT64:
+ {
+ dbus_uint64_t v;
+
+ dbus_message_iter_get_basic (var_iter, &v);
+
+ p->v.uint64_value = v;
+ p->type = LIBHAL_PROPERTY_TYPE_UINT64;
+
+ break;
+ }
+ case DBUS_TYPE_DOUBLE:
+ {
+ double v;
+
+ dbus_message_iter_get_basic (var_iter, &v);
+
+ p->v.double_value = v;
+ p->type = LIBHAL_PROPERTY_TYPE_DOUBLE;
+
+ break;
+ }
+ case DBUS_TYPE_BOOLEAN:
+ {
+ double v;
+
+ dbus_message_iter_get_basic (var_iter, &v);
+
+ p->v.double_value = v;
+ p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
+
+ break;
+ }
+ default:
+ /** @todo report error */
+ break;
+ }
+
+ return TRUE;
+}
+
+/**
+ * libhal_device_get_all_properties:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique id of device
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Retrieve all the properties on a device.
+ *
+ * Returns: An object represent all properties. Must be freed with libhal_free_property_set().
+ */
+LibHalPropertySet *
+libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter reply_iter;
+ DBusMessageIter dict_iter;
+ LibHalPropertySet *result;
+ LibHalProperty *p_last;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetAllProperties");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ fprintf (stderr,
+ "%s %d : %s\n",
+ __FILE__, __LINE__, error->message);
+
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ result = malloc (sizeof (LibHalPropertySet));
+ if (result == NULL)
+ goto oom;
+/*
+ result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
+ if( result->properties==NULL )
+ {
+ /// @todo cleanup
+ return NULL;
+ }
+*/
+
+ result->properties_head = NULL;
+ result->num_properties = 0;
+
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY &&
+ dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
+ fprintf (stderr, "%s %d : error, expecting an array of dict entries\n",
+ __FILE__, __LINE__);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return NULL;
+ }
+
+ dbus_message_iter_recurse (&reply_iter, &dict_iter);
+
+ p_last = NULL;
+
+ while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
+ {
+ DBusMessageIter dict_entry_iter, var_iter;
+ const char *key;
+ LibHalProperty *p;
+
+ dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
+
+ dbus_message_iter_get_basic (&dict_entry_iter, &key);
+
+ p = malloc (sizeof (LibHalProperty));
+ if (p == NULL)
+ goto oom;
+
+ p->next = NULL;
+
+ if (result->num_properties == 0)
+ result->properties_head = p;
+
+ if (p_last != NULL)
+ p_last->next = p;
+
+ p_last = p;
+
+ p->key = strdup (key);
+ if (p->key == NULL)
+ goto oom;
+
+ dbus_message_iter_next (&dict_entry_iter);
+
+ dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
+
+
+ p->type = dbus_message_iter_get_arg_type (&var_iter);
+
+ result->num_properties++;
+
+ if(!libhal_property_fill_value_from_variant (p, &var_iter))
+ goto oom;
+
+ dbus_message_iter_next (&dict_iter);
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ return result;
+
+oom:
+ fprintf (stderr,
+ "%s %d : error allocating memory\n",
+ __FILE__, __LINE__);
+ /** @todo FIXME cleanup */
+ return NULL;
+}
+
+/**
+ * libhal_free_property_set:
+ * @set: property-set to free
+ *
+ * Free a property set earlier obtained with libhal_device_get_all_properties().
+ */
+void
+libhal_free_property_set (LibHalPropertySet * set)
+{
+ LibHalProperty *p;
+ LibHalProperty *q;
+
+ if (set == NULL)
+ return;
+
+ for (p = set->properties_head; p != NULL; p = q) {
+ free (p->key);
+ if (p->type == DBUS_TYPE_STRING)
+ free (p->v.str_value);
+ if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
+ libhal_free_string_array (p->v.strlist_value);
+ q = p->next;
+ free (p);
+ }
+ free (set);
+}
+
+/**
+ * libhal_property_set_get_num_elems:
+ * @set: property set to consider
+ *
+ * Get the number of properties in a property set.
+ *
+ * Returns: number of properties in given property set
+ */
+unsigned int
+libhal_property_set_get_num_elems (LibHalPropertySet *set)
+{
+ unsigned int num_elems;
+ LibHalProperty *p;
+
+ if (set == NULL)
+ return 0;
+
+ num_elems = 0;
+ for (p = set->properties_head; p != NULL; p = p->next)
+ num_elems++;
+
+ return num_elems;
+}
+
+
+/**
+ * libhal_psi_init:
+ * @iter: iterator object
+ * @set: property set to iterate over
+ *
+ * Initialize a property set iterator.
+ *
+ */
+void
+libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
+{
+ if (set == NULL)
+ return;
+
+ iter->set = set;
+ iter->idx = 0;
+ iter->cur_prop = set->properties_head;
+}
+
+
+/**
+ * libhal_psi_has_more:
+ * @iter: iterator object
+ *
+ * Determine whether there are more properties to iterate over.
+ *
+ * Returns: TRUE if there are more properties, FALSE otherwise.
+ */
+dbus_bool_t
+libhal_psi_has_more (LibHalPropertySetIterator * iter)
+{
+ return iter->idx < iter->set->num_properties;
+}
+
+/**
+ * libhal_psi_next:
+ * @iter: iterator object
+ *
+ * Advance iterator to next property.
+ */
+void
+libhal_psi_next (LibHalPropertySetIterator * iter)
+{
+ iter->idx++;
+ iter->cur_prop = iter->cur_prop->next;
+}
+
+/**
+ * libhal_psi_get_type:
+ * @iter: iterator object
+ *
+ * Get type of property.
+ *
+ * Returns: the property type at the iterator's position
+ */
+LibHalPropertyType
+libhal_psi_get_type (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->type;
+}
+
+/**
+ * libhal_psi_get_key:
+ * @iter: iterator object
+ *
+ * Get the key of a property.
+ *
+ * Returns: ASCII nul-terminated string. This pointer is only valid
+ * until libhal_free_property_set() is invoked on the property set
+ * this property belongs to.
+ */
+char *
+libhal_psi_get_key (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->key;
+}
+
+/**
+ * libhal_psi_get_string:
+ * @iter: iterator object
+ *
+ * Get the value of a property of type string.
+ *
+ * Returns: UTF8 nul-terminated string. This pointer is only valid
+ * until libhal_free_property_set() is invoked on the property set
+ * this property belongs to.
+ */
+char *
+libhal_psi_get_string (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->v.str_value;
+}
+
+/**
+ * libhal_psi_get_int:
+ * @iter: iterator object
+ *
+ * Get the value of a property of type signed integer.
+ *
+ * Returns: property value (32-bit signed integer)
+ */
+dbus_int32_t
+libhal_psi_get_int (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->v.int_value;
+}
+
+/**
+ * libhal_psi_get_uint64:
+ * @iter: iterator object
+ *
+ * Get the value of a property of type unsigned integer.
+ *
+ * Returns: property value (64-bit unsigned integer)
+ */
+dbus_uint64_t
+libhal_psi_get_uint64 (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->v.uint64_value;
+}
+
+/**
+ * libhal_psi_get_double:
+ * @iter: iterator object
+ *
+ * Get the value of a property of type double.
+ *
+ * Returns: property value (IEEE754 double precision float)
+ */
+double
+libhal_psi_get_double (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->v.double_value;
+}
+
+/**
+ * libhal_psi_get_bool:
+ * @iter: iterator object
+ *
+ * Get the value of a property of type bool.
+ *
+ * Returns: property value (bool)
+ */
+dbus_bool_t
+libhal_psi_get_bool (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->v.bool_value;
+}
+
+/**
+ * libhal_psi_get_strlist:
+ * @iter: iterator object
+ *
+ * Get the value of a property of type string list.
+ *
+ * Returns: pointer to array of strings
+ */
+char **
+libhal_psi_get_strlist (LibHalPropertySetIterator * iter)
+{
+ return iter->cur_prop->v.strlist_value;
+}
+
+
+static DBusHandlerResult
+filter_func (DBusConnection * connection,
+ DBusMessage * message, void *user_data)
+{
+ const char *object_path;
+ DBusError error;
+ LibHalContext *ctx = (LibHalContext *) user_data;
+
+ if (ctx->is_shutdown)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ dbus_error_init (&error);
+
+ object_path = dbus_message_get_path (message);
+
+ /*printf("*** in filter_func, object_path=%s\n", object_path);*/
+
+ if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
+ "DeviceAdded")) {
+ char *udi;
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_INVALID)) {
+ if (ctx->device_added != NULL) {
+ ctx->device_added (ctx, udi);
+ }
+ } else {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
+ char *udi;
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_INVALID)) {
+ if (ctx->device_removed != NULL) {
+ ctx->device_removed (ctx, udi);
+ }
+ } else {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) {
+ char *udi;
+ char *capability;
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &udi,
+ DBUS_TYPE_STRING, &capability,
+ DBUS_TYPE_INVALID)) {
+ if (ctx->device_new_capability != NULL) {
+ ctx->device_new_capability (ctx, udi, capability);
+ }
+ } else {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) {
+ char *condition_name;
+ char *condition_detail;
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &condition_name,
+ DBUS_TYPE_STRING, &condition_detail,
+ DBUS_TYPE_INVALID)) {
+ if (ctx->device_condition != NULL) {
+ ctx->device_condition (ctx, object_path, condition_name, condition_detail);
+ }
+ } else {
+ LIBHAL_FREE_DBUS_ERROR(&error);
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) {
+ if (ctx->device_property_modified != NULL) {
+ int i;
+ char *key;
+ dbus_bool_t removed;
+ dbus_bool_t added;
+ int num_modifications;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+
+ dbus_message_iter_init (message, &iter);
+ dbus_message_iter_get_basic (&iter, &num_modifications);
+ dbus_message_iter_next (&iter);
+
+ dbus_message_iter_recurse (&iter, &iter_array);
+
+ for (i = 0; i < num_modifications; i++) {
+ DBusMessageIter iter_struct;
+
+ dbus_message_iter_recurse (&iter_array, &iter_struct);
+
+ dbus_message_iter_get_basic (&iter_struct, &key);
+ dbus_message_iter_next (&iter_struct);
+ dbus_message_iter_get_basic (&iter_struct, &removed);
+ dbus_message_iter_next (&iter_struct);
+ dbus_message_iter_get_basic (&iter_struct, &added);
+
+ ctx->device_property_modified (ctx,
+ object_path,
+ key, removed,
+ added);
+
+ dbus_message_iter_next (&iter_array);
+ }
+
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+/* for i18n purposes */
+static dbus_bool_t libhal_already_initialized_once = FALSE;
+
+
+/**
+ * libhal_get_all_devices:
+ * @ctx: the context for the connection to hald
+ * @num_devices: the number of devices will be stored here
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get all devices in the Global Device List (GDL).
+ *
+ * Returns: An array of device identifiers terminated with NULL. It is
+ * the responsibility of the caller to free with
+ * libhal_free_string_array(). If an error occurs NULL is returned.
+ */
+char **
+libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter_array, reply_iter;
+ char **hal_device_names;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ *num_devices = 0;
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "GetAllDevices");
+ if (message == NULL) {
+ fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ /* now analyze reply */
+ dbus_message_iter_init (reply, &reply_iter);
+
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
+ fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_recurse (&reply_iter, &iter_array);
+
+ hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
+
+ dbus_message_unref (reply);
+ dbus_message_unref (message);
+
+ return hal_device_names;
+}
+
+/**
+ * libhal_device_get_property_type:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Query a property type of a device.
+ *
+ * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is
+ * return if the property doesn't exist.
+ */
+LibHalPropertyType
+libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ int type;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID); /* or return NULL? */
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyType");
+ if (message == NULL) {
+ fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
+ return LIBHAL_PROPERTY_TYPE_INVALID;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return LIBHAL_PROPERTY_TYPE_INVALID;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return LIBHAL_PROPERTY_TYPE_INVALID;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+ dbus_message_iter_get_basic (&reply_iter, &type);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ return type;
+}
+
+/**
+ * libhal_device_get_property_strlist:
+ * @ctx: the context for the connection to hald
+ * @udi: unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get the value of a property of type string list.
+ *
+ * Returns: Array of pointers to UTF8 nul-terminated strings
+ * terminated by NULL. The caller is responsible for freeing this
+ * string array with the function libhal_free_string_array(). Returns
+ * NULL if the property didn't exist or we are OOM
+ */
+char **
+libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_array, reply_iter;
+ char **our_strings;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyStringList");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ /* now analyse reply */
+ dbus_message_iter_init (reply, &reply_iter);
+
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
+ fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_recurse (&reply_iter, &iter_array);
+
+ our_strings = libhal_get_string_array_from_iter (&iter_array, NULL);
+
+ dbus_message_unref (reply);
+ dbus_message_unref (message);
+
+ return our_strings;
+}
+
+/**
+ * libhal_device_get_property_string:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: the name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get the value of a property of type string.
+ *
+ * Returns: UTF8 nul-terminated string. The caller is responsible for
+ * freeing this string with the function libhal_free_string(). Returns
+ * NULL if the property didn't exist or we are OOM.
+ */
+char *
+libhal_device_get_property_string (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ char *value;
+ char *dbus_str;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyString");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_STRING) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return NULL;
+ }
+
+ dbus_message_iter_get_basic (&reply_iter, &dbus_str);
+ value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
+ if (value == NULL) {
+ fprintf (stderr, "%s %d : error allocating memory\n",
+ __FILE__, __LINE__);
+ /** @todo FIXME cleanup */
+ return NULL;
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+/**
+ * libhal_device_get_property_int:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get the value of a property of type integer.
+ *
+ * Returns: Property value (32-bit signed integer)
+ */
+dbus_int32_t
+libhal_device_get_property_int (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ dbus_int32_t value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyInteger");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return -1;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return -1;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return -1;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_INT32) {
+ fprintf (stderr,
+ "%s %d : property '%s' for device '%s' is not "
+ "of type integer\n", __FILE__, __LINE__, key,
+ udi);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return -1;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+/**
+ * libhal_device_get_property_uint64:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get the value of a property of type signed integer.
+ *
+ * Returns: Property value (64-bit unsigned integer)
+ */
+dbus_uint64_t
+libhal_device_get_property_uint64 (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ dbus_uint64_t value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyInteger");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return -1;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return -1;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return -1;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_UINT64) {
+ fprintf (stderr,
+ "%s %d : property '%s' for device '%s' is not "
+ "of type integer\n", __FILE__, __LINE__, key,
+ udi);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return -1;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+/**
+ * libhal_device_get_property_double:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get the value of a property of type double.
+ *
+ * Returns: Property value (IEEE754 double precision float)
+ */
+double
+libhal_device_get_property_double (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ double value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyDouble");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return -1.0f;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return -1.0f;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return -1.0f;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_DOUBLE) {
+ fprintf (stderr,
+ "%s %d : property '%s' for device '%s' is not "
+ "of type double\n", __FILE__, __LINE__, key, udi);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return -1.0f;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return (double) value;
+}
+
+/**
+ * libhal_device_get_property_bool:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Get the value of a property of type bool.
+ *
+ * Returns: Property value (boolean)
+ */
+dbus_bool_t
+libhal_device_get_property_bool (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ dbus_bool_t value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "GetPropertyBoolean");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_BOOLEAN) {
+ fprintf (stderr,
+ "%s %d : property '%s' for device '%s' is not "
+ "of type bool\n", __FILE__, __LINE__, key, udi);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+
+/* generic helper */
+static dbus_bool_t
+libhal_device_set_property_helper (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ int type,
+ const char *str_value,
+ dbus_int32_t int_value,
+ dbus_uint64_t uint64_value,
+ double double_value,
+ dbus_bool_t bool_value,
+ DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ char *method_name = NULL;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ /** @todo sanity check incoming params */
+ switch (type) {
+ case DBUS_TYPE_INVALID:
+ method_name = "RemoveProperty";
+ break;
+ case DBUS_TYPE_STRING:
+ method_name = "SetPropertyString";
+ break;
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT64:
+ method_name = "SetPropertyInteger";
+ break;
+ case DBUS_TYPE_DOUBLE:
+ method_name = "SetPropertyDouble";
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ method_name = "SetPropertyBoolean";
+ break;
+
+ default:
+ /* cannot happen; is not callable from outside this file */
+ break;
+ }
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ method_name);
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ switch (type) {
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value);
+ break;
+ case DBUS_TYPE_INT32:
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value);
+ break;
+ case DBUS_TYPE_UINT64:
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value);
+ break;
+ case DBUS_TYPE_DOUBLE:
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value);
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value);
+ break;
+ }
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ return TRUE;
+}
+
+/**
+ * libhal_device_set_property_string:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value of the property; a UTF8 string
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Set a property of type string.
+ *
+ * Returns: TRUE if the property was set, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_set_property_string (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error)
+{
+ return libhal_device_set_property_helper (ctx, udi, key,
+ DBUS_TYPE_STRING,
+ value, 0, 0, 0.0f, FALSE, error);
+}
+
+/**
+ * libhal_device_set_property_int:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Set a property of type signed integer.
+ *
+ * Returns: TRUE if the property was set, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_set_property_int (LibHalContext *ctx, const char *udi,
+ const char *key, dbus_int32_t value, DBusError *error)
+{
+ return libhal_device_set_property_helper (ctx, udi, key,
+ DBUS_TYPE_INT32,
+ NULL, value, 0, 0.0f, FALSE, error);
+}
+
+/**
+ * libhal_device_set_property_uint64:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Set a property of type unsigned integer.
+ *
+ * Returns: TRUE if the property was set, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
+ const char *key, dbus_uint64_t value, DBusError *error)
+{
+ return libhal_device_set_property_helper (ctx, udi, key,
+ DBUS_TYPE_UINT64,
+ NULL, 0, value, 0.0f, FALSE, error);
+}
+
+/**
+ * libhal_device_set_property_double:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Set a property of type double.
+ *
+ * Returns: TRUE if the property was set, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_set_property_double (LibHalContext *ctx, const char *udi,
+ const char *key, double value, DBusError *error)
+{
+ return libhal_device_set_property_helper (ctx, udi, key,
+ DBUS_TYPE_DOUBLE,
+ NULL, 0, 0, value, FALSE, error);
+}
+
+/**
+ * libhal_device_set_property_bool:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Set a property of type bool.
+ *
+ * Returns: TRUE if the property was set, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_set_property_bool (LibHalContext *ctx, const char *udi,
+ const char *key, dbus_bool_t value, DBusError *error)
+{
+ return libhal_device_set_property_helper (ctx, udi, key,
+ DBUS_TYPE_BOOLEAN,
+ NULL, 0, 0, 0.0f, value, error);
+}
+
+
+/**
+ * libhal_device_remove_property:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Remove a property.
+ *
+ * Returns: TRUE if the property was set, FALSE if the device didn't
+ * exist
+ */
+dbus_bool_t
+libhal_device_remove_property (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID,
+ /* DBUS_TYPE_INVALID means remove */
+ NULL, 0, 0, 0.0f, FALSE, error);
+}
+
+/**
+ * libhal_device_property_strlist_append:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value to append to property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Append to a property of type strlist.
+ *
+ * Returns: TRUE if the value was appended, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_property_strlist_append (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "StringListAppend");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * libhal_device_property_strlist_prepend:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: value to prepend to property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Prepend to a property of type strlist.
+ *
+ * Returns: TRUE if the value was prepended, FALSE if the device
+ * didn't exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_property_strlist_prepend (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "StringListPrepend");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * libhal_device_property_strlist_remove_index:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @idx: index of string to remove in the strlist
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Remove a specified string from a property of type strlist.
+ *
+ * Returns: TRUE if the string was removed, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_property_strlist_remove_index (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ unsigned int idx,
+ DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "StringListRemoveIndex");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &idx);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * libhal_device_property_strlist_remove:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property
+ * @value: the string to remove
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Remove a specified string from a property of type strlist.
+ *
+ * Returns: TRUE if the string was removed, FALSE if the device didn't
+ * exist or the property had a different type.
+ */
+dbus_bool_t
+libhal_device_property_strlist_remove (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "StringListRemove");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ * libhal_device_lock:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @reason_to_lock: a user-presentable reason why the device is locked.
+ * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Take an advisory lock on the device.
+ *
+ * Returns: TRUE if the lock was obtained, FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_lock (LibHalContext *ctx,
+ const char *udi,
+ const char *reason_to_lock,
+ char **reason_why_locked, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ if (reason_why_locked != NULL)
+ *reason_why_locked = NULL;
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "Lock");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock);
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ if (strcmp (error->name,
+ "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
+ if (reason_why_locked != NULL) {
+ *reason_why_locked =
+ dbus_malloc0 (strlen (error->message) + 1);
+ strcpy (*reason_why_locked, error->message);
+ }
+ }
+
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_unref (reply);
+
+ return TRUE;
+}
+
+/**
+ * libhal_device_unlock:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Release an advisory lock on the device.
+ *
+ * Returns: TRUE if the device was successfully unlocked,
+ * FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_unlock (LibHalContext *ctx,
+ const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "Unlock");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_unref (reply);
+
+ return TRUE;
+}
+
+
+/**
+ * libhal_new_device:
+ * @ctx: the context for the connection to hald
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Create a new device object which will be hidden from applications
+ * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method
+ * is called. Note that the program invoking this method needs to run
+ * with super user privileges.
+ *
+ * Returns: Temporary device unique id or NULL if there was a
+ * problem. This string must be freed by the caller.
+ */
+char *
+libhal_new_device (LibHalContext *ctx, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter reply_iter;
+ char *value;
+ char *dbus_str;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "NewDevice");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
+ fprintf (stderr,
+ "%s %d : expected a string in reply to NewDevice\n",
+ __FILE__, __LINE__);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return NULL;
+ }
+
+ dbus_message_iter_get_basic (&reply_iter, &dbus_str);
+ value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
+ if (value == NULL) {
+ fprintf (stderr, "%s %d : error allocating memory\n",
+ __FILE__, __LINE__);
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+
+/**
+ * libhal_device_commit_to_gdl:
+ * @ctx: the context for the connection to hald
+ * @temp_udi: the temporary unique device id as returned by libhal_new_device()
+ * @udi: the new unique device id.
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * When a hidden device has been built using the NewDevice method,
+ * ie. libhal_new_device(), and the org.freedesktop.Hal.Device
+ * interface this function will commit it to the global device list.
+ *
+ * This means that the device object will be visible to applications
+ * and the HAL daemon will possibly attempt to boot the device
+ * (depending on the property RequireEnable).
+ *
+ * Note that the program invoking this method needs to run with super
+ * user privileges.
+ *
+ * Returns: FALSE if the given unique device id is already in use.
+ */
+dbus_bool_t
+libhal_device_commit_to_gdl (LibHalContext *ctx,
+ const char *temp_udi, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "CommitToGdl");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return TRUE;
+}
+
+/**
+ * libhal_remove_device:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique device id.
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * This method can be invoked when a device is removed. The HAL daemon
+ * will shut down the device. Note that the device may still be in the
+ * device list if the Persistent property is set to true.
+ *
+ * Note that the program invoking this method needs to run with super
+ * user privileges.
+ *
+ * Returns: TRUE if the device was removed, FALSE otherwise
+ */
+dbus_bool_t
+libhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "Remove");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return TRUE;
+}
+
+/**
+ * libhal_device_exists:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique device id.
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Determine if a device exists.
+ *
+ * Returns: TRUE if the device exists
+ */
+dbus_bool_t
+libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ dbus_bool_t value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "DeviceExists");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyze reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
+ fprintf (stderr,
+ "%s %d : expected a bool in reply to DeviceExists\n",
+ __FILE__, __LINE__);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+/**
+ * libhal_device_property_exists:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique device id.
+ * @key: name of the property
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Determine if a property on a device exists.
+ *
+ * Returns: TRUE if the device exists, FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_property_exists (LibHalContext *ctx,
+ const char *udi, const char *key, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ dbus_bool_t value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "PropertyExists");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_iter_init (reply, &reply_iter);
+
+ /* now analyse reply */
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
+ fprintf (stderr, "%s %d : expected a bool in reply to "
+ "PropertyExists\n", __FILE__, __LINE__);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+/**
+ * libhal_merge_properties:
+ * @ctx: the context for the connection to hald
+ * @target_udi: the Unique device id of target device to merge to
+ * @source_udi: the Unique device id of device to merge from
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Merge properties from one device to another.
+ *
+ * Returns: TRUE if the properties were merged, FALSE otherwise
+ */
+dbus_bool_t
+libhal_merge_properties (LibHalContext *ctx,
+ const char *target_udi, const char *source_udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "MergeProperties");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi);
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return TRUE;
+}
+
+/**
+ * libhal_device_matches:
+ * @ctx: the context for the connection to hald
+ * @udi1: the Unique Device Id for device 1
+ * @udi2: the Unique Device Id for device 2
+ * @property_namespace: the namespace for set of devices, e.g. "usb"
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Check a set of properties for two devices matches.
+ *
+ * Checks that all properties where keys, starting with a given value
+ * (namespace), of the first device is in the second device and that
+ * they got the same value and type.
+ *
+ * Note that the other inclusion isn't tested, so there could be
+ * properties (from the given namespace) in the second device not
+ * present in the first device.
+ *
+ * Returns: TRUE if all properties starting with the given namespace
+ * parameter from one device is in the other and have the same value.
+ */
+dbus_bool_t
+libhal_device_matches (LibHalContext *ctx,
+ const char *udi1, const char *udi2,
+ const char *property_namespace, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, reply_iter;
+ dbus_bool_t value;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "DeviceMatches");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+ /* now analyse reply */
+ dbus_message_iter_init (reply, &reply_iter);
+
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
+ fprintf (stderr,
+ "%s %d : expected a bool in reply to DeviceMatches\n",
+ __FILE__, __LINE__);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+
+ dbus_message_iter_get_basic (&reply_iter, &value);
+
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return value;
+}
+
+/**
+ * libhal_device_print:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Print a device to stdout; useful for debugging.
+ *
+ * Returns: TRUE if device's information could be obtained, FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ int type;
+ char *key;
+ LibHalPropertySet *pset;
+ LibHalPropertySetIterator i;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ printf ("device_id = %s\n", udi);
+
+ if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL)
+ return FALSE;
+
+ for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i);
+ libhal_psi_next (&i)) {
+ type = libhal_psi_get_type (&i);
+ key = libhal_psi_get_key (&i);
+
+ switch (type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ printf (" %s = '%s' (string)\n", key,
+ libhal_psi_get_string (&i));
+ break;
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ printf (" %s = %d = 0x%x (int)\n", key,
+ libhal_psi_get_int (&i),
+ libhal_psi_get_int (&i));
+ break;
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ printf (" %s = %llu = 0x%llx (uint64)\n", key,
+ (long long unsigned int) libhal_psi_get_uint64 (&i),
+ (long long unsigned int) libhal_psi_get_uint64 (&i));
+ break;
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ printf (" %s = %s (bool)\n", key,
+ (libhal_psi_get_bool (&i) ? "true" :
+ "false"));
+ break;
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ printf (" %s = %g (double)\n", key,
+ libhal_psi_get_double (&i));
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ {
+ unsigned int j;
+ char **str_list;
+
+ str_list = libhal_psi_get_strlist (&i);
+ printf (" %s = [", key);
+ for (j = 0; str_list[j] != NULL; j++) {
+ printf ("'%s'", str_list[j]);
+ if (str_list[j+1] != NULL)
+ printf (", ");
+ }
+ printf ("] (string list)\n");
+
+ break;
+ }
+ default:
+ printf (" *** unknown type for key %s\n", key);
+ break;
+ }
+ }
+
+ libhal_free_property_set (pset);
+
+ return TRUE;
+}
+
+/**
+ * libhal_manager_find_device_string_match:
+ * @ctx: the context for the connection to hald
+ * @key: name of the property
+ * @value: the value to match
+ * @num_devices: pointer to store number of devices
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Find a device in the GDL where a single string property matches a
+ * given value.
+ *
+ * Returns: UDI of devices; free with libhal_free_string_array()
+ */
+char **
+libhal_manager_find_device_string_match (LibHalContext *ctx,
+ const char *key,
+ const char *value, int *num_devices, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_array, reply_iter;
+ char **hal_device_names;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "FindDeviceStringMatch");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ /* now analyse reply */
+ dbus_message_iter_init (reply, &reply_iter);
+
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
+ fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_recurse (&reply_iter, &iter_array);
+
+ hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
+
+ dbus_message_unref (reply);
+ dbus_message_unref (message);
+
+ return hal_device_names;
+}
+
+
+/**
+ * libhal_device_add_capability:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @capability: the capability name to add
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Assign a capability to a device.
+ *
+ * Returns: TRUE if the capability was added, FALSE if the device didn't exist
+ */
+dbus_bool_t
+libhal_device_add_capability (LibHalContext *ctx,
+ const char *udi, const char *capability, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "AddCapability");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
+
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (reply);
+ dbus_message_unref (message);
+ return TRUE;
+}
+
+/**
+ * libhal_device_query_capability:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @capability: the capability name
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Check if a device has a capability. The result is undefined if the
+ * device doesn't exist.
+ *
+ * Returns: TRUE if the device has the capability, otherwise FALSE
+ */
+dbus_bool_t
+libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error)
+{
+ char **caps;
+ unsigned int i;
+ dbus_bool_t ret;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ret = FALSE;
+
+ caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error);
+ if (caps != NULL) {
+ for (i = 0; caps[i] != NULL; i++) {
+ if (strcmp (caps[i], capability) == 0) {
+ ret = TRUE;
+ break;
+ }
+ }
+ libhal_free_string_array (caps);
+ }
+
+ return ret;
+}
+
+/**
+ * libhal_find_device_by_capability:
+ * @ctx: the context for the connection to hald
+ * @capability: the capability name
+ * @num_devices: pointer to store number of devices
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Find devices with a given capability.
+ *
+ * Returns: UDI of devices; free with libhal_free_string_array()
+ */
+char **
+libhal_find_device_by_capability (LibHalContext *ctx,
+ const char *capability, int *num_devices, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_array, reply_iter;
+ char **hal_device_names;
+ DBusError _error;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ "/org/freedesktop/Hal/Manager",
+ "org.freedesktop.Hal.Manager",
+ "FindDeviceByCapability");
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return NULL;
+ }
+ /* now analyse reply */
+ dbus_message_iter_init (reply, &reply_iter);
+
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
+ fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ dbus_message_iter_recurse (&reply_iter, &iter_array);
+
+ hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
+
+ dbus_message_unref (reply);
+ dbus_message_unref (message);
+
+ return hal_device_names;
+}
+
+/**
+ * libhal_device_property_watch_all:
+ * @ctx: the context for the connection to hald
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Watch all devices, ie. the device_property_changed callback is
+ * invoked when the properties on any device changes.
+ *
+ * Returns: TRUE only if the operation succeeded
+ */
+dbus_bool_t
+libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ dbus_bus_add_match (ctx->connection,
+ "type='signal',"
+ "interface='org.freedesktop.Hal.Device',"
+ "sender='org.freedesktop.Hal'", error);
+ if (dbus_error_is_set (error)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ * libhal_device_add_property_watch:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Add a watch on a device, so the device_property_changed callback is
+ * invoked when the properties on the given device changes.
+ *
+ * The application itself is responsible for deleting the watch, using
+ * libhal_device_remove_property_watch, if the device is removed.
+ *
+ * Returns: TRUE only if the operation succeeded
+ */
+dbus_bool_t
+libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ char buf[512];
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ snprintf (buf, 512,
+ "type='signal',"
+ "interface='org.freedesktop.Hal.Device',"
+ "sender='org.freedesktop.Hal'," "path=%s", udi);
+
+ dbus_bus_add_match (ctx->connection, buf, error);
+ if (dbus_error_is_set (error)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ * libhal_device_remove_property_watch:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Remove a watch on a device.
+ *
+ * Returns: TRUE only if the operation succeeded
+ */
+dbus_bool_t
+libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ char buf[512];
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ snprintf (buf, 512,
+ "type='signal',"
+ "interface='org.freedesktop.Hal.Device',"
+ "sender='org.freedesktop.Hal'," "path=%s", udi);
+
+ dbus_bus_remove_match (ctx->connection, buf, error);
+ if (dbus_error_is_set (error)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ * libhal_ctx_new:
+ *
+ * Create a new LibHalContext
+ *
+ * Returns: a new uninitialized LibHalContext object
+ */
+LibHalContext *
+libhal_ctx_new (void)
+{
+ LibHalContext *ctx;
+
+ if (!libhal_already_initialized_once) {
+ bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+ libhal_already_initialized_once = TRUE;
+ }
+
+ ctx = calloc (1, sizeof (LibHalContext));
+ if (ctx == NULL) {
+ fprintf (stderr,
+ "%s %d : Failed to allocate %d bytes\n",
+ __FILE__, __LINE__, sizeof (LibHalContext));
+ return NULL;
+ }
+
+ ctx->is_initialized = FALSE;
+ ctx->is_shutdown = FALSE;
+ ctx->connection = NULL;
+ ctx->is_direct = FALSE;
+
+ return ctx;
+}
+
+/**
+ * libhal_ctx_set_cache:
+ * @ctx: context to enable/disable cache for
+ * @use_cache: whether or not to use cache
+ *
+ * Enable or disable caching. Note: Caching is not actually
+ * implemented yet.
+ *
+ * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->cache_enabled = use_cache;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_dbus_connection:
+ * @ctx: context to set connection for
+ * @conn: DBus connection to use
+ *
+ * Set DBus connection to use to talk to hald.
+ *
+ * Returns: TRUE if connection was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ if (conn == NULL)
+ return FALSE;
+
+ ctx->connection = conn;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_get_dbus_connection:
+ * @ctx: context to get connection for
+ *
+ * Get DBus connection used for talking to hald.
+ *
+ * Returns: DBus connection to use or NULL
+ */
+DBusConnection *
+libhal_ctx_get_dbus_connection (LibHalContext *ctx)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ return ctx->connection;
+}
+
+
+/**
+ * libhal_ctx_init:
+ * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection)
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Initialize the connection to hald.
+ *
+ * Returns: TRUE if initialization succeeds, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_init (LibHalContext *ctx, DBusError *error)
+{
+ DBusError _error;
+ dbus_bool_t hald_exists;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ if (ctx->connection == NULL)
+ return FALSE;
+
+ dbus_error_init (&_error);
+ hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error);
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ return FALSE;
+ }
+
+ if (!hald_exists) {
+ return FALSE;
+ }
+
+
+ if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
+ return FALSE;
+ }
+
+ dbus_bus_add_match (ctx->connection,
+ "type='signal',"
+ "interface='org.freedesktop.Hal.Manager',"
+ "sender='org.freedesktop.Hal',"
+ "path='/org/freedesktop/Hal/Manager'", &_error);
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ return FALSE;
+ }
+ ctx->is_initialized = TRUE;
+ ctx->is_direct = FALSE;
+
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_init_direct:
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Create an already initialized connection to hald. This function should only be used by HAL helpers.
+ *
+ * Returns: A pointer to an already initialized LibHalContext
+ */
+LibHalContext *
+libhal_ctx_init_direct (DBusError *error)
+{
+ char *hald_addr;
+ LibHalContext *ctx;
+ DBusError _error;
+
+ ctx = libhal_ctx_new ();
+ if (ctx == NULL)
+ goto out;
+
+ if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
+ libhal_ctx_free (ctx);
+ ctx = NULL;
+ goto out;
+ }
+
+ dbus_error_init (&_error);
+ ctx->connection = dbus_connection_open (hald_addr, &_error);
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ libhal_ctx_free (ctx);
+ ctx = NULL;
+ goto out;
+ }
+
+ ctx->is_initialized = TRUE;
+ ctx->is_direct = TRUE;
+
+out:
+ return ctx;
+}
+
+/**
+ * libhal_ctx_shutdown:
+ * @ctx: the context for the connection to hald
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Shut down a connection to hald.
+ *
+ * Returns: TRUE if connection successfully shut down, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
+{
+ DBusError myerror;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ if (ctx->is_direct) {
+ /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */
+ /*dbus_connection_unref (ctx->connection);*/
+ } else {
+ dbus_error_init (&myerror);
+ dbus_bus_remove_match (ctx->connection,
+ "type='signal',"
+ "interface='org.freedesktop.Hal.Manager',"
+ "sender='org.freedesktop.Hal',"
+ "path='/org/freedesktop/Hal/Manager'", &myerror);
+ if (dbus_error_is_set (&myerror)) {
+ dbus_move_error (&myerror, error);
+ fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
+ __FILE__, __LINE__, error->message);
+ /** @todo clean up */
+ }
+
+ /* TODO: remove other matches */
+
+ dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
+ }
+
+ ctx->is_initialized = FALSE;
+
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_free:
+ * @ctx: pointer to a LibHalContext
+ *
+ * Free a LibHalContext resource.
+ *
+ * Returns: TRUE
+ */
+dbus_bool_t
+libhal_ctx_free (LibHalContext *ctx)
+{
+ free (ctx);
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_device_added:
+ * @ctx: the context for the connection to hald
+ * @callback: the function to call when a device is added
+ *
+ * Set the callback for when a device is added
+ *
+ * Returns: TRUE if callback was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->device_added = callback;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_device_removed:
+ * @ctx: the context for the connection to hald
+ * @callback: the function to call when a device is removed
+ *
+ * Set the callback for when a device is removed.
+ *
+ * Returns: TRUE if callback was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->device_removed = callback;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_device_new_capability:
+ * @ctx: the context for the connection to hald
+ * @callback: the function to call when a device gains a new capability
+ *
+ * Set the callback for when a device gains a new capability.
+ *
+ * Returns: TRUE if callback was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->device_new_capability = callback;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_device_lost_capability:
+ * @ctx: the context for the connection to hald
+ * @callback: the function to call when a device loses a capability
+ *
+ * Set the callback for when a device loses a capability
+ *
+ * Returns: TRUE if callback was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->device_lost_capability = callback;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_device_property_modified:
+ * @ctx: the context for the connection to hald
+ * @callback: the function to call when a property is modified on a device
+ *
+ * Set the callback for when a property is modified on a device.
+ *
+ * Returns: TRUE if callback was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->device_property_modified = callback;
+ return TRUE;
+}
+
+/**
+ * libhal_ctx_set_device_condition:
+ * @ctx: the context for the connection to hald
+ * @callback: the function to call when a device emits a condition
+ *
+ * Set the callback for when a device emits a condition
+ *
+ * Returns: TRUE if callback was successfully set, FALSE otherwise
+ */
+dbus_bool_t
+libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
+{
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ ctx->device_condition = callback;
+ return TRUE;
+}
+
+/**
+ * libhal_string_array_length:
+ * @str_array: array of strings to consider
+ *
+ * Get the length of an array of strings.
+ *
+ * Returns: Number of strings in array
+ */
+unsigned int
+libhal_string_array_length (char **str_array)
+{
+ unsigned int i;
+
+ if (str_array == NULL)
+ return 0;
+
+ for (i = 0; str_array[i] != NULL; i++)
+ ;
+
+ return i;
+}
+
+
+/**
+ * libhal_device_rescan:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique id of device
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * TODO document me.
+ *
+ * Returns: Whether the operation succeeded
+ */
+dbus_bool_t
+libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter reply_iter;
+ DBusMessage *reply;
+ dbus_bool_t result;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
+ "org.freedesktop.Hal.Device",
+ "Rescan");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_iter_init (reply, &reply_iter);
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_BOOLEAN) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &result);
+
+ dbus_message_unref (reply);
+
+ return result;
+}
+
+/**
+ * libhal_device_reprobe:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique id of device
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * TODO document me.
+ *
+ * Returns: Whether the operation succeeded
+ */
+dbus_bool_t
+libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter reply_iter;
+ DBusMessage *reply;
+ dbus_bool_t result;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "Reprobe");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_iter_init (reply, &reply_iter);
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_BOOLEAN) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &result);
+
+ dbus_message_unref (reply);
+
+ return result;
+}
+
+/**
+ * libhal_device_emit_condition:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @condition_name: user-readable name of condition
+ * @condition_details: user-readable details of condition
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Emit a condition from a device. Can only be used from hald helpers.
+ *
+ * Returns: TRUE if condition successfully emitted,
+ * FALSE otherwise
+ */
+dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
+ const char *udi,
+ const char *condition_name,
+ const char *condition_details,
+ DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessageIter reply_iter;
+ DBusMessage *reply;
+ dbus_bool_t result;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "EmitCondition");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_iter_init (reply, &reply_iter);
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_BOOLEAN) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &result);
+
+ dbus_message_unref (reply);
+
+ return result;
+}
+
+/**
+ * libhal_device_addon_is_ready:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * HAL addon's must call this method when they are done initializing the device object. The HAL
+ * daemon will wait for all addon's to call this.
+ *
+ * Can only be used from hald helpers.
+ *
+ * Returns: TRUE if the HAL daemon received the message, FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessageIter reply_iter;
+ DBusMessage *reply;
+ dbus_bool_t result;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "AddonIsReady");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_iter_init (reply, &reply_iter);
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &result);
+
+ dbus_message_unref (reply);
+ return result;
+}
+
+/**
+ * libhal_device_claim_interface:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing
+ * @introspection_xml: Introspection XML containing what would be inside the interface XML tag
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Claim an interface for a device. All messages to this interface
+ * will be forwarded to the helper. Can only be used from hald
+ * helpers.
+ *
+ * Returns: TRUE if interface was claimed, FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_claim_interface (LibHalContext *ctx,
+ const char *udi,
+ const char *interface_name,
+ const char *introspection_xml,
+ DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessageIter reply_iter;
+ DBusMessage *reply;
+ dbus_bool_t result;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "ClaimInterface");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &introspection_xml);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_iter_init (reply, &reply_iter);
+ if (dbus_message_iter_get_arg_type (&reply_iter) !=
+ DBUS_TYPE_BOOLEAN) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &result);
+
+ dbus_message_unref (reply);
+
+ return result;
+}
+
+
+
+struct LibHalChangeSetElement_s;
+
+typedef struct LibHalChangeSetElement_s LibHalChangeSetElement;
+
+struct LibHalChangeSetElement_s {
+ char *key;
+ int change_type;
+ union {
+ char *val_str;
+ dbus_int32_t val_int;
+ dbus_uint64_t val_uint64;
+ double val_double;
+ dbus_bool_t val_bool;
+ char **val_strlist;
+ } value;
+ LibHalChangeSetElement *next;
+ LibHalChangeSetElement *prev;
+};
+
+struct LibHalChangeSet_s {
+ char *udi;
+ LibHalChangeSetElement *head;
+ LibHalChangeSetElement *tail;
+};
+
+/**
+ * libhal_device_new_changeset:
+ * @udi: unique device identifier
+ *
+ * Request a new changeset object. Used for changing multiple properties at once. Useful when
+ * performance is critical and also for atomically updating several properties.
+ *
+ * Returns: A new changeset object or NULL on error
+ */
+LibHalChangeSet *
+libhal_device_new_changeset (const char *udi)
+{
+ LibHalChangeSet *changeset;
+
+ changeset = calloc (1, sizeof (LibHalChangeSet));
+ if (changeset == NULL)
+ goto out;
+
+ changeset->udi = strdup (udi);
+ if (changeset->udi == NULL) {
+ free (changeset);
+ changeset = NULL;
+ goto out;
+ }
+
+ changeset->head = NULL;
+ changeset->tail = NULL;
+
+out:
+ return changeset;
+}
+
+static void
+libhal_changeset_append (LibHalChangeSet *changeset, LibHalChangeSetElement *elem)
+{
+ if (changeset->head == NULL) {
+ changeset->head = elem;
+ changeset->tail = elem;
+ elem->next = NULL;
+ elem->prev = NULL;
+ } else {
+ elem->prev = changeset->tail;
+ elem->next = NULL;
+ elem->prev->next = elem;
+ changeset->tail = elem;
+ }
+}
+
+
+/**
+ * libhal_device_set_property_string:
+ * @changeset: the changeset
+ * @key: key of property
+ * @value: the value to set
+ *
+ * Set a property.
+ *
+ * Returns: FALSE on OOM
+ */
+dbus_bool_t
+libhal_changeset_set_property_string (LibHalChangeSet *changeset, const char *key, const char *value)
+{
+ LibHalChangeSetElement *elem;
+
+ elem = calloc (1, sizeof (LibHalChangeSetElement));
+ if (elem == NULL)
+ goto out;
+ elem->key = strdup (key);
+ if (elem->key == NULL) {
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ elem->change_type = LIBHAL_PROPERTY_TYPE_STRING;
+ elem->value.val_str = strdup (value);
+ if (elem->value.val_str == NULL) {
+ free (elem->key);
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ libhal_changeset_append (changeset, elem);
+out:
+ return elem != NULL;
+}
+
+/**
+ * libhal_device_set_property_int:
+ * @changeset: the changeset
+ * @key: key of property
+ * @value: the value to set
+ *
+ * Set a property.
+ *
+ * Returns: FALSE on OOM
+ */
+dbus_bool_t
+libhal_changeset_set_property_int (LibHalChangeSet *changeset, const char *key, dbus_int32_t value)
+{
+ LibHalChangeSetElement *elem;
+
+ elem = calloc (1, sizeof (LibHalChangeSetElement));
+ if (elem == NULL)
+ goto out;
+ elem->key = strdup (key);
+ if (elem->key == NULL) {
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ elem->change_type = LIBHAL_PROPERTY_TYPE_INT32;
+ elem->value.val_int = value;
+
+ libhal_changeset_append (changeset, elem);
+out:
+ return elem != NULL;
+}
+
+/**
+ * libhal_device_set_property_uint64:
+ * @changeset: the changeset
+ * @key: key of property
+ * @value: the value to set
+ *
+ * Set a property.
+ *
+ * Returns: FALSE on OOM
+ */
+dbus_bool_t
+libhal_changeset_set_property_uint64 (LibHalChangeSet *changeset, const char *key, dbus_uint64_t value)
+{
+ LibHalChangeSetElement *elem;
+
+ elem = calloc (1, sizeof (LibHalChangeSetElement));
+ if (elem == NULL)
+ goto out;
+ elem->key = strdup (key);
+ if (elem->key == NULL) {
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ elem->change_type = LIBHAL_PROPERTY_TYPE_UINT64;
+ elem->value.val_uint64 = value;
+
+ libhal_changeset_append (changeset, elem);
+out:
+ return elem != NULL;
+}
+
+/**
+ * libhal_device_set_property_double:
+ * @changeset: the changeset
+ * @key: key of property
+ * @value: the value to set
+ *
+ * Set a property.
+ *
+ * Returns: FALSE on OOM
+ */
+dbus_bool_t
+libhal_changeset_set_property_double (LibHalChangeSet *changeset, const char *key, double value)
+{
+ LibHalChangeSetElement *elem;
+
+ elem = calloc (1, sizeof (LibHalChangeSetElement));
+ if (elem == NULL)
+ goto out;
+ elem->key = strdup (key);
+ if (elem->key == NULL) {
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ elem->change_type = LIBHAL_PROPERTY_TYPE_DOUBLE;
+ elem->value.val_double = value;
+
+ libhal_changeset_append (changeset, elem);
+out:
+ return elem != NULL;
+}
+
+/**
+ * libhal_device_set_property_bool:
+ * @changeset: the changeset
+ * @key: key of property
+ * @value: the value to set
+ *
+ * Set a property.
+ *
+ * Returns: FALSE on OOM
+ */
+dbus_bool_t
+libhal_changeset_set_property_bool (LibHalChangeSet *changeset, const char *key, dbus_bool_t value)
+{
+ LibHalChangeSetElement *elem;
+
+ elem = calloc (1, sizeof (LibHalChangeSetElement));
+ if (elem == NULL)
+ goto out;
+ elem->key = strdup (key);
+ if (elem->key == NULL) {
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ elem->change_type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
+ elem->value.val_bool = value;
+
+ libhal_changeset_append (changeset, elem);
+out:
+ return elem != NULL;
+}
+
+/**
+ * libhal_device_set_property_strlist:
+ * @changeset: the changeset
+ * @key: key of property
+ * @value: the value to set - NULL terminated array of strings
+ *
+ * Set a property.
+ *
+ * Returns: FALSE on OOM
+ */
+dbus_bool_t
+libhal_changeset_set_property_strlist (LibHalChangeSet *changeset, const char *key, const char **value)
+{
+ LibHalChangeSetElement *elem;
+ char **value_copy;
+ int len;
+ int i, j;
+
+ elem = calloc (1, sizeof (LibHalChangeSetElement));
+ if (elem == NULL)
+ goto out;
+ elem->key = strdup (key);
+ if (elem->key == NULL) {
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ for (i = 0; value[i] != NULL; i++)
+ ;
+ len = i;
+
+ value_copy = calloc (len + 1, sizeof (char *));
+ if (value_copy == NULL) {
+ free (elem->key);
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+
+ for (i = 0; i < len; i++) {
+ value_copy[i] = strdup (value[i]);
+ if (value_copy[i] == NULL) {
+ for (j = 0; j < i; j++) {
+ free (value_copy[j]);
+ }
+ free (value_copy);
+ free (elem->key);
+ free (elem);
+ elem = NULL;
+ goto out;
+ }
+ }
+ value_copy[i] = NULL;
+
+ elem->change_type = LIBHAL_PROPERTY_TYPE_STRLIST;
+ elem->value.val_strlist = value_copy;
+
+ libhal_changeset_append (changeset, elem);
+out:
+ return elem != NULL;
+}
+
+/**
+ * libhal_device_commit_changeset:
+ * @ctx: the context for the connection to hald
+ * @changeset: the changeset to commit
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * Commit a changeset to the daemon.
+ *
+ * Returns: True if the changeset was committed on the daemon side
+ */
+dbus_bool_t
+libhal_device_commit_changeset (LibHalContext *ctx, LibHalChangeSet *changeset, DBusError *error)
+{
+ LibHalChangeSetElement *elem;
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusError _error;
+ DBusMessageIter iter;
+ DBusMessageIter sub;
+ DBusMessageIter sub2;
+ DBusMessageIter sub3;
+ DBusMessageIter sub4;
+ int i;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ if (changeset->head == NULL) {
+ return TRUE;
+ }
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal", changeset->udi,
+ "org.freedesktop.Hal.Device",
+ "SetMultipleProperties");
+
+ if (message == NULL) {
+ fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+
+ dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &sub);
+
+ for (elem = changeset->head; elem != NULL; elem = elem->next) {
+ dbus_message_iter_open_container (&sub,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL,
+ &sub2);
+ dbus_message_iter_append_basic (&sub2, DBUS_TYPE_STRING, &(elem->key));
+
+ switch (elem->change_type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub3);
+ dbus_message_iter_append_basic (&sub3, DBUS_TYPE_STRING, &(elem->value.val_str));
+ dbus_message_iter_close_container (&sub2, &sub3);
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &sub3);
+ dbus_message_iter_open_container (&sub3, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &sub4);
+ for (i = 0; elem->value.val_strlist[i] != NULL; i++) {
+ dbus_message_iter_append_basic (&sub4, DBUS_TYPE_STRING,
+ &(elem->value.val_strlist[i]));
+ }
+ dbus_message_iter_close_container (&sub3, &sub4);
+ dbus_message_iter_close_container (&sub2, &sub3);
+ break;
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub3);
+ dbus_message_iter_append_basic (&sub3, DBUS_TYPE_INT32, &(elem->value.val_int));
+ dbus_message_iter_close_container (&sub2, &sub3);
+ break;
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT64_AS_STRING, &sub3);
+ dbus_message_iter_append_basic (&sub3, DBUS_TYPE_UINT64, &(elem->value.val_uint64));
+ dbus_message_iter_close_container (&sub2, &sub3);
+ break;
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub3);
+ dbus_message_iter_append_basic (&sub3, DBUS_TYPE_DOUBLE, &(elem->value.val_double));
+ dbus_message_iter_close_container (&sub2, &sub3);
+ break;
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING,&sub3);
+ dbus_message_iter_append_basic (&sub3, DBUS_TYPE_BOOLEAN, &(elem->value.val_bool));
+ dbus_message_iter_close_container (&sub2, &sub3);
+ break;
+ default:
+ fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type);
+ break;
+ }
+ dbus_message_iter_close_container (&sub, &sub2);
+ }
+
+ dbus_message_iter_close_container (&iter, &sub);
+
+
+ dbus_error_init (&_error);
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ &_error);
+
+ dbus_move_error (&_error, error);
+ if (error != NULL && dbus_error_is_set (error)) {
+ fprintf (stderr,
+ "%s %d : %s\n",
+ __FILE__, __LINE__, error->message);
+
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ if (reply == NULL) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * libhal_device_free_changeset:
+ * @changeset: the changeset to free
+ *
+ * Free a changeset.
+ */
+void
+libhal_device_free_changeset (LibHalChangeSet *changeset)
+{
+ LibHalChangeSetElement *elem;
+ LibHalChangeSetElement *elem2;
+
+ for (elem = changeset->head; elem != NULL; elem = elem2) {
+ elem2 = elem->next;
+
+ switch (elem->change_type) {
+ case LIBHAL_PROPERTY_TYPE_STRING:
+ free (elem->value.val_str);
+ break;
+ case LIBHAL_PROPERTY_TYPE_STRLIST:
+ libhal_free_string_array (elem->value.val_strlist);
+ break;
+ /* explicit fallthrough */
+ case LIBHAL_PROPERTY_TYPE_INT32:
+ case LIBHAL_PROPERTY_TYPE_UINT64:
+ case LIBHAL_PROPERTY_TYPE_DOUBLE:
+ case LIBHAL_PROPERTY_TYPE_BOOLEAN:
+ break;
+ default:
+ fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type);
+ break;
+ }
+ free (elem);
+ }
+
+ free (changeset->udi);
+ free (changeset);
+}
diff --git a/usr/src/lib/hal/libhal/common/libhal.h b/usr/src/lib/hal/libhal/common/libhal.h
new file mode 100644
index 0000000000..9962da1ec0
--- /dev/null
+++ b/usr/src/lib/hal/libhal/common/libhal.h
@@ -0,0 +1,604 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * libhal.h : HAL daemon C convenience library headers
+ *
+ * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LIBHAL_H
+#define LIBHAL_H
+
+#include <dbus/dbus.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#if 0
+} /* shut up emacs indenting */
+#endif
+#endif
+
+#if defined(__GNUC__)
+#define LIBHAL_DEPRECATED __attribute__ ((deprecated))
+#else
+#define LIBHAL_DEPRECATED
+#endif
+
+
+#define LIBHAL_FREE_DBUS_ERROR(_dbus_error_) \
+ do { \
+ if (dbus_error_is_set(_dbus_error_)) \
+ dbus_error_free (_dbus_error_); \
+ else \
+ fprintf (stderr, \
+ "%s %d : INFO: called LIBHAL_FREE_DBUS_ERROR " \
+ "but dbusError was not set.\n", \
+ __FILE__, __LINE__); \
+ } while (0)
+
+
+/**
+ * LIBHAL_CHECK_LIBHALCONTEXT:
+ * @_ctx_: the context
+ * @_ret_: what to use for return value if context is invalid
+ *
+ * Handy macro for checking whether a context is valid.
+ */
+#define LIBHAL_CHECK_LIBHALCONTEXT(_ctx_, _ret_) \
+ do { \
+ if (_ctx_ == NULL) { \
+ fprintf (stderr, \
+ "%s %d : LibHalContext *ctx is NULL\n", \
+ __FILE__, __LINE__); \
+ return _ret_; \
+ } \
+ } while(0)
+
+/**
+ * LibHalPropertyType:
+ *
+ * Possible types for properties on hal device objects
+ */
+typedef enum {
+ /** Used to report error condition */
+ LIBHAL_PROPERTY_TYPE_INVALID = DBUS_TYPE_INVALID,
+
+ /** Type for 32-bit signed integer property */
+ LIBHAL_PROPERTY_TYPE_INT32 = DBUS_TYPE_INT32,
+
+ /** Type for 64-bit unsigned integer property */
+ LIBHAL_PROPERTY_TYPE_UINT64 = DBUS_TYPE_UINT64,
+
+ /** Type for double precision floating point property */
+ LIBHAL_PROPERTY_TYPE_DOUBLE = DBUS_TYPE_DOUBLE,
+
+ /** Type for boolean property */
+ LIBHAL_PROPERTY_TYPE_BOOLEAN = DBUS_TYPE_BOOLEAN,
+
+ /** Type for UTF-8 string property */
+ LIBHAL_PROPERTY_TYPE_STRING = DBUS_TYPE_STRING,
+
+ /** Type for list of UTF-8 strings property */
+ LIBHAL_PROPERTY_TYPE_STRLIST = ((int) (DBUS_TYPE_STRING<<8)+('l'))
+} LibHalPropertyType;
+
+
+typedef struct LibHalContext_s LibHalContext;
+
+/**
+ * LibHalIntegrateDBusIntoMainLoop:
+ * @ctx: context for connection to hald
+ * @dbus_connection: DBus connection to use in ctx
+ *
+ * Type for function in application code that integrates a
+ * DBusConnection object into its own mainloop.
+ */
+typedef void (*LibHalIntegrateDBusIntoMainLoop) (LibHalContext *ctx,
+ DBusConnection *dbus_connection);
+
+/**
+ * LibHalDeviceAdded:
+ * @ctx: context for connection to hald
+ * @udi: the Unique Device Id
+ *
+ * Type for callback when a device is added.
+ */
+typedef void (*LibHalDeviceAdded) (LibHalContext *ctx,
+ const char *udi);
+
+/**
+ * LibHalDeviceRemoved:
+ * @ctx: context for connection to hald
+ * @udi: the Unique Device Id
+ *
+ * Type for callback when a device is removed.
+ */
+typedef void (*LibHalDeviceRemoved) (LibHalContext *ctx,
+ const char *udi);
+
+/**
+ * LibHalDeviceNewCapability:
+ * @ctx: context for connection to hald
+ * @udi: the Unique Device Id
+ * @capability: capability of the device
+ *
+ * Type for callback when a device gains a new capability.
+ *
+ */
+typedef void (*LibHalDeviceNewCapability) (LibHalContext *ctx,
+ const char *udi,
+ const char *capability);
+
+/**
+ * LibHalDeviceLostCapability:
+ * @ctx: context for connection to hald
+ * @udi: the Unique Device Id
+ * @capability: capability of the device
+ *
+ * Type for callback when a device loses a capability.
+ *
+ */
+typedef void (*LibHalDeviceLostCapability) (LibHalContext *ctx,
+ const char *udi,
+ const char *capability);
+
+/**
+ * LibHalDevicePropertyModified:
+ * @ctx: context for connection to hald
+ * @udi: the Unique Device Id
+ * @key: name of the property that has changed
+ * @is_removed: whether or not property was removed
+ * @is_added: whether or not property was added
+ *
+ * Type for callback when a property of a device changes.
+ */
+typedef void (*LibHalDevicePropertyModified) (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ dbus_bool_t is_removed,
+ dbus_bool_t is_added);
+
+/**
+ * LibHalDeviceCondition:
+ * @ctx: context for connection to hald
+ * @udi: the Unique Device Id
+ * @condition_name: name of the condition, e.g. ProcessorOverheating. Consult the HAL spec for details
+ * @condition_detail: detail of condition
+ *
+ * Type for callback when a non-continuous condition occurs on a device.
+ */
+typedef void (*LibHalDeviceCondition) (LibHalContext *ctx,
+ const char *udi,
+ const char *condition_name,
+ const char *condition_detail);
+
+
+/* Create a new context for a connection with hald */
+LibHalContext *libhal_ctx_new (void);
+
+/* Enable or disable caching */
+dbus_bool_t libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache);
+
+/* Set DBus connection to use to talk to hald. */
+dbus_bool_t libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn);
+
+/* Get DBus connection to use to talk to hald. */
+DBusConnection *libhal_ctx_get_dbus_connection (LibHalContext *ctx);
+
+/* Set user data for the context */
+dbus_bool_t libhal_ctx_set_user_data (LibHalContext *ctx, void *user_data);
+
+/* Get user data for the context */
+void* libhal_ctx_get_user_data (LibHalContext *ctx);
+
+/* Set the callback for when a device is added */
+dbus_bool_t libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback);
+
+/* Set the callback for when a device is removed */
+dbus_bool_t libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback);
+
+/* Set the callback for when a device gains a new capability */
+dbus_bool_t libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback);
+
+/* Set the callback for when a device loses a capability */
+dbus_bool_t libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback);
+
+/* Set the callback for when a property is modified on a device */
+dbus_bool_t libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback);
+
+/* Set the callback for when a device emits a condition */
+dbus_bool_t libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback);
+
+/* Initialize the connection to hald */
+dbus_bool_t libhal_ctx_init (LibHalContext *ctx, DBusError *error);
+
+/* Shut down a connection to hald */
+dbus_bool_t libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error);
+
+/* Free a LibHalContext resource */
+dbus_bool_t libhal_ctx_free (LibHalContext *ctx);
+
+/* Create an already initialized connection to hald */
+LibHalContext *libhal_ctx_init_direct (DBusError *error);
+
+/* Get all devices in the Global Device List (GDL). */
+char **libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error);
+
+/* Determine if a device exists. */
+dbus_bool_t libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error);
+
+/* Print a device to stdout; useful for debugging. */
+dbus_bool_t libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error);
+
+/* Determine if a property on a device exists. */
+dbus_bool_t libhal_device_property_exists (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Get the value of a property of type string. */
+char *libhal_device_get_property_string (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Get the value of a property of type signed integer. */
+dbus_int32_t libhal_device_get_property_int (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Get the value of a property of type unsigned integer. */
+dbus_uint64_t libhal_device_get_property_uint64 (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Get the value of a property of type double. */
+double libhal_device_get_property_double (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Get the value of a property of type bool. */
+dbus_bool_t libhal_device_get_property_bool (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Get the value of a property of type string list. */
+char **libhal_device_get_property_strlist (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Set a property of type string. */
+dbus_bool_t libhal_device_set_property_string (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error);
+
+/* Set a property of type signed integer. */
+dbus_bool_t libhal_device_set_property_int (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ dbus_int32_t value,
+ DBusError *error);
+
+/* Set a property of type unsigned integer. */
+dbus_bool_t libhal_device_set_property_uint64 (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ dbus_uint64_t value,
+ DBusError *error);
+
+/* Set a property of type double. */
+dbus_bool_t libhal_device_set_property_double (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ double value,
+ DBusError *error);
+
+/* Set a property of type bool. */
+dbus_bool_t libhal_device_set_property_bool (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ dbus_bool_t value,
+ DBusError *error);
+
+/* Append to a property of type strlist. */
+dbus_bool_t libhal_device_property_strlist_append (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error);
+
+/* Prepend to a property of type strlist. */
+dbus_bool_t libhal_device_property_strlist_prepend (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error);
+
+/* Remove a specified string from a property of type strlist. */
+dbus_bool_t libhal_device_property_strlist_remove_index (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ unsigned int idx,
+ DBusError *error);
+
+/* Remove a specified string from a property of type strlist. */
+dbus_bool_t libhal_device_property_strlist_remove (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ const char *value,
+ DBusError *error);
+
+/* Remove a property. */
+dbus_bool_t libhal_device_remove_property (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+/* Query a property type of a device. */
+LibHalPropertyType libhal_device_get_property_type (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ DBusError *error);
+
+struct LibHalChangeSet_s;
+typedef struct LibHalChangeSet_s LibHalChangeSet;
+
+LibHalChangeSet *libhal_device_new_changeset (const char *udi);
+
+dbus_bool_t libhal_changeset_set_property_string (LibHalChangeSet *changeset,
+ const char *key,
+ const char *value);
+
+dbus_bool_t libhal_changeset_set_property_int (LibHalChangeSet *changeset,
+ const char *key,
+ dbus_int32_t value);
+
+dbus_bool_t libhal_changeset_set_property_uint64 (LibHalChangeSet *changeset,
+ const char *key,
+ dbus_uint64_t value);
+
+dbus_bool_t libhal_changeset_set_property_double (LibHalChangeSet *changeset,
+ const char *key,
+ double value);
+
+dbus_bool_t libhal_changeset_set_property_bool (LibHalChangeSet *changeset,
+ const char *key,
+ dbus_bool_t value);
+
+dbus_bool_t libhal_changeset_set_property_strlist (LibHalChangeSet *changeset,
+ const char *key,
+ const char **value);
+
+dbus_bool_t libhal_device_commit_changeset (LibHalContext *ctx,
+ LibHalChangeSet *changeset,
+ DBusError *error);
+
+void libhal_device_free_changeset (LibHalChangeSet *changeset);
+
+
+struct LibHalProperty_s;
+typedef struct LibHalProperty_s LibHalProperty;
+
+struct LibHalPropertySet_s;
+typedef struct LibHalPropertySet_s LibHalPropertySet;
+
+
+/* Retrieve all the properties on a device. */
+LibHalPropertySet *libhal_device_get_all_properties (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+/* Free a property set earlier obtained with libhal_device_get_all_properties(). */
+void libhal_free_property_set (LibHalPropertySet *set);
+
+/* Get the number of properties in a property set. */
+unsigned int libhal_property_set_get_num_elems (LibHalPropertySet *set);
+
+/**
+ * LibHalPropertySetIterator:
+ *
+ * Iterator for inspecting all properties. Do not access any members;
+ * use the libhal_psi_* family of functions instead.
+ */
+struct LibHalPropertySetIterator_s {
+ LibHalPropertySet *set; /**< Property set we are iterating over */
+ unsigned int idx; /**< Index into current element */
+ LibHalProperty *cur_prop; /**< Current property being visited */
+ void *reservered0; /**< Reserved for future use */
+ void *reservered1; /**< Reserved for future use */
+};
+
+
+typedef struct LibHalPropertySetIterator_s LibHalPropertySetIterator;
+
+/* Initialize a property set iterator. */
+void libhal_psi_init (LibHalPropertySetIterator *iter, LibHalPropertySet *set);
+
+/* Determine whether there are more properties to iterate over */
+dbus_bool_t libhal_psi_has_more (LibHalPropertySetIterator *iter);
+
+/* Advance iterator to next property. */
+void libhal_psi_next (LibHalPropertySetIterator *iter);
+
+/* Get type of property. */
+LibHalPropertyType libhal_psi_get_type (LibHalPropertySetIterator *iter);
+
+/* Get the key of a property. */
+char *libhal_psi_get_key (LibHalPropertySetIterator *iter);
+
+/* Get the value of a property of type string. */
+char *libhal_psi_get_string (LibHalPropertySetIterator *iter);
+
+/* Get the value of a property of type signed integer. */
+dbus_int32_t libhal_psi_get_int (LibHalPropertySetIterator *iter);
+
+/* Get the value of a property of type unsigned integer. */
+dbus_uint64_t libhal_psi_get_uint64 (LibHalPropertySetIterator *iter);
+
+/* Get the value of a property of type double. */
+double libhal_psi_get_double (LibHalPropertySetIterator *iter);
+
+/* Get the value of a property of type bool. */
+dbus_bool_t libhal_psi_get_bool (LibHalPropertySetIterator *iter);
+
+/* Get the value of a property of type string list. */
+char **libhal_psi_get_strlist (LibHalPropertySetIterator *iter);
+
+/* Get the length of an array of strings */
+unsigned int libhal_string_array_length (char **str_array);
+
+/* Frees a NULL-terminated array of strings. If passed NULL, does nothing. */
+void libhal_free_string_array (char **str_array);
+
+/* Frees a nul-terminated string */
+void libhal_free_string (char *str);
+
+/* Create a new device object which will be hidden from applications
+ * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method is called.
+ */
+char *libhal_new_device (LibHalContext *ctx, DBusError *error);
+
+/* When a hidden device has been built using the NewDevice method, ie.
+ * libhal_new_device(), and the org.freedesktop.Hal.Device interface
+ * this function will commit it to the global device list.
+ */
+dbus_bool_t libhal_device_commit_to_gdl (LibHalContext *ctx,
+ const char *temp_udi,
+ const char *udi,
+ DBusError *error);
+
+/* This method can be invoked when a device is removed. The HAL daemon
+ * will shut down the device. Note that the device may still be in the device
+ * list if the Persistent property is set to true.
+ */
+dbus_bool_t libhal_remove_device (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+/* Merge properties from one device to another. */
+dbus_bool_t libhal_merge_properties (LibHalContext *ctx,
+ const char *target_udi,
+ const char *source_udi,
+ DBusError *error);
+
+/* Check a set of properties for two devices matches. */
+dbus_bool_t libhal_device_matches (LibHalContext *ctx,
+ const char *udi1,
+ const char *udi2,
+ const char *property_namespace,
+ DBusError *error);
+
+/* Find a device in the GDL where a single string property matches a
+ * given value.
+ */
+char **libhal_manager_find_device_string_match (LibHalContext *ctx,
+ const char *key,
+ const char *value,
+ int *num_devices,
+ DBusError *error);
+
+/* Assign a capability to a device. */
+dbus_bool_t libhal_device_add_capability (LibHalContext *ctx,
+ const char *udi,
+ const char *capability,
+ DBusError *error);
+
+/* Check if a device has a capability. The result is undefined if the
+ * device doesn't exist.
+ */
+dbus_bool_t libhal_device_query_capability (LibHalContext *ctx,
+ const char *udi,
+ const char *capability,
+ DBusError *error);
+
+/* Find devices with a given capability. */
+char **libhal_find_device_by_capability (LibHalContext *ctx,
+ const char *capability,
+ int *num_devices,
+ DBusError *error);
+
+/* Watch all devices, ie. the device_property_changed callback is
+ * invoked when the properties on any device changes.
+ */
+dbus_bool_t libhal_device_property_watch_all (LibHalContext *ctx,
+ DBusError *error);
+
+/* Add a watch on a device, so the device_property_changed callback is
+ * invoked when the properties on the given device changes.
+ */
+dbus_bool_t libhal_device_add_property_watch (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+/* Remove a watch on a device */
+dbus_bool_t libhal_device_remove_property_watch (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+/* Take an advisory lock on the device. */
+dbus_bool_t libhal_device_lock (LibHalContext *ctx,
+ const char *udi,
+ const char *reason_to_lock,
+ char **reason_why_locked,
+ DBusError *error);
+
+/* Release an advisory lock on the device. */
+dbus_bool_t libhal_device_unlock (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+dbus_bool_t libhal_device_rescan (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+dbus_bool_t libhal_device_reprobe (LibHalContext *ctx,
+ const char *udi,
+ DBusError *error);
+
+/* Emit a condition from a device (for hald helpers only) */
+dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
+ const char *udi,
+ const char *condition_name,
+ const char *condition_details,
+ DBusError *error);
+
+/* Claim an interface for a device (for hald helpers only) */
+dbus_bool_t libhal_device_claim_interface (LibHalContext *ctx,
+ const char *udi,
+ const char *interface_name,
+ const char *introspection_xml,
+ DBusError *error);
+
+/* hald waits for all addons to call this function before announcing the addon (for hald helpers only) */
+dbus_bool_t libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* LIBHAL_H */
diff --git a/usr/src/lib/hal/libhal/common/llib-lhal b/usr/src/lib/hal/libhal/common/llib-lhal
new file mode 100644
index 0000000000..d89da6716b
--- /dev/null
+++ b/usr/src/lib/hal/libhal/common/llib-lhal
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <hal/libhal.h>
diff --git a/usr/src/lib/hal/libhal/common/mapfile-vers b/usr/src/lib/hal/libhal/common/mapfile-vers
new file mode 100644
index 0000000000..19177567bd
--- /dev/null
+++ b/usr/src/lib/hal/libhal/common/mapfile-vers
@@ -0,0 +1,119 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUNW_1.1 {
+ global:
+ libhal_ctx_new;
+ libhal_ctx_set_cache;
+ libhal_ctx_set_dbus_connection;
+ libhal_ctx_get_dbus_connection;
+ libhal_ctx_set_user_data;
+ libhal_ctx_get_user_data;
+ libhal_ctx_set_device_added;
+ libhal_ctx_set_device_removed;
+ libhal_ctx_set_device_new_capability;
+ libhal_ctx_set_device_lost_capability;
+ libhal_ctx_set_device_property_modified;
+ libhal_ctx_set_device_condition;
+ libhal_ctx_init;
+ libhal_ctx_shutdown;
+ libhal_ctx_free;
+ libhal_ctx_init_direct;
+ libhal_get_all_devices;
+ libhal_device_exists;
+ libhal_device_print;
+ libhal_device_property_exists;
+ libhal_device_get_property_string;
+ libhal_device_get_property_int;
+ libhal_device_get_property_uint64;
+ libhal_device_get_property_double;
+ libhal_device_get_property_bool;
+ libhal_device_get_property_strlist;
+ libhal_device_set_property_string;
+ libhal_device_set_property_int;
+ libhal_device_set_property_uint64;
+ libhal_device_set_property_double;
+ libhal_device_set_property_bool;
+ libhal_device_property_strlist_append;
+ libhal_device_property_strlist_prepend;
+ libhal_device_property_strlist_remove_index;
+ libhal_device_property_strlist_remove;
+ libhal_device_remove_property;
+ libhal_device_get_property_type;
+ libhal_device_new_changeset;
+ libhal_changeset_set_property_string;
+ libhal_changeset_set_property_int;
+ libhal_changeset_set_property_uint64;
+ libhal_changeset_set_property_double;
+ libhal_changeset_set_property_bool;
+ libhal_changeset_set_property_strlist;
+ libhal_device_commit_changeset;
+ libhal_device_free_changeset;
+ libhal_device_get_all_properties;
+ libhal_free_property_set;
+ libhal_property_set_get_num_elems;
+ libhal_psi_init;
+ libhal_psi_has_more;
+ libhal_psi_next;
+ libhal_psi_get_type;
+ libhal_psi_get_key;
+ libhal_psi_get_string;
+ libhal_psi_get_int;
+ libhal_psi_get_uint64;
+ libhal_psi_get_double;
+ libhal_psi_get_bool;
+ libhal_psi_get_strlist;
+ libhal_string_array_length;
+ libhal_free_string_array;
+ libhal_free_string;
+ libhal_new_device;
+ libhal_device_commit_to_gdl;
+ libhal_remove_device;
+ libhal_merge_properties;
+ libhal_device_matches;
+ libhal_manager_find_device_string_match;
+ libhal_device_add_capability;
+ libhal_device_query_capability;
+ libhal_find_device_by_capability;
+ libhal_device_property_watch_all;
+ libhal_device_add_property_watch;
+ libhal_device_remove_property_watch;
+ libhal_device_lock;
+ libhal_device_unlock;
+ libhal_device_rescan;
+ libhal_device_reprobe;
+ libhal_device_emit_condition;
+ libhal_device_claim_interface;
+ libhal_device_addon_is_ready;
+};
+
+SUNWprivate_1.1 {
+ global:
+ SUNWprivate_1.1;
+ local:
+ *;
+};
diff --git a/usr/src/lib/hal/libhal/i386/Makefile b/usr/src/lib/hal/libhal/i386/Makefile
new file mode 100644
index 0000000000..8643a8305f
--- /dev/null
+++ b/usr/src/lib/hal/libhal/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK)
diff --git a/usr/src/lib/hal/libhal/sparc/Makefile b/usr/src/lib/hal/libhal/sparc/Makefile
new file mode 100644
index 0000000000..8643a8305f
--- /dev/null
+++ b/usr/src/lib/hal/libhal/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK)
diff --git a/usr/src/lib/libbsm/audit_event.txt b/usr/src/lib/libbsm/audit_event.txt
index 9e383aa97f..da1ab9aabe 100644
--- a/usr/src/lib/libbsm/audit_event.txt
+++ b/usr/src/lib/libbsm/audit_event.txt
@@ -423,6 +423,11 @@
6227:AUE_zlogin:login - zlogin:lo
6228:AUE_su_logout:su logout:lo
6229:AUE_role_logout:role logout:lo
+6230:AUE_attach:attach device:ot
+6231:AUE_detach:detach device:ot
+6232:AUE_remove:remove/eject device:ot
+6233:AUE_pool_import:import device into pool:ot
+6234:AUE_pool_export:export device from pool:ot
#
# Trusted Extensions events:
#
diff --git a/usr/src/lib/libbsm/common/adt_event.h b/usr/src/lib/libbsm/common/adt_event.h
index 91ab333548..f55e446097 100644
--- a/usr/src/lib/libbsm/common/adt_event.h
+++ b/usr/src/lib/libbsm/common/adt_event.h
@@ -93,6 +93,8 @@ enum adt_login_text {
ADT_LOGIN_ANON_USER /* No anonymous */
};
#define ADT_admin_authenticate 3
+#define ADT_attach 42
+#define ADT_detach 43
#define ADT_filesystem_add 4
#define ADT_filesystem_delete 5
#define ADT_filesystem_modify 6
@@ -108,10 +110,13 @@ enum adt_login_text {
#define ADT_network_modify 9
#define ADT_newgrp_login 41
#define ADT_passwd 27
+#define ADT_pool_export 46
+#define ADT_pool_import 45
#define ADT_printer_add 10
#define ADT_printer_delete 11
#define ADT_printer_modify 12
#define ADT_prof_cmd 24
+#define ADT_remove 44
#define ADT_rlogin 28
#define ADT_role_login 13
#define ADT_role_logout 40
@@ -140,6 +145,22 @@ struct adt_admin_authenticate { /* ADT_admin_authenticate */
};
typedef struct adt_admin_authenticate adt_admin_authenticate_t;
+struct adt_attach { /* ADT_attach */
+ char *auth_used; /* required */
+ char *mount_point; /* required */
+ char *device; /* required */
+ char *options; /* optional */
+};
+typedef struct adt_attach adt_attach_t;
+
+struct adt_detach { /* ADT_detach */
+ char *auth_used; /* required */
+ char *mount_point; /* required */
+ char *device; /* required */
+ char *options; /* optional */
+};
+typedef struct adt_detach adt_detach_t;
+
struct adt_filesystem_add { /* ADT_filesystem_add */
char *object_name; /* required */
char *domain; /* optional */
@@ -248,6 +269,20 @@ struct adt_passwd { /* ADT_passwd */
};
typedef struct adt_passwd adt_passwd_t;
+struct adt_pool_export { /* ADT_pool_export */
+ char *auth_used; /* required */
+ char *pool; /* required */
+ char *device; /* required */
+};
+typedef struct adt_pool_export adt_pool_export_t;
+
+struct adt_pool_import { /* ADT_pool_import */
+ char *auth_used; /* required */
+ char *pool; /* required */
+ char *device; /* required */
+};
+typedef struct adt_pool_import adt_pool_import_t;
+
struct adt_printer_add { /* ADT_printer_add */
char *object_name; /* required */
char *domain; /* optional */
@@ -294,6 +329,13 @@ struct adt_prof_cmd { /* ADT_prof_cmd */
};
typedef struct adt_prof_cmd adt_prof_cmd_t;
+struct adt_remove { /* ADT_remove */
+ char *auth_used; /* required */
+ char *mount_point; /* optional */
+ char *device; /* required */
+};
+typedef struct adt_remove adt_remove_t;
+
struct adt_rlogin { /* ADT_rlogin */
enum adt_login_text message; /* optional */
};
@@ -439,6 +481,8 @@ typedef struct adt_zone_state adt_zone_state_t;
union adt_event_data {
adt_admin_authenticate_t adt_admin_authenticate;
+ adt_attach_t adt_attach;
+ adt_detach_t adt_detach;
adt_filesystem_add_t adt_filesystem_add;
adt_filesystem_delete_t adt_filesystem_delete;
adt_filesystem_modify_t adt_filesystem_modify;
@@ -454,10 +498,13 @@ union adt_event_data {
adt_network_modify_t adt_network_modify;
adt_newgrp_login_t adt_newgrp_login;
adt_passwd_t adt_passwd;
+ adt_pool_export_t adt_pool_export;
+ adt_pool_import_t adt_pool_import;
adt_printer_add_t adt_printer_add;
adt_printer_delete_t adt_printer_delete;
adt_printer_modify_t adt_printer_modify;
adt_prof_cmd_t adt_prof_cmd;
+ adt_remove_t adt_remove;
adt_rlogin_t adt_rlogin;
adt_role_login_t adt_role_login;
adt_role_logout_t adt_role_logout;
diff --git a/usr/src/lib/libbsm/common/adt_xlate.c b/usr/src/lib/libbsm/common/adt_xlate.c
index 452a102492..1da827d5f7 100644
--- a/usr/src/lib/libbsm/common/adt_xlate.c
+++ b/usr/src/lib/libbsm/common/adt_xlate.c
@@ -73,6 +73,50 @@ static struct translation X_admin_authenticate = {
&XX_admin_authenticate[0],
&XX_admin_authenticate[0]
};
+static struct entry XX_attach[6] = {
+ {AUT_SUBJECT, 1, NULL, &(XX_attach[1]),
+ 0, 0, 0, NULL},
+ {AUT_UAUTH, 1, &adr1[0], &(XX_attach[2]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_attach[3]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_attach[4]),
+ 0, 1, 0, NULL},
+ {AUT_TEXT, 1, &adr1[0], &(XX_attach[5]),
+ 0, 0, 0, NULL},
+ {AUT_RETURN, 1, NULL, NULL,
+ 0, 0, 0, NULL}
+};
+static struct translation X_attach = {
+ 0,
+ ADT_attach,
+ AUE_attach,
+ 6,
+ &XX_attach[0],
+ &XX_attach[0]
+};
+static struct entry XX_detach[6] = {
+ {AUT_SUBJECT, 1, NULL, &(XX_detach[1]),
+ 0, 0, 0, NULL},
+ {AUT_UAUTH, 1, &adr1[0], &(XX_detach[2]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_detach[3]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_detach[4]),
+ 0, 1, 0, NULL},
+ {AUT_TEXT, 1, &adr1[0], &(XX_detach[5]),
+ 0, 0, 0, NULL},
+ {AUT_RETURN, 1, NULL, NULL,
+ 0, 0, 0, NULL}
+};
+static struct translation X_detach = {
+ 0,
+ ADT_detach,
+ AUE_detach,
+ 6,
+ &XX_detach[0],
+ &XX_detach[0]
+};
static struct entry XX_filesystem_add[7] = {
{AUT_SUBJECT, 1, NULL, &(XX_filesystem_add[1]),
0, 0, 0, NULL},
@@ -373,6 +417,46 @@ static struct translation X_passwd = {
&XX_passwd[0],
&XX_passwd[0]
};
+static struct entry XX_pool_export[5] = {
+ {AUT_SUBJECT, 1, NULL, &(XX_pool_export[1]),
+ 0, 0, 0, NULL},
+ {AUT_UAUTH, 1, &adr1[0], &(XX_pool_export[2]),
+ 0, 1, 0, NULL},
+ {AUT_TEXT, 1, &adr1[0], &(XX_pool_export[3]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_pool_export[4]),
+ 0, 1, 0, NULL},
+ {AUT_RETURN, 1, NULL, NULL,
+ 0, 0, 0, NULL}
+};
+static struct translation X_pool_export = {
+ 0,
+ ADT_pool_export,
+ AUE_pool_export,
+ 5,
+ &XX_pool_export[0],
+ &XX_pool_export[0]
+};
+static struct entry XX_pool_import[5] = {
+ {AUT_SUBJECT, 1, NULL, &(XX_pool_import[1]),
+ 0, 0, 0, NULL},
+ {AUT_UAUTH, 1, &adr1[0], &(XX_pool_import[2]),
+ 0, 1, 0, NULL},
+ {AUT_TEXT, 1, &adr1[0], &(XX_pool_import[3]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_pool_import[4]),
+ 0, 1, 0, NULL},
+ {AUT_RETURN, 1, NULL, NULL,
+ 0, 0, 0, NULL}
+};
+static struct translation X_pool_import = {
+ 0,
+ ADT_pool_import,
+ AUE_pool_import,
+ 5,
+ &XX_pool_import[0],
+ &XX_pool_import[0]
+};
static struct entry XX_printer_add[7] = {
{AUT_SUBJECT, 1, NULL, &(XX_printer_add[1]),
0, 0, 0, NULL},
@@ -471,6 +555,26 @@ static struct translation X_prof_cmd = {
&XX_prof_cmd[0],
&XX_prof_cmd[0]
};
+static struct entry XX_remove[5] = {
+ {AUT_SUBJECT, 1, NULL, &(XX_remove[1]),
+ 0, 0, 0, NULL},
+ {AUT_UAUTH, 1, &adr1[0], &(XX_remove[2]),
+ 0, 1, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_remove[3]),
+ 0, 0, 0, NULL},
+ {AUT_PATH, 1, &adr1[0], &(XX_remove[4]),
+ 0, 1, 0, NULL},
+ {AUT_RETURN, 1, NULL, NULL,
+ 0, 0, 0, NULL}
+};
+static struct translation X_remove = {
+ 0,
+ ADT_remove,
+ AUE_remove,
+ 5,
+ &XX_remove[0],
+ &XX_remove[0]
+};
static struct entry XX_rlogin[3] = {
{AUT_SUBJECT, 1, NULL, &(XX_rlogin[1]),
0, 0, 0, NULL},
@@ -875,8 +979,10 @@ static struct translation X_zone_state = {
&XX_zone_state[0],
&XX_zone_state[0]
};
-struct translation *xlate_table[42] = {
+struct translation *xlate_table[47] = {
&X_admin_authenticate,
+ &X_attach,
+ &X_detach,
&X_filesystem_add,
&X_filesystem_delete,
&X_filesystem_modify,
@@ -892,10 +998,13 @@ struct translation *xlate_table[42] = {
&X_network_modify,
&X_newgrp_login,
&X_passwd,
+ &X_pool_export,
+ &X_pool_import,
&X_printer_add,
&X_printer_delete,
&X_printer_modify,
&X_prof_cmd,
+ &X_remove,
&X_rlogin,
&X_role_login,
&X_role_logout,
diff --git a/usr/src/lib/libbsm/common/adt_xml.txt b/usr/src/lib/libbsm/common/adt_xml.txt
index 8efee26724..222dfaf59c 100644
--- a/usr/src/lib/libbsm/common/adt_xml.txt
+++ b/usr/src/lib/libbsm/common/adt_xml.txt
@@ -737,8 +737,114 @@ Use is subject to license terms.
</entry>
</event>
+ <event id="AUE_generic_mountable" type="generic" omit="always">
+ <!--
+
+ User device mounting related functions
+
+ -->
+ <entry id="subject">
+ <internal token="subject"/>
+ <external opt="none"/>
+ </entry>
+ <entry id="auth_used">
+ <internal token="uauth"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="mount_point">
+ <internal token="path"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="device">
+ <internal token="path"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="options">
+ <internal token="text"/>
+ <external opt="optional" type="char *"/>
+ </entry>
+ <entry id="return">
+ <internal token="return"/>
+ <external opt="none"/>
+ </entry>
+ </event>
+
+ <event id="AUE_attach" instance_of="AUE_generic_mountable"
+ header="0" idNo="42" omit="JNI">
+ </event>
+ <event id="AUE_detach" instance_of="AUE_generic_mountable"
+ header="0" idNo="43" omit="JNI">
+ </event>
+ <event id="AUE_remove" header="0" idNo="44" omit="JNI">
+ <entry id="subject">
+ <internal token="subject"/>
+ <external opt="none"/>
+ </entry>
+ <entry id="auth_used">
+ <internal token="uauth"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="mount_point">
+ <internal token="path"/>
+ <external opt="optional" type="char *"/>
+ </entry>
+ <entry id="device">
+ <internal token="path"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="return">
+ <internal token="return"/>
+ <external opt="none"/>
+ </entry>
+ </event>
+
+ <event id="AUE_pool_import" header="0" idNo="45" omit="JNI">
+ <entry id="subject">
+ <internal token="subject"/>
+ <external opt="none"/>
+ </entry>
+ <entry id="auth_used">
+ <internal token="uauth"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="pool">
+ <internal token="text"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="device">
+ <internal token="path"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="return">
+ <internal token="return"/>
+ <external opt="none"/>
+ </entry>
+ </event>
+ <event id="AUE_pool_export" header="0" idNo="46" omit="JNI">
+ <entry id="subject">
+ <internal token="subject"/>
+ <external opt="none"/>
+ </entry>
+ <entry id="auth_used">
+ <internal token="uauth"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="pool">
+ <internal token="text"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="device">
+ <internal token="path"/>
+ <external opt="required" type="char *"/>
+ </entry>
+ <entry id="return">
+ <internal token="return"/>
+ <external opt="none"/>
+ </entry>
+ </event>
+
<!-- add new everts here with the next higher idNo -->
-<!-- Highest idNo is 41, so next is 42, then fix this comment -->
+<!-- Highest idNo is 46, so next is 47, then fix this comment -->
<!-- end of C Only events -->
diff --git a/usr/src/lib/libdevinfo/devinfo_devperm.c b/usr/src/lib/libdevinfo/devinfo_devperm.c
index 412eb74fc8..18e2409065 100644
--- a/usr/src/lib/libdevinfo/devinfo_devperm.c
+++ b/usr/src/lib/libdevinfo/devinfo_devperm.c
@@ -87,6 +87,7 @@ setdevaccess(char *dev, uid_t uid, gid_t gid, mode_t mode,
{
int err = 0, local_errno;
char errstring[MAX_LINELEN];
+ struct stat st;
if (chown(dev, uid, gid) == -1) {
if (errno == ENOENT) /* no such file */
@@ -95,17 +96,22 @@ setdevaccess(char *dev, uid_t uid, gid_t gid, mode_t mode,
local_errno = errno;
}
- while (fdetach(dev) == 0) {
- if (chown(dev, uid, gid) == -1) {
- err = -1;
- local_errno = errno;
+ /*
+ * don't fdetach block devices, as it will unmount them
+ */
+ if (!((stat(dev, &st) == 0) && ((st.st_mode & S_IFMT) == S_IFBLK))) {
+ while (fdetach(dev) == 0) {
+ if (chown(dev, uid, gid) == -1) {
+ err = -1;
+ local_errno = errno;
+ }
+ }
+ if (err && errmsg) {
+ (void) snprintf(errstring, MAX_LINELEN,
+ "failed to chown device %s: %s\n",
+ dev, strerror(local_errno));
+ (*errmsg)(errstring);
}
- }
- if (err && errmsg) {
- (void) snprintf(errstring, MAX_LINELEN,
- "failed to chown device %s: %s\n",
- dev, strerror(local_errno));
- (*errmsg)(errstring);
}
/*
diff --git a/usr/src/lib/libdiskmgt/Makefile.com b/usr/src/lib/libdiskmgt/Makefile.com
index 350c1248fd..735889cc8b 100644
--- a/usr/src/lib/libdiskmgt/Makefile.com
+++ b/usr/src/lib/libdiskmgt/Makefile.com
@@ -37,7 +37,7 @@ include ../../Makefile.lib
LIBS = $(DYNLIB) $(LINTLIB)
LDLIBS += -ldevinfo -ladm -ldevid -lkstat -lsysevent \
- -lvolmgt -lnvpair -lefi -lc
+ -lnvpair -lefi -lc
LDFLAGS += -R/opt/VRTSvxvm/lib
SRCDIR = ../common
diff --git a/usr/src/lib/libdiskmgt/common/disks_private.h b/usr/src/lib/libdiskmgt/common/disks_private.h
index 2d738dfcbf..0f782bc383 100644
--- a/usr/src/lib/libdiskmgt/common/disks_private.h
+++ b/usr/src/lib/libdiskmgt/common/disks_private.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -98,7 +97,6 @@ typedef struct disk {
char *device_id; /* string encoded device id */
ddi_devid_t devid; /* decoded device id */
char *kernel_name; /* handles drives w/ no devlinks */
- char *volm_path;
char *product_id;
char *vendor_id;
controller_t **controllers;
@@ -111,7 +109,6 @@ typedef struct disk {
int rpm;
int wide;
int cd_rom;
- int volm_path_set;
} disk_t;
typedef struct descriptor {
@@ -196,7 +193,6 @@ descriptor_t *media_get_descriptor_by_name(char *name, int *errp);
char *media_get_name(descriptor_t *desc);
nvlist_t *media_get_attributes(descriptor_t *desc, int *errp);
nvlist_t *media_get_stats(descriptor_t *desc, int stat_type, int *errp);
-int media_get_volm_path(disk_t *diskp, char *mediapath, int size);
int media_make_descriptors();
int media_read_info(int fd, struct dk_minfo *minfo);
int media_read_name(disk_t *dp, char *mname, int size);
diff --git a/usr/src/lib/libdiskmgt/common/drive.c b/usr/src/lib/libdiskmgt/common/drive.c
index b3f32c70d6..825348ce9f 100644
--- a/usr/src/lib/libdiskmgt/common/drive.c
+++ b/usr/src/lib/libdiskmgt/common/drive.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -626,99 +625,12 @@ drive_make_descriptors()
/*
* This function opens the disk generically (any slice).
- *
- * Opening the disk could fail because the disk is managed by the volume
- * manager. Handle this if that is the case. Note that the media APIs don't
- * always return a device. If the media has slices (e.g. a solaris install
- * CD-ROM) then media_findname(volname) returns a directory with per slice
- * devices underneath. We need to open one of those devices in this case.
*/
int
drive_open_disk(disk_t *diskp, char *opath, int len)
{
- char rmmedia_devpath[MAXPATHLEN];
-
- if (diskp->removable && media_get_volm_path(diskp, rmmedia_devpath,
- sizeof (rmmedia_devpath))) {
-
- int fd;
- struct stat buf;
-
- if (rmmedia_devpath[0] == 0) {
- /* removable but no media */
- return (-1);
- }
-
- if ((fd = open(rmmedia_devpath, O_RDONLY|O_NDELAY)) < 0) {
- return (-1);
- }
-
- if (fstat(fd, &buf) != 0) {
- (void) close(fd);
- return (-1);
- }
-
- if (S_ISCHR(buf.st_mode)) {
- /* opened, is device, so done */
- if (opath != NULL) {
- (void) strlcpy(opath, rmmedia_devpath, len);
- }
- return (fd);
-
- } else if (S_ISDIR(buf.st_mode)) {
- /* disk w/ slices so handle the directory */
- DIR *dirp;
- struct dirent *dentp;
- int dfd;
-
- /* each device file in the dir represents a slice */
-
- if ((dirp = fdopendir(fd)) == NULL) {
- (void) close(fd);
- return (-1);
- }
-
- while ((dentp = readdir(dirp)) != NULL) {
- char slice_path[MAXPATHLEN];
-
- if (libdiskmgt_str_eq(".", dentp->d_name) ||
- libdiskmgt_str_eq("..", dentp->d_name)) {
- continue;
- }
-
- (void) snprintf(slice_path, sizeof (slice_path), "%s/%s",
- rmmedia_devpath, dentp->d_name);
-
- if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) < 0) {
- continue;
- }
-
- if (fstat(dfd, &buf) == 0 && S_ISCHR(buf.st_mode)) {
- /* opened, is device, so done */
- (void) closedir(dirp);
- if (opath != NULL) {
- (void) strlcpy(opath, slice_path, len);
- }
- return (dfd);
- }
-
- /* not a device, keep looking */
- (void) close(dfd);
- }
-
- /* did not find a device under the rmmedia_path */
- (void) closedir(dirp);
- return (-1);
- }
-
- /* didn't find a device under volume management control */
- (void) close(fd);
- return (-1);
- }
-
/*
- * Not removable media under volume management control so just open the
- * first devpath.
+ * Just open the first devpath.
*/
if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) {
if (opath != NULL) {
diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c
index 5a5bd4fc15..42d57d428a 100644
--- a/usr/src/lib/libdiskmgt/common/findevs.c
+++ b/usr/src/lib/libdiskmgt/common/findevs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -977,15 +976,6 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args)
/* not a "CD-ROM" or Floppy */
diskp->removable = get_prop(REMOVABLE_PROP, args->node);
- if (diskp->removable == -1) {
- /*
- * This is a workaround. Hotpluggable devices don't export
- * a "removable-media" property, but they are treated as
- * removable media devices by vold to implement automount.
- * Once vold is EOL'ed, it should be removed.
- */
- diskp->removable = get_prop(HOTPLUGGABLE_PROP, args->node);
- }
if (diskp->removable == -1) {
diskp->removable = 0;
@@ -1026,8 +1016,6 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args)
diskp->drv_type = DM_DT_FIXED;
}
}
- diskp->volm_path_set = 0;
- diskp->volm_path = NULL;
diskp->next = args->disk_listp;
args->disk_listp = diskp;
diff --git a/usr/src/lib/libdiskmgt/common/media.c b/usr/src/lib/libdiskmgt/common/media.c
index ac29898ede..9f6ee99ff1 100644
--- a/usr/src/lib/libdiskmgt/common/media.c
+++ b/usr/src/lib/libdiskmgt/common/media.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,7 +37,6 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/vtoc.h>
-#include <volmgt.h>
#include <sys/efi_partition.h>
#include "libdiskmgt.h"
@@ -51,7 +49,7 @@
static descriptor_t **apply_filter(descriptor_t **media, int filter[],
int *errp);
static int get_attrs(disk_t *dp, int fd, nvlist_t *attrs);
-static int get_non_volm_name(disk_t *dp, char *mname, int size);
+static int get_rmm_name(disk_t *dp, char *mname, int size);
static int get_media_type(uint_t media_type);
static int desc_ok(descriptor_t *dp);
@@ -215,90 +213,6 @@ media_get_stats(descriptor_t *dp, int stat_type, int *errp)
return (NULL);
}
-/*
- * Get the removable media volume manager devpath for the disk. This is the
- * name we need to open that will work with vold.
- * Return 1 if under volm control, 0 if not under volm control.
- * The string in mediapath will be empty if the drive is under volm control
- * but there is no media loaded.
- */
-int
-media_get_volm_path(disk_t *diskp, char *mediapath, int size)
-{
- char vname[MAXPATHLEN];
- char *volname;
- char *media_name;
-
- if (!diskp->removable || !volmgt_running()) {
- return (0);
- }
-
- /*
- * The volume manager is running, so we have to check if this removable
- * drive is under volm control or not.
- */
-
- /*
- * We must check if this drive is under volume management control and
- * what devpath to use.
- * Note that we have to do this every time for drives that are not
- * under the control of the volume manager, since the volume manager
- * might have taken control since the last time we checked.
- */
- if (diskp->volm_path_set == 0) {
- alias_t *ap;
- slice_t *dp;
-
- if ((ap = diskp->aliases) == NULL) {
- return (0);
- }
-
- /* Check each devpath to see if it is under volm control. */
- dp = ap->devpaths;
- while (dp != NULL) {
- slice_rdsk2dsk(dp->devpath, vname, sizeof (vname));
- if (volmgt_inuse(vname)) {
- break;
- }
-
- dp = dp->next;
- }
-
- if (dp != NULL) {
- /* Volume manager is managing the devpath that dp points to. */
- diskp->volm_path = dp->devpath;
- diskp->volm_path_set = 1;
- }
- }
-
- if (diskp->volm_path_set == 0) {
- /* The volume manager is not managing any of the devpaths. */
- return (0);
- }
-
- if (dm_debug > 1) {
- (void) fprintf(stderr, "INFO: chk vol: %s\n", diskp->volm_path);
- }
-
- slice_rdsk2dsk(diskp->volm_path, vname, sizeof (vname));
- volname = volmgt_symname(vname);
- if (volname == NULL) {
- mediapath[0] = 0;
- return (1);
- }
-
- media_name = media_findname(volname);
- free(volname);
- if (media_name == NULL) {
- mediapath[0] = 0;
- return (1);
- }
-
- (void) strlcpy(mediapath, media_name, size);
- free(media_name);
- return (1);
-}
-
int
media_make_descriptors()
{
@@ -357,9 +271,6 @@ media_read_info(int fd, struct dk_minfo *minfo)
int
media_read_name(disk_t *dp, char *mname, int size)
{
- int under_volm;
- char rmmedia_devpath[MAXPATHLEN];
-
mname[0] = 0;
if (!dp->removable) {
@@ -371,24 +282,7 @@ media_read_name(disk_t *dp, char *mname, int size)
}
/* This is a removable media drive. */
-
- /* Get 1 if under volm control, 0 if not */
- under_volm = media_get_volm_path(dp, rmmedia_devpath,
- sizeof (rmmedia_devpath));
-
- if (under_volm) {
- /* under volm control */
- if (rmmedia_devpath[0] == 0) {
- /* no media */
- return (0);
- }
- (void) strlcpy(mname, rmmedia_devpath, size);
- return (1);
-
- } else {
- /* not under volm control */
- return (get_non_volm_name(dp, mname, size));
- }
+ return (get_rmm_name(dp, mname, size));
}
static descriptor_t **
@@ -636,10 +530,10 @@ get_media_type(uint_t media_type)
}
/*
- * This function handles removable media not under volume management.
+ * This function handles removable media.
*/
static int
-get_non_volm_name(disk_t *dp, char *mname, int size)
+get_rmm_name(disk_t *dp, char *mname, int size)
{
int loaded;
int fd;
diff --git a/usr/src/lib/libdiskmgt/common/partition.c b/usr/src/lib/libdiskmgt/common/partition.c
index 49fa757330..e1f29479b9 100644
--- a/usr/src/lib/libdiskmgt/common/partition.c
+++ b/usr/src/lib/libdiskmgt/common/partition.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -604,89 +603,8 @@ has_slices(descriptor_t *desc, int *errp)
static int
open_disk(disk_t *diskp, char *opath, int len)
{
- char rmmedia_devpath[MAXPATHLEN];
-
- if (diskp->removable && media_get_volm_path(diskp, rmmedia_devpath,
- sizeof (rmmedia_devpath))) {
-
- int fd;
- struct stat buf;
-
- if (rmmedia_devpath[0] == 0) {
- /* removable but no media */
- return (-1);
- }
-
- if ((fd = open(rmmedia_devpath, O_RDONLY|O_NDELAY)) < 0) {
- return (-1);
- }
-
- if (fstat(fd, &buf) != 0) {
- (void) close(fd);
- return (-1);
- }
-
- if (S_ISCHR(buf.st_mode)) {
- /* opened, is device, so done */
- if (opath != NULL) {
- (void) strlcpy(opath, rmmedia_devpath, len);
- }
- return (fd);
-
- } else if (S_ISDIR(buf.st_mode)) {
- /* disk w/ slices so handle the directory */
- DIR *dirp;
- struct dirent *dentp;
- int dfd;
-
- /* each device file in the dir represents a slice */
-
- if ((dirp = fdopendir(fd)) == NULL) {
- (void) close(fd);
- return (-1);
- }
-
- while ((dentp = readdir(dirp)) != NULL) {
- char slice_path[MAXPATHLEN];
-
- if (libdiskmgt_str_eq(".", dentp->d_name) ||
- libdiskmgt_str_eq("..", dentp->d_name)) {
- continue;
- }
-
- (void) snprintf(slice_path, sizeof (slice_path), "%s/%s",
- rmmedia_devpath, dentp->d_name);
-
- if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) < 0) {
- continue;
- }
-
- if (fstat(dfd, &buf) == 0 && S_ISCHR(buf.st_mode)) {
- /* opened, is device, so done */
- (void) closedir(dirp);
- if (opath != NULL) {
- (void) strlcpy(opath, slice_path, len);
- }
- return (dfd);
- }
-
- /* not a device, keep looking */
- (void) close(dfd);
- }
-
- /* did not find a device under the rmmedia_path */
- (void) closedir(dirp);
- return (-1);
- }
-
- /* didn't find a device under volume management control */
- (void) close(fd);
- return (-1);
- }
-
/*
- * Not removable media under volume management control so just open the
- * first devpath.
+ * Just open the first devpath.
*/
if (diskp->aliases != NULL && diskp->aliases->devpaths != NULL) {
#ifdef sparc
diff --git a/usr/src/lib/libdiskmgt/common/slice.c b/usr/src/lib/libdiskmgt/common/slice.c
index e94c443cfb..2e76e43671 100644
--- a/usr/src/lib/libdiskmgt/common/slice.c
+++ b/usr/src/lib/libdiskmgt/common/slice.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -73,17 +72,9 @@ static int desc_ok(descriptor_t *dp);
static void dsk2rdsk(char *dsk, char *rdsk, int size);
static int get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs);
static descriptor_t **get_fixed_assocs(descriptor_t *desc, int *errp);
-static descriptor_t **get_removable_assocs(descriptor_t *desc, char *volm_path,
- int *errp);
static int get_slice_num(slice_t *devp);
static int match_fixed_name(disk_t *dp, char *name, int *errp);
-static int match_removable_name(disk_t *dp, char *name, int *errp);
static int make_fixed_descriptors(disk_t *dp);
-static int make_removable_descriptors(disk_t *dp);
-static int make_volm_dir_descriptors(disk_t *dp, int fd,
- char *volm_path);
-static int num_removable_slices(int fd, struct stat *bufp,
- char *volm_path);
descriptor_t **
slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type,
@@ -114,35 +105,13 @@ slice_get_assoc_descriptors(descriptor_t *desc, dm_desc_type_t type,
descriptor_t **
slice_get_assocs(descriptor_t *desc, int *errp)
{
- int under_volm = 0;
- char volm_path[MAXPATHLEN];
-
/* Just check the first drive name. */
if (desc->p.disk->aliases == NULL) {
*errp = 0;
return (libdiskmgt_empty_desc_array(errp));
}
- if (desc->p.disk->removable) {
- if ((under_volm = media_get_volm_path(desc->p.disk, volm_path,
- sizeof (volm_path)))) {
- if (volm_path[0] == 0) {
- /* no media */
- *errp = 0;
- return (libdiskmgt_empty_desc_array(errp));
- }
- }
- }
-
- if (desc->p.disk->removable) {
- if (under_volm) {
- return (get_removable_assocs(desc, volm_path, errp));
- } else {
- return (get_fixed_assocs(desc, errp));
- }
- } else {
- return (get_fixed_assocs(desc, errp));
- }
+ return (get_fixed_assocs(desc, errp));
}
nvlist_t *
@@ -188,24 +157,21 @@ slice_get_descriptor_by_name(char *name, int *errp)
disk_t *dp;
for (dp = cache_get_disklist(); dp != NULL; dp = dp->next) {
- if (dp->removable) {
- found = match_removable_name(dp, name, errp);
- } else {
found = match_fixed_name(dp, name, errp);
- }
- if (found) {
- char mname[MAXPATHLEN];
+ if (found) {
+ char mname[MAXPATHLEN];
- if (*errp != 0) {
- return (NULL);
- }
+ if (*errp != 0) {
+ return (NULL);
+ }
- mname[0] = 0;
- (void) media_read_name(dp, mname, sizeof (mname));
+ mname[0] = 0;
+ (void) media_read_name(dp, mname, sizeof (mname));
- return (cache_get_desc(DM_SLICE, dp, name, mname, errp));
- }
+ return (cache_get_desc(DM_SLICE, dp, name, mname,
+ errp));
+ }
}
*errp = ENODEV;
@@ -310,11 +276,7 @@ slice_make_descriptors()
while (dp != NULL) {
int error;
- if (dp->removable) {
- error = make_removable_descriptors(dp);
- } else {
- error = make_fixed_descriptors(dp);
- }
+ error = make_fixed_descriptors(dp);
if (error != 0) {
return (error);
}
@@ -750,140 +712,6 @@ get_fixed_assocs(descriptor_t *desc, int *errp)
return (slices);
}
-/*
- * Called for loaded removable media under volume management control.
- */
-static descriptor_t **
-get_removable_assocs(descriptor_t *desc, char *volm_path, int *errp)
-{
- int pos;
- int fd;
- int cnt;
- struct stat buf;
- descriptor_t **slices;
- char *media_name = NULL;
- char devpath[MAXPATHLEN];
-
- /* get the media name from the descriptor */
- if (desc->type == DM_MEDIA) {
- media_name = desc->name;
- } else {
- /* must be a DM_PARTITION */
- media_name = desc->secondary_name;
- }
-
- /*
- * For removable media under volm control the volm_path will
- * either be a device (if the media is made up of a single slice) or
- * a directory (if the media has multiple slices) with the slices
- * as devices contained in the directory.
- */
-
- if ((fd = open(volm_path, O_RDONLY|O_NDELAY)) < 0 ||
- fstat(fd, &buf) != 0) {
- *errp = ENODEV;
- return (NULL);
- }
-
- cnt = num_removable_slices(fd, &buf, volm_path);
-
- /* allocate the array for the descriptors */
- slices = calloc(cnt + 1, sizeof (descriptor_t *));
- if (slices == NULL) {
- *errp = ENOMEM;
- return (NULL);
- }
-
- slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
-
- pos = 0;
- *errp = 0;
- if (S_ISCHR(buf.st_mode)) {
- struct dk_minfo minfo;
-
- /* Make sure media has readable label */
- if (media_read_info(fd, &minfo)) {
- int status;
- int data_format = FMT_UNKNOWN;
- struct vtoc vtoc;
- struct dk_gpt *efip;
-
- if ((status = read_vtoc(fd, &vtoc)) >= 0) {
- data_format = FMT_VTOC;
- } else if (status == VT_ENOTSUP &&
- efi_alloc_and_read(fd, &efip) >= 0) {
- data_format = FMT_EFI;
- }
-
- if (data_format != FMT_UNKNOWN) {
- /* has a readable label */
- slices[pos++] =
- cache_get_desc(DM_SLICE, desc->p.disk,
- devpath, media_name, errp);
- }
- }
- (void) close(fd);
- } else if (S_ISDIR(buf.st_mode)) {
- DIR *dirp;
- struct dirent *dentp;
-
- /* rewind, num_removable_slices already traversed */
- (void) lseek(fd, 0, SEEK_SET);
-
- if ((dirp = fdopendir(fd)) == NULL) {
- *errp = errno;
- (void) close(fd);
- return (NULL);
- }
-
- while ((dentp = readdir(dirp)) != NULL) {
- int dfd;
- int is_dev = 0;
- char slice_path[MAXPATHLEN];
-
- if (libdiskmgt_str_eq(".", dentp->d_name) ||
- libdiskmgt_str_eq("..", dentp->d_name)) {
- continue;
- }
-
- (void) snprintf(slice_path, sizeof (slice_path),
- "%s/%s", devpath, dentp->d_name);
-
- if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) >= 0) {
- struct stat buf;
-
- if (fstat(dfd, &buf) == 0 &&
- S_ISCHR(buf.st_mode)) {
- is_dev = 1;
- }
- (void) close(dfd);
- }
-
- if (!is_dev) {
- continue;
- }
-
- slices[pos++] = cache_get_desc(DM_SLICE, desc->p.disk,
- slice_path, media_name, errp);
- if (*errp != 0) {
- break;
- }
- }
- (void) closedir(dirp);
- } else {
- (void) close(fd);
- }
-
- slices[pos] = NULL;
-
- if (*errp != 0) {
- cache_free_descriptors(slices);
- return (NULL);
- }
-
- return (slices);
-}
-
static int
get_slice_num(slice_t *devp)
{
@@ -979,141 +807,6 @@ make_fixed_descriptors(disk_t *dp)
}
/*
- * For removable media under volm control we have to do some special handling.
- * We don't use the vtoc and /dev/dsk devpaths, since the slices are named
- * under the /vol fs.
- */
-static int
-make_removable_descriptors(disk_t *dp)
-{
- char volm_path[MAXPATHLEN];
- int error;
- int fd;
-
- /*
- * If this removable drive is not under volm control, just use
- * normal handling.
- */
- if (!media_get_volm_path(dp, volm_path, sizeof (volm_path))) {
- return (make_fixed_descriptors(dp));
- }
-
- if (volm_path[0] == 0) {
- /* no media */
- return (0);
- }
-
- /*
- * For removable media under volm control the rmmedia_devapth will
- * either be a device (if the media is made up of a single slice) or
- * a directory (if the media has multiple slices) with the slices
- * as devices contained in the directory.
- */
- error = 0;
- if ((fd = open(volm_path, O_RDONLY|O_NDELAY)) >= 0) {
- struct stat buf;
-
- if (fstat(fd, &buf) == 0) {
- if (S_ISCHR(buf.st_mode)) {
- int status;
- int data_format = FMT_UNKNOWN;
- struct dk_minfo minfo;
- int error;
- struct vtoc vtoc;
- struct dk_gpt *efip;
- char devpath[MAXPATHLEN];
-
- /* Make sure media has readable label */
- if (!media_read_info(fd, &minfo)) {
- /* no media */
- return (0);
- }
-
- if ((status = read_vtoc(fd, &vtoc)) >= 0) {
- data_format = FMT_VTOC;
- } else if (status == VT_ENOTSUP &&
- efi_alloc_and_read(fd, &efip) >= 0) {
- data_format = FMT_EFI;
- }
-
- if (data_format == FMT_UNKNOWN) {
- /* no readable label */
- return (0);
- }
-
- slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
- /* The media name is the volm_path in this case. */
- cache_load_desc(DM_SLICE, dp, devpath, volm_path, &error);
-
- } else if (S_ISDIR(buf.st_mode)) {
- /* each device file in the dir represents a slice */
- error = make_volm_dir_descriptors(dp, fd, volm_path);
- }
- }
- (void) close(fd);
- }
-
- return (error);
-}
-
-/*
- * This handles removable media with slices under volume management control.
- * In this case we have a dir which is the media name and each slice on the
- * media is a device file in this dir.
- */
-static int
-make_volm_dir_descriptors(disk_t *dp, int dirfd, char *volm_path)
-{
- int error;
- DIR *dirp;
- struct dirent *dentp;
- char devpath[MAXPATHLEN];
-
- dirfd = dup(dirfd);
- if (dirfd < 0)
- return (0);
- if ((dirp = fdopendir(dirfd)) == NULL) {
- (void) close(dirfd);
- return (0);
- }
-
- slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
-
- error = 0;
- while ((dentp = readdir(dirp)) != NULL) {
- int fd;
- char slice_path[MAXPATHLEN];
-
- if (libdiskmgt_str_eq(".", dentp->d_name) ||
- libdiskmgt_str_eq("..", dentp->d_name)) {
- continue;
- }
-
- (void) snprintf(slice_path, sizeof (slice_path), "%s/%s",
- devpath, dentp->d_name);
-
- if ((fd = open(slice_path, O_RDONLY|O_NDELAY)) >= 0) {
- struct stat buf;
-
- /* The media name is the volm_path in this case. */
- if (fstat(fd, &buf) == 0 && S_ISCHR(buf.st_mode)) {
- cache_load_desc(DM_SLICE, dp, slice_path,
- volm_path, &error);
- if (error != 0) {
- (void) close(fd);
- break;
- }
- }
-
- (void) close(fd);
- }
- }
- (void) closedir(dirp);
-
- return (error);
-}
-
-/*
* Just look for the name on the devpaths we have cached. Return 1 if we
* find the name and the size of that slice is non-zero.
*/
@@ -1206,161 +899,3 @@ match_fixed_name(disk_t *diskp, char *name, int *errp)
*errp = ENODEV;
return (1);
}
-
-static int
-match_removable_name(disk_t *diskp, char *name, int *errp)
-{
- char volm_path[MAXPATHLEN];
- int found;
- int fd;
- struct stat buf;
-
- /*
- * If this removable drive is not under volm control, just use
- * normal handling.
- */
- if (!media_get_volm_path(diskp, volm_path, sizeof (volm_path))) {
- return (match_fixed_name(diskp, name, errp));
- }
-
- if (volm_path[0] == 0) {
- /* no media */
- *errp = 0;
- return (0);
- }
-
- /*
- * For removable media under volm control the rmmedia_devapth will
- * either be a device (if the media is made up of a single slice) or
- * a directory (if the media has multiple slices) with the slices
- * as devices contained in the directory.
- */
-
- *errp = 0;
-
- if ((fd = open(volm_path, O_RDONLY|O_NDELAY)) == -1 ||
- fstat(fd, &buf) != 0) {
- return (0);
- }
-
- found = 0;
-
- if (S_ISCHR(buf.st_mode)) {
- char devpath[MAXPATHLEN];
-
- slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
- if (libdiskmgt_str_eq(name, devpath)) {
- found = 1;
- }
- (void) close(fd);
- return (found);
- } else if (S_ISDIR(buf.st_mode)) {
- /* each device file in the dir represents a slice */
- DIR *dirp;
- struct dirent *dentp;
- char devpath[MAXPATHLEN];
-
- if ((dirp = fdopendir(fd)) == NULL) {
- (void) close(fd);
- return (0);
- }
-
- slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
-
- while ((dentp = readdir(dirp)) != NULL) {
- char slice_path[MAXPATHLEN];
-
- if (libdiskmgt_str_eq(".", dentp->d_name) ||
- libdiskmgt_str_eq("..", dentp->d_name)) {
- continue;
- }
-
- (void) snprintf(slice_path, sizeof (slice_path),
- "%s/%s", devpath, dentp->d_name);
-
- if (libdiskmgt_str_eq(name, slice_path)) {
- /* found name, check device */
- int dfd;
- int is_dev = 0;
-
- dfd = open(slice_path, O_RDONLY|O_NDELAY);
- if (dfd >= 0) {
- struct stat buf;
-
- if (fstat(dfd, &buf) == 0 &&
- S_ISCHR(buf.st_mode)) {
- is_dev = 1;
- }
- (void) close(dfd);
- }
-
- /* we found the name */
- found = 1;
-
- if (!is_dev) {
- *errp = ENODEV;
- }
-
- break;
- }
- }
- (void) closedir(dirp);
- } else {
- (void) close(fd);
- }
-
- return (found);
-}
-
-static int
-num_removable_slices(int fd, struct stat *bufp, char *volm_path)
-{
- int cnt = 0;
-
- if (S_ISCHR(bufp->st_mode))
- return (1);
-
- if (S_ISDIR(bufp->st_mode)) {
- /* each device file in the dir represents a slice */
- DIR *dirp;
- struct dirent *dentp;
- char devpath[MAXPATHLEN];
-
- fd = dup(fd);
-
- if (fd < 0)
- return (0);
-
- if ((dirp = fdopendir(fd)) == NULL) {
- (void) close(fd);
- return (0);
- }
-
- slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
-
- while ((dentp = readdir(dirp)) != NULL) {
- int dfd;
- char slice_path[MAXPATHLEN];
-
- if (libdiskmgt_str_eq(".", dentp->d_name) ||
- libdiskmgt_str_eq("..", dentp->d_name)) {
- continue;
- }
-
- (void) snprintf(slice_path, sizeof (slice_path),
- "%s/%s", devpath, dentp->d_name);
-
- if ((dfd = open(slice_path, O_RDONLY|O_NDELAY)) >= 0) {
- struct stat buf;
-
- if (fstat(dfd, &buf) == 0 &&
- S_ISCHR(buf.st_mode)) {
- cnt++;
- }
- (void) close(dfd);
- }
- }
- (void) closedir(dirp);
- }
- return (cnt);
-}
diff --git a/usr/src/lib/libsecdb/auth_attr.txt b/usr/src/lib/libsecdb/auth_attr.txt
index b667fa61dc..5a2ec0e67f 100644
--- a/usr/src/lib/libsecdb/auth_attr.txt
+++ b/usr/src/lib/libsecdb/auth_attr.txt
@@ -40,6 +40,11 @@ solaris.device.config:::Configure Device Attributes::help=DevConfig.html
solaris.device.grant:::Delegate Device Administration::help=DevGrant.html
solaris.device.revoke:::Revoke or Reclaim Device::help=DevRevoke.html
solaris.device.cdrw:::CD-R/RW Recording Authorizations::help=DevCDRW.html
+solaris.device.mount.:::Device Mount::help=DevMount.html
+solaris.device.mount.alloptions.fixed:::Device Mount Fixed With All Options::help=DevMount.html
+solaris.device.mount.alloptions.removable:::Device Mount Removable With All Options::help=DevMount.html
+solaris.device.mount.fixed:::Device Mount Fixed::help=DevMount.html
+solaris.device.mount.removable:::Device Mount Removable::help=DevMount.html
#
solaris.dhcpmgr.:::DHCP Service Management::help=DhcpmgrHeader.html
solaris.dhcpmgr.write:::Modify DHCP Service Configuration::help=DhcpmgrWrite.html
@@ -82,8 +87,10 @@ solaris.smf.manage.:::Manage All SMF Service States::help=SmfManageHeader.html
solaris.smf.manage.autofs:::Manage Automount Service States::help=SmfAutofsStates.html
solaris.smf.manage.bind:::Manage DNS Service States::help=BindStates.html
solaris.smf.manage.cron:::Manage Cron Service States::help=SmfCronStates.html
+solaris.smf.manage.hal:::Manage HAL Service States::help=SmfHALStates.html
solaris.smf.manage.name-service-cache:::Manage Name Service Cache Daemon Service States::help=SmfNscdStates.html
solaris.smf.manage.power:::Manage Power Management Service States::help=SmfPowerStates.html
+solaris.smf.manage.rmvolmgr:::Manage Rmvolmgr Service States::help=SmfRmvolmgrStates.html
solaris.smf.manage.rpc.bind:::Manage RPC Program number mapper::help=SmfRPCBind.html
solaris.smf.manage.sendmail:::Manage Sendmail Service States::help=SmfSendmailStates.html
solaris.smf.manage.ssh:::Manage Secure Shell Service States::help=SmfSshStates.html
diff --git a/usr/src/lib/libsecdb/prof_attr.txt b/usr/src/lib/libsecdb/prof_attr.txt
index b18e06d42c..a79f9aabe4 100644
--- a/usr/src/lib/libsecdb/prof_attr.txt
+++ b/usr/src/lib/libsecdb/prof_attr.txt
@@ -20,7 +20,7 @@
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -39,11 +39,12 @@ Device Management:::Control Access to Removable Media:auths=solaris.device.*;hel
Printer Management:::Manage printers, daemons, spooling:help=RtPrntAdmin.html
Cron Management:::Manage at and cron jobs:auths=solaris.jobs.*,solaris.smf.manage.cron;help=RtCronMngmnt.html
Log Management:::Manage log files:help=RtLogMngmnt.html
-Basic Solaris User:::Automatically assigned rights:auths=solaris.profmgr.read,solaris.jobs.user,solaris.mail.mailq;profiles=All;help=RtDefault.html
+Basic Solaris User:::Automatically assigned rights:auths=solaris.profmgr.read,solaris.jobs.user,solaris.mail.mailq,solaris.device.mount.removable;profiles=All;help=RtDefault.html
Device Security:::Manage devices and Volume Manager:auths=solaris.device.*;help=RtDeviceSecurity.html
DHCP Management:::Manage the DHCP service:auths=solaris.dhcpmgr.*;help=RtDHCPMngmnt.html
File System Management:::Manage, mount, share file systems:auths=solaris.smf.manage.autofs;help=RtFileSysMngmnt.html
File System Security:::Manage file system security attributes:help=RtFileSysSecurity.html
+HAL Management:::Manage HAL SMF service:auths=solaris.smf.manage.hal;help=RtHALMngmnt.html
Mail Management:::Manage sendmail & queues:auths=solaris.smf.manage.sendmail;help=RtMailMngmnt.html
Maintenance and Repair:::Maintain and repair a system:auths=solaris.smf.manage.system-log;help=RtMaintAndRepair.html
Media Backup:::Backup files and file systems:help=RtMediaBkup.html
@@ -57,6 +58,7 @@ Name Service Security:::Security related name service scripts/commands:help=RtNa
Object Access Management:::Change ownership and permission on files:help=RtObAccessMngmnt.html
Process Management:::Manage current processes and processors:auths=solaris.smf.manage.cron,solaris.smf.manage.power;help=RtProcManagement.html
Rights Delegation:::Delegate ability to assign rights to users and roles:auths=solaris.role.delegate,solaris.profmgr.delegate,solaris.grant;help=RtRightsDelegate.html
+Rmvolmgr Management:::Manage Removable Volume Manager SMF service:auths=solaris.smf.manage.rmvolmgr;help=RtRmvolmgrMngmnt.html
Service Management:::Manage services:auths=solaris.smf.manage,solaris.smf.modify
Service Operator:::Administer services:auths=solaris.smf.manage,solaris.smf.modify.framework
Software Installation:::Add application software to the system:help=RtSoftwareInstall.html
diff --git a/usr/src/lib/libvolmgt/Makefile.com b/usr/src/lib/libvolmgt/Makefile.com
index 0a5a1187b6..c91a0027a1 100644
--- a/usr/src/lib/libvolmgt/Makefile.com
+++ b/usr/src/lib/libvolmgt/Makefile.com
@@ -28,8 +28,7 @@
LIBRARY= libvolmgt.a
VERS=.1
-OBJECTS= volattr.o volutil.o volprivate.o volname.o volmgt_fsi.o \
- volmgt_fsidbi.o volmgt_on_private.o
+OBJECTS= volmgt.o volprivate.o volmgt_on_private.o
# include library definitions
include ../../Makefile.lib
diff --git a/usr/src/lib/libvolmgt/common/llib-lvolmgt b/usr/src/lib/libvolmgt/common/llib-lvolmgt
index ed4277a32b..1f12243534 100644
--- a/usr/src/lib/libvolmgt/common/llib-lvolmgt
+++ b/usr/src/lib/libvolmgt/common/llib-lvolmgt
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -23,8 +22,8 @@
/* PROTOLIB1 */
/*
- * Copyright(c) 1997 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -40,7 +39,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
-#include <sys/vol.h>
/* volmgt_fsi.c */
int volmgt_acquire(char *, char *, int, char **, pid_t *);
diff --git a/usr/src/lib/libvolmgt/common/volmgt.c b/usr/src/lib/libvolmgt/common/volmgt.c
new file mode 100644
index 0000000000..b16910d233
--- /dev/null
+++ b/usr/src/lib/libvolmgt/common/volmgt.c
@@ -0,0 +1,631 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/mkdev.h>
+#include <volmgt.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include "volmgt_private.h"
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_running: check to see if volume management is running.
+ *
+ * arguments:
+ * none.
+ *
+ * return value(s):
+ * TRUE if volume management is running, FALSE if not.
+ *
+ * preconditions:
+ * none.
+ */
+int
+volmgt_running(void)
+{
+ /* vold is dead */
+ return (FALSE);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_inuse: check to see if volume management is currently
+ * managing a particular device.
+ *
+ * arguments:
+ * path - the name of the device in /dev. For example,
+ * "/dev/rdiskette".
+ *
+ * return value(s):
+ * TRUE if volume management is managing the device, FALSE if not.
+ *
+ * preconditions:
+ * none.
+ */
+/* ARGSUSED */
+int
+volmgt_inuse(char *path)
+{
+ return (FALSE);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_check: have volume management look at its devices to check
+ * for media having arrived. Since volume management can't
+ * automatically check all types of devices, this function is provided
+ * to allow applications to cause the check to happen automatically.
+ *
+ * arguments:
+ * path - the name of the device in /dev. For example,
+ * /dev/rdiskette. If path is NULL, all "checkable" devices are
+ * checked.
+ *
+ * return value(s):
+ * TRUE if media was found in the device, FALSE if not.
+ *
+ * preconditions:
+ * volume management must be running.
+ */
+/* ARGSUSED */
+int
+volmgt_check(char *path)
+{
+ return (FALSE);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_ownspath: check to see if the given path is contained in
+ * the volume management name space.
+ *
+ * arguments:
+ * path - string containing the path.
+ *
+ * return value(s):
+ * TRUE if the path is owned by volume management, FALSE if not.
+ * Will return FALSE if volume management isn't running.
+ *
+ * preconditions:
+ * none.
+ */
+/* ARGSUSED */
+int
+volmgt_ownspath(char *path)
+{
+ return (FALSE);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_root: return the root of where the volume management
+ * name space is mounted.
+ *
+ * arguments:
+ * none.
+ *
+ * return value(s):
+ * Returns a pointer to a static string containing the path to the
+ * volume management root (e.g. "/vol").
+ * Will return NULL if volume management isn't running.
+ *
+ * preconditions:
+ * none.
+ */
+const char *
+volmgt_root(void)
+{
+ static const char *vold_root = "/dev";
+
+ return (vold_root);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_symname: Returns the volume management symbolic name
+ * for a given device. If an application wants to determine
+ * what the symbolic name (e.g. "floppy0") for the /dev/rdiskette
+ * device would be, this is the function to use.
+ *
+ * arguments:
+ * path - a string containing the /dev device name. For example,
+ * "/dev/diskette" or "/dev/rdiskette".
+ *
+ * Note: must be a block- or char-spcl device, and have a non-zero
+ * st_rdev (real device) stat() value.
+ *
+ * return value(s):
+ * pointer to a string containing the symbolic name.
+ *
+ * NULL indicates that volume management isn't managing that device.
+ *
+ * The string must be free(3)'d.
+ *
+ * preconditions:
+ * none.
+ */
+/* ARGSUSED */
+char *
+volmgt_symname(char *path)
+{
+ return (NULL);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_symdev: Returns the device given the volume management
+ * symbolic name. If an application wants to determine
+ * what the device associated with a particular symbolic name
+ * might be, this is the function to use.
+ *
+ * arguments:
+ * path - a string containing the symbolic device name. For example,
+ * "cdrom0" or "floppy0".
+ *
+ * return value(s):
+ * pointer to a string containing the /dev name.
+ *
+ * NULL indicates that volume management isn't managing that device.
+ *
+ * The string must be free(3)'d.
+ *
+ * preconditions:
+ * none.
+ */
+/* ARGSUSED */
+char *
+volmgt_symdev(char *symname)
+{
+ return (NULL);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * volmgt_feat_enabled: check to see if a volume management feature
+ * is available
+ *
+ * arguments:
+ * feat_str - a string containing the feature to be checked for
+ *
+ * return value(s):
+ * return non-zero if the specified feature is available in
+ * volume management, else return zero
+ *
+ * preconditions:
+ * none.
+ */
+
+
+/*
+ * the following is a lit of the "feature" available in volmgt
+ *
+ * this list is meant to be updated when new features (that users may
+ * want to use) are added to volmgt
+ *
+ * note: feature strings added should be all lower case, and spaces are
+ * discouraged
+ *
+ * (see psarc/1995/138 for more info)
+ */
+static char *volmgt_feat_list[] = {
+#ifdef DIRECT_DEV_ACCESS_WORKING
+ "direct-dev-access", /* access through /dev co-exists */
+#endif
+ "floppy-summit-interfaces", /* volmgt_{acquire,release} */
+ NULL
+};
+
+
+int
+volmgt_feature_enabled(char *feat_str)
+{
+ return (0);
+}
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * uncommitted
+ *
+ * description:
+ * volmgt_acquire: try to acquire the volmgt advisory device reservation
+ * for a specific device.
+ *
+ * arguments:
+ * dev - a device name to attempt reserving. This string can be:
+ * - a full path name to a device
+ * - a symbolic device name (e.g. floppy0)
+ *
+ * id - a reservation string that hopefully describes the application
+ * making this reservation.
+ *
+ * pid - a pointer to a pid_t type. If this argument is not NULL
+ * and the requested device is already reserved, the process
+ * id of the reservation owner will be returned in this
+ * location.
+ *
+ * ovr - an override indicator. If set to non-zero, the caller requests
+ * that this reservation be made unconditionally.
+ *
+ * err - the address of a pointer to a string which is to receive the
+ * id argument used when the current device was reserved. This
+ * is only used when the current reservation attempt fails due
+ * to an already existing reservation for this device.
+ *
+ * return value(s):
+ * A non-zero indicator if successful.
+ *
+ * A zero indicator if unsuccessful. If errno is EBUSY, then the err
+ * argument will be set to point to the string that the process currently
+ * holding the reservation supplied when reserving the device. It is up
+ * to the caller to release the storage occupied by the string via
+ * free(3C) when no longer needed.
+ *
+ * preconditions:
+ * none
+ */
+/* ARGSUSED */
+int
+volmgt_acquire(char *dev, char *id, int ovr, char **err, pid_t *pidp)
+{
+ return (0);
+}
+
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * uncommitted
+ *
+ * description:
+ * volmgt_release: try to release the volmgt advisory device reservation
+ * for a specific device.
+ *
+ * arguments:
+ * dev - a device name to attempt reserving. This string can be:
+ * - a full path name to a device
+ * - a symbolic device name (e.g. floppy0)
+ *
+ * return value(s):
+ * A non-zero indicator if successful
+ * A zero indicator if unsuccessful
+ *
+ * preconditions:
+ * none
+ */
+int
+volmgt_release(char *dev)
+{
+ return (0);
+}
+
+
+/*
+ * returns the "value" of the attribute.
+ * If the attribute is boolean and is TRUE,
+ * "true" is returned. If the boolean is
+ * FALSE, NULL is returned. If the attribute
+ * doesn't exist, NULL is returned. The pointer
+ * returned by media_getattr has been malloc'd and
+ * it is the callers responsibility to free it.
+ */
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * media_getattr: returns the value for an attribute for a piece of
+ * removable media.
+ *
+ * arguments:
+ * path - Path to the media in /vol. Can be the block or character
+ * device.
+ *
+ * attr - name of the attribute.
+ *
+ * return value(s):
+ * returns NULL or a pointer to a string that contains the value for
+ * the requested attribute.
+ *
+ * NULL can mean:
+ * - the media doesn't exist
+ * - there is no more space for malloc(3)
+ * - the attribute doesn't exist for the named media
+ * - the attribute is a boolean and is FALSE
+ *
+ * the pointer to the string must be free'd with free(3).
+ *
+ * preconditions:
+ * volume management (vold) must be running.
+ */
+/* ARGSUSED */
+char *
+media_getattr(char *vol_path, char *attr)
+{
+ return (NULL);
+}
+
+
+/*
+ * sets the attribute "attr" to value "value".
+ *
+ * If value == "" the flag is
+ * considered to be a TRUE boolean.
+ *
+ * If value == 0, it is considered to be a FALSE boolean.
+ * returns TRUE on success, FALSE on failure.
+ *
+ * Can fail for reasons of permission, or if you
+ * write a read-only attribute.
+ */
+
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * media_setattr: set an attribute for a piece of media to a
+ * particular value.
+ *
+ * arguments:
+ * path - Path to the media in /vol. Can be the block or character
+ * device.
+ *
+ * attr - name of the attribute.
+ *
+ * value - value of the attribute. If value == "", the flag is
+ * considered to be a boolean that is TRUE. If value == 0, it
+ * is considered to be a FALSE boolean.
+ *
+ * return value(s):
+ * TRUE on success, FALSE for failure.
+ *
+ * Can fail because:
+ * - don't have permission to set the attribute because caller
+ * is not the owner of the media and attribute is a "system"
+ * attribute.
+ *
+ * - don't have permission to set the attribute because the
+ * attribute is a "system" attribute and is read-only.
+ *
+ * preconditions:
+ * volume management must be running.
+ */
+/* ARGSUSED */
+int
+media_setattr(char *vol_path, char *attr, char *value)
+{
+ return (FALSE);
+}
+
+
+/*
+ * Returns the "id" of a volume. If the returned value
+ * & VOLID_TMP, the volume is temporary and this value
+ * cannot be relied upon across reboots.
+ */
+/*
+ * arc approved interface
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * media_getid: return the "id" of a piece of media.
+ *
+ * arguments:
+ * path - Path to the media in /vol. Can be the block or character
+ * device.
+ * return value(s):
+ * returns a u_longlong_t that is the "id" of the volume.
+ *
+ * preconditions:
+ * volume management must be running.
+ */
+u_longlong_t
+media_getid(char *vol_path)
+{
+ return (0);
+}
+/*
+ * arc approved interface (pending)
+ * - can not be modified without approval from an arc
+ *
+ * committment level:
+ * public
+ *
+ * description:
+ * media_findname: try to come up with the character device when
+ * provided with a starting point. This interface provides the
+ * application programmer to provide "user friendly" names and
+ * easily determine the "/vol" name.
+ *
+ * arguments:
+ * start - a string describing a device. This string can be:
+ * - a full path name to a device (insures it's a
+ * character device by using getfullrawname()).
+ * - a full path name to a volume management media name
+ * with partitions (will return the lowest numbered
+ * raw partition.
+ * - the name of a piece of media (e.g. "fred").
+ * - a symbolic device name (e.g. floppy0, cdrom0, etc)
+ * - a name like "floppy" or "cdrom". Will pick the lowest
+ * numbered device with media in it.
+ *
+ * return value(s):
+ * A pointer to a string that contains the character device
+ * most appropriate to the "start" argument.
+ *
+ * NULL indicates that we were unable to find media based on "start".
+ *
+ * The string must be free(3)'d.
+ *
+ * preconditions:
+ * none.
+ */
+/* ARGSUSED */
+char *
+media_findname(char *start)
+{
+ /* XXX can use HAL nicknames here */
+ return (NULL);
+}
+
+struct alias {
+ char *alias;
+ char *name;
+};
+
+/*
+ * "old" aliases -- used to be used when vold wasn't running
+ */
+static struct alias device_aliases[] = {
+ { "fd", "/dev/rdiskette" },
+ { "fd0", "/dev/rdiskette" },
+ { "fd1", "/dev/rdiskette1" },
+ { "diskette", "/dev/rdiskette" },
+ { "diskette0", "/dev/rdiskette0" },
+ { "diskette1", "/dev/rdiskette1" },
+ { "rdiskette", "/dev/rdiskette" },
+ { "rdiskette0", "/dev/rdiskette0" },
+ { "rdiskette1", "/dev/rdiskette1" },
+ { "floppy", "/dev/rdiskette" },
+ { "floppy0", "/dev/rdiskette0" },
+ { "floppy1", "/dev/rdiskette1" },
+ { "cd", "cdrom0" },
+ { "cd0", "cdrom0" },
+ { "cd1", "cdrom1" },
+ { NULL, NULL }
+};
+
+/*
+ * This is an ON Consolidation Private interface.
+ */
+/* ARGSUSED */
+char *
+_media_oldaliases(char *start)
+{
+ struct alias *s;
+ char *p;
+ char *res = NULL;
+
+ for (s = device_aliases; s->alias != NULL; s++) {
+ if (strcmp(start, s->alias) == 0) {
+ res = strdup(s->name);
+ break;
+ }
+ }
+
+ return (res);
+}
+
+
+/*
+ * This is an ON Consolidation Private interface.
+ *
+ * Print out the aliases available to the program user. Changes
+ * depending in whether volume management is running.
+ */
+void
+_media_printaliases(void)
+{
+}
diff --git a/usr/src/lib/libvolmgt/common/volmgt_on_private.c b/usr/src/lib/libvolmgt/common/volmgt_on_private.c
index 2dd2f6f2cc..0535d07325 100644
--- a/usr/src/lib/libvolmgt/common/volmgt_on_private.c
+++ b/usr/src/lib/libvolmgt/common/volmgt_on_private.c
@@ -50,7 +50,6 @@
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/mnttab.h>
-#include <sys/vol.h>
#include "volmgt_private.h"
@@ -84,60 +83,25 @@ _dev_mounted(char *path)
int ret_val = 0;
-
-#ifdef DEBUG
- denter("_dev_mounted(%s): entering\n", path);
-#endif
-
/* ensure we have the block spcl pathname */
if ((cn = (char *)volmgt_getfullrawname(path)) == NULL) {
-#ifdef DEBUG
- dprintf("_dev_mounted: volmgt_getfullrawname failed\n");
-#endif
goto dun;
}
-#ifdef DEBUG_OPEN
- dprintf("_dev_mounted: fopen()ing \"%s\"\n", MNTTAB);
-#endif
if ((fp = fopen(MNTTAB, "rF")) == NULL) {
/* mtab is gone... let him go */
-#ifdef DEBUG
- perror(MNTTAB);
-#endif
goto dun;
}
-#ifdef DEBUG_OPEN
- dprintf("_dev_mounted: open()ing \"%s\"\n", cn);
-#endif
if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
-#ifdef DEBUG
- dprintf("_dev_mounted: can't open \"%s\" (%d)\n", cn, errno);
-#endif
goto dun;
}
-#ifdef DEBUG_STAT
- dprintf("_dev_mounted: fstat()ing \"%s\"\n", cn);
-#endif
if (fstat64(fd, &sb) < 0) {
-#ifdef DEBUG
- dprintf("_dev_mounted: stat of \"%s\" failed (%d)\n", cn,
- errno);
-#endif
goto dun;
}
-#ifdef DEBUG_IOCTL
- dprintf("_dev_mounted: ioctl(%s, DKIOCINFO)\n", cn);
-#endif
if (ioctl(fd, DKIOCINFO, &info) != 0) {
-#ifdef DEBUG
- dprintf(
- "_dev_mounted: ioctl(DKIOCINFO) on \"%s\" failed (%d)\n",
- cn, errno);
-#endif
goto dun;
}
@@ -155,10 +119,6 @@ dun:
if (fd >= 0) {
(void) close(fd);
}
-#ifdef DEBUG
- dexit("_dev_mounted: returning %s\n",
- ret_val ? "TRUE" : "FALSE");
-#endif
return (ret_val);
}
@@ -187,14 +147,8 @@ _dev_unmount(char *path)
int volume_is_not_managed;
char *pathbuf, *absname;
-#ifdef DEBUG
- denter("_dev_unmount(%s): entering\n", path);
-#endif
if ((bn = (char *)volmgt_getfullblkname(path)) == NULL) {
-#ifdef DEBUG
- dprintf("_dev_unmount: volmgt_getfullblkname failed\n");
-#endif
goto dun;
}
@@ -298,9 +252,6 @@ _dev_unmount(char *path)
dun:
-#ifdef DEBUG
- dexit("_dev_unmount: returning %s\n", ret_val ? "TRUE" : "FALSE");
-#endif
return (ret_val);
}
@@ -351,30 +302,14 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip)
}
/* open the device */
-#ifdef DEBUG_OPEN
- dprintf("vol_getmntdev: open()ing \"%s\"\n", cn);
-#endif
if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
/* if we can't open it *assume* it's not a match */
-#ifdef DEBUG
- dprintf(
- "vol_getmntdev: open of \"%s\" (%s) failed (%d)\n",
- cn, mp->mnt_fstype, errno);
-#endif
free(cn);
continue;
}
/* stat the device */
-#ifdef DEBUG_STAT
- dprintf("vol_getmntdev: fstat()ing \"%s\"\n", cn);
-#endif
if (fstat64(fd, &sb) < 0) {
-#ifdef DEBUG
- dprintf(
- "vol_getmntdev: stat of \"%s\" (%s) failed (%d)\n",
- cn, mp->mnt_fstype, errno);
-#endif
free(cn);
(void) close(fd);
continue; /* ain't there: can't be a match */
@@ -382,11 +317,6 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip)
/* ensure we have a spcl device (a double check) */
if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) {
-#ifdef DEBUG
- dprintf(
- "vol_getmntdev: \"%s\" not a blk- or chr-spcl device\n",
- cn);
-#endif
free(cn);
(void) close(fd);
continue;
@@ -413,16 +343,8 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip)
continue;
}
-#ifdef DEBUG_IOCTL
- dprintf("vol_getmntdev: ioctl(%s, DKIOCINFO)\n", cn);
-#endif
/* one last check -- for diff. slices of the same dev/unit */
if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) {
-#ifdef DEBUG
- dprintf(
- "vol_getmntdev: ioctl(DKIOCINFO) of \"%s\" failed (%d)\n",
- cn, errno);
-#endif
free(cn);
(void) close(fd);
continue;
@@ -446,10 +368,6 @@ vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip)
/* go around again */
}
-#ifdef DEBUG
- dexit("vol_getmntdev: returning %d (%s)\n", ret_val,
- ret_val == 1 ? "SUCCESS" : "FAILURE");
-#endif
return (ret_val);
}
@@ -501,21 +419,8 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
struct mnttab mnt;
int ret_val = FALSE;
-
-
-#ifdef DEBUG
- denter("get_media_info(%s): entering\n", path);
-#endif
-
-#ifdef DEBUG_OPEN
- dprintf("get_media_info: fopen()ing \"%s\"\n", MNTTAB);
-#endif
if ((fp = fopen(MNTTAB, "rF")) == NULL) {
/* mtab is gone... let him go */
-#ifdef DEBUG
- dprintf("get_media_info: can't open \"%s\" (%d)\n", MNTTAB,
- errno);
-#endif
goto dun;
}
@@ -527,36 +432,15 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
goto dun;
}
-#ifdef DEBUG_OPEN
- dprintf("get_media_info: open()ing \"%s\"\n", cn);
-#endif
if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
-#ifdef DEBUG
- dprintf("get_media_info(): can't open \"%s\" (%d)\n", cn,
- errno);
-#endif
goto dun;
}
-#ifdef DEBUG_STAT
- dprintf("get_media_info: fstat()ing \"%s\"\n", cn);
-#endif
if (fstat64(fd, &sb) < 0) {
-#ifdef DEBUG
- dprintf("get_media_info: can't stat \"%s\" (%d)\n", cn, errno);
-#endif
goto dun;
}
-#ifdef DEBUG_IOCTL
- dprintf("get_media_info: ioctl(%s, DKIOCINFO)\n", cn);
-#endif
if (ioctl(fd, DKIOCINFO, &info) != 0) {
-#ifdef DEBUG
- dprintf(
- "get_media_info: ioctl(DKIOCINFO) on \"%s\" failed (%d)\n",
- cn, errno);
-#endif
goto dun;
}
@@ -589,20 +473,10 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
/* get the first part of the mount point (e.g. "floppy") */
cp = mnt.mnt_mountp;
if (*cp++ != '/') {
-#ifdef DEBUG
- dprintf(
- "get_media_info warning: no leading '/' in mount point \"%s\"\n",
- mnt.mnt_mountp);
-#endif
goto dun;
}
mtype = cp;
if ((cp = strchr(mtype, '/')) == NULL) {
-#ifdef DEBUG
- dprintf(
- "get_media_info warning: no 2nd '/' in mount point \"%s\"\n",
- mnt.mnt_mountp);
-#endif
goto dun;
}
*cp++ = NULLC;
@@ -613,11 +487,6 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
/* scan for the symlink that points to our volname */
if ((dirp = opendir(mnt_dir)) == NULL) {
-#ifdef DEBUG
- dprintf(
- "get_media_info warning: can't open directory \"%s\"\n",
- mnt_dir);
-#endif
goto dun;
}
mtype_len = strlen(mtype);
@@ -634,9 +503,6 @@ get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
(void) sprintf(lpath, "%s/%s", mnt_dir,
dp->d_name);
-#ifdef DEBUG_STAT
- dprintf("get_media_info: lstat()ing \"%s\"\n", lpath);
-#endif
if (lstat64(lpath, &sb) < 0) {
continue; /* what? */
}
@@ -713,10 +579,6 @@ call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum,
#endif
/* create a child to unmount the path */
if ((pid = fork()) < 0) {
-#ifdef DEBUG
- dprintf("error in call_unmount_prog: fork failed (errno %d)\n",
- errno);
-#endif
goto dun;
}
@@ -775,9 +637,6 @@ call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum,
mi_gotten ? spcl : bn,
NULL);
}
-#ifdef DEBUG
- dprintf("call_unmount_prog: exec failed (errno %d)\n", errno);
-#endif
exit(-1);
/*NOTREACHED*/
}
@@ -792,8 +651,5 @@ call_unmount_prog(int mi_gotten, int use_rmm, char *mtype, int mnum,
}
dun:
-#ifdef DEBUG
- dexit("call_unmount_prog: returning %s\n", ret_val ? "TRUE" : "FALSE");
-#endif
return (ret_val);
}
diff --git a/usr/src/lib/libvolmgt/common/volmgt_private.h b/usr/src/lib/libvolmgt/common/volmgt_private.h
index 6ee2db9f00..7f5f004904 100644
--- a/usr/src/lib/libvolmgt/common/volmgt_private.h
+++ b/usr/src/lib/libvolmgt/common/volmgt_private.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1995-1996, by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _VOLMGT_PRIVATE_H
@@ -36,15 +35,8 @@ extern "C" {
/*
* Interfaces that are private to the volmgt library.
*/
-char *getrawpart0(char *path);
char *volmgt_getfullblkname(char *n);
char *volmgt_getfullrawname(char *n);
-char *volmgt_completename(char *name);
-char *concat_paths(char *s, char *head, char *tail, char *opt_tail2);
-
-#define DEFAULT_ROOT "/vol"
-#define DEFAULT_CONFIG "/etc/vold.conf"
-#define MAXARGC 100
#ifndef TRUE
#define TRUE 1
diff --git a/usr/src/lib/libvolmgt/common/volprivate.c b/usr/src/lib/libvolmgt/common/volprivate.c
index 989405c06b..9ef56f329e 100644
--- a/usr/src/lib/libvolmgt/common/volprivate.c
+++ b/usr/src/lib/libvolmgt/common/volprivate.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1995-1997 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -42,79 +41,10 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
-#include <sys/vol.h>
-#ifdef DEBUG
#include <sys/varargs.h>
-#endif
#include "volmgt_private.h"
-
-/*
- * We have been passed a path which (presumably) is a volume.
- * We look through the directory until we find a name which is
- * a character device.
- */
-char *
-getrawpart0(char *path)
-{
- DIR *dirp = NULL;
- struct dirent64 *dp;
- static char fname[MAXPATHLEN+1];
- struct stat64 sb;
- char *res;
- int len;
-
-
-
- /* open the directory */
- if ((dirp = opendir(path)) == NULL) {
- res = NULL;
- goto dun;
- }
-
- /* get length of directory part */
- len = strlen(path);
-
- /* scan the directory */
- while (dp = readdir64(dirp)) {
-
- /* skip "." and ".." */
- if (strcmp(dp->d_name, ".") == 0) {
- continue;
- }
- if (strcmp(dp->d_name, "..") == 0) {
- continue;
- }
-
- /* ensure we have room for this name */
- if ((len + strlen(dp->d_name) + 1) > MAXPATHLEN) {
- /* XXX: just give up? */
- continue;
- }
-
- /* create a pathname for this device */
- (void) concat_paths(fname, path, dp->d_name, NULL);
- if (stat64(fname, &sb) < 0) {
- continue; /* this shouldn't happen */
- }
- /* check for a char-spcl device */
- if (S_ISCHR(sb.st_mode)) {
- res = strdup(fname);
- goto dun;
- }
- }
-
- /* raw part not found */
- res = NULL;
-dun:
- if (dirp != NULL) {
- (void) closedir(dirp);
- }
- return (res);
-}
-
-
/*
* fix the getfull{raw,blk}name problem for the fd and diskette case
*
@@ -236,72 +166,6 @@ dun:
}
-/*
- * volctl_name -- return name of volctl device
- */
-const char *
-volctl_name(void)
-{
- static char dev_name[] = "/dev/" VOLCTLNAME;
-
- return (dev_name);
-}
-
-
-/*
- * concat_paths -- create a pathname from two (or three) components
- *
- * truncate the result if it is too large
- *
- * assume that res has a defined length of MAXPATHLEN+1
- *
- * ("head" and "tail" are required, but "tail2" is optional)
- */
-char *
-concat_paths(char *res, char *head, char *tail, char *tail2)
-{
- int head_len = strlen(head);
- int len_avail = MAXPATHLEN;
-
-
-
- /* put in as much of the head as will fit */
- (void) strncpy(res, head, len_avail);
- len_avail -= head_len;
-
- /* see if there is room to proceed */
- if (len_avail > 0) {
- char *cp = res + head_len;
-
- /* there is room to append a slash */
- *cp++ = '/';
- len_avail--;
-
- /* see if there is room to proceed */
- if (len_avail > 0) {
- int tail_len = strlen(tail);
-
- /* there is room to append the tail */
- (void) strncpy(cp, tail, len_avail);
- cp += tail_len;
- len_avail -= tail_len;
-
- /* see if there is room to proceed */
- if ((len_avail > 0) && (tail2 != NULL)) {
-
- /* there is room to add tail2 (and need) */
- (void) strncpy(cp, tail2, len_avail);
- }
- }
- }
-
- /* null terminate result (just in case) and return */
- res[MAXPATHLEN] = NULLC;
- return (res);
-}
-
-
-
#ifdef DEBUG
/*
diff --git a/usr/src/lib/policykit/Makefile b/usr/src/lib/policykit/Makefile
new file mode 100644
index 0000000000..b60b67f7a1
--- /dev/null
+++ b/usr/src/lib/policykit/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.lib
+include $(SRC)/lib/policykit/Makefile.policykit
+
+SUBDIRS = libpolkit
+HDRSUBDIRS = libpolkit
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+install_h := TARGET= install_h
+
+.KEEP_STATE:
+
+all clean clobber install: $(SUBDIRS)
+
+install_h: $(ROOTHDRDIR) $(ROOTHDRS) $(SUBDIRS)
+
+#
+# Don't check 3rd party headers.
+#
+check:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/lib/policykit/Makefile.com b/usr/src/lib/policykit/Makefile.com
new file mode 100644
index 0000000000..2dc67c1614
--- /dev/null
+++ b/usr/src/lib/policykit/Makefile.com
@@ -0,0 +1,54 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/policykit/Makefile.policykit
+
+CPPFLAGS = $(POLICYKIT_DBUS_CPPFLAGS) $(POLICYKIT_GLIB_CPPFLAGS) $(CPPFLAGS.master)
+
+C99MODE = $(C99_ENABLE)
+
+ROOTLIBPCDIR = $(ROOT)/usr/lib/pkgconfig
+ROOTLIBPC = $(LIBPCSRC:%=$(ROOTLIBPCDIR)/%)
+
+CLOBBERFILES += $(LIBPCSRC)
+
+#
+# Ensure `all' is the default target.
+#
+all:
+
+$(ROOTLIBPCDIR):
+ $(INS.dir)
+
+$(ROOTLIBPC): $(ROOTLIBPCDIR) $(LIBPCSRC)
+ $(INS.file) $(LIBPCSRC)
+
+$(LIBPCSRC): ../common/$(LIBPCSRC).in
+ $(SED) -e "s@__VERSION__@$(POLICYKIT_VERSION)@" \
+ < ../common/$(LIBPCSRC).in > $(LIBPCSRC)
+
diff --git a/usr/src/lib/policykit/Makefile.policykit b/usr/src/lib/policykit/Makefile.policykit
new file mode 100644
index 0000000000..8b8cff0fe1
--- /dev/null
+++ b/usr/src/lib/policykit/Makefile.policykit
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Definitions common for PolicyKit
+#
+
+POLICYKIT_VERSION = 0.2
+
+POLICYKIT_DBUS_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include
+POLICYKIT_GLIB_CPPFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
+
+POLICYKIT_DBUS_LDLIBS = -ldbus-1
+POLICYKIT_GLIB_LDLIBS = -lglib-2.0
diff --git a/usr/src/lib/policykit/libpolkit/Makefile b/usr/src/lib/policykit/libpolkit/Makefile
new file mode 100644
index 0000000000..76b1fd758e
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/Makefile
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+include ../../Makefile.lib
+include ../Makefile.com
+
+HDRS = libpolkit.h
+HDRDIR = common
+ROOTHDRDIR = $(ROOT)/usr/include/libpolkit
+
+SUBDIRS = $(MACH)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+
+.KEEP_STATE:
+
+all clean clobber install: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/policykit/libpolkit/Makefile.com b/usr/src/lib/policykit/libpolkit/Makefile.com
new file mode 100644
index 0000000000..0fb2f8a7f6
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/Makefile.com
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# usr/src/lib/policykit/libpolkit/Makefile.com
+#
+
+LIBRARY = libpolkit.a
+VERS = .0.0.0
+VERS_MAJ = .0
+OBJECTS = libpolkit-rbac.o
+LIBPCSRC = polkit.pc
+
+include ../../Makefile.com
+
+LIBS = $(DYNLIB) $(LINTLIB)
+LDLIBS += $(POLICYKIT_GLIB_LDLIBS)
+LDLIBS += -lc -lsecdb
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -DPACKAGE_LOCALE_DIR=\"/usr/lib/locale\"
+
+ROOTMAJLINK = $(ROOTLIBDIR)/$(LIBRARY:.a=.so)$(VERS_MAJ)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint:
+
+$(ROOTMAJLINK):
+ -$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c b/usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c
new file mode 100644
index 0000000000..a0c757f622
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/common/libpolkit-rbac.c
@@ -0,0 +1,204 @@
+/***************************************************************************
+ *
+ * libpolkit-rbac.c : RBAC implementation of the libpolkit API
+ *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+#include <auth_attr.h>
+#include <secdb.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include "libpolkit.h"
+
+#define LIBPOLKIT_MAGIC 0x3117beef
+
+#ifdef __SUNPRO_C
+#define __FUNCTION__ __func__
+#endif
+
+#define LIBPOLKIT_CHECK_CONTEXT(_ctx_, _ret_) \
+ do { \
+ if (_ctx_ == NULL) { \
+ g_warning ("%s: given LibPolKitContext is NULL", \
+ __FUNCTION__); \
+ return _ret_; \
+ } \
+ if (_ctx_->magic != LIBPOLKIT_MAGIC) { \
+ g_warning ("%s: given LibPolKitContext is invalid (read magic 0x%08x, should be 0x%08x)", \
+ __FUNCTION__, _ctx_->magic, LIBPOLKIT_MAGIC); \
+ return _ret_; \
+ } \
+ } while(0)
+
+
+struct LibPolKitContext_s
+{
+ guint32 magic;
+};
+
+/** Get a new context.
+ *
+ * @return Pointer to new context or NULL if an error occured
+ */
+LibPolKitContext *
+libpolkit_new_context (DBusConnection *connection)
+{
+ LibPolKitContext *ctx;
+
+ ctx = g_new0 (LibPolKitContext, 1);
+ ctx->magic = LIBPOLKIT_MAGIC;
+
+ return ctx;
+}
+
+/** Free a context
+ *
+ * @param ctx The context obtained from libpolkit_new_context
+ * @return Pointer to new context or NULL if an error occured
+ */
+gboolean
+libpolkit_free_context (LibPolKitContext *ctx)
+{
+ LIBPOLKIT_CHECK_CONTEXT (ctx, FALSE);
+
+ ctx->magic = 0;
+ g_free (ctx);
+ return TRUE;
+}
+
+LibPolKitResult
+libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx,
+ const char *user,
+ const char *privilege,
+ GList **resources,
+ GList **restrictions,
+ int *num_non_temporary)
+{
+ LibPolKitResult res;
+ char **resource_list;
+ int num_resources;
+ char **restriction_list;
+ int num_restrictions;
+
+ LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
+
+ res = LIBPOLKIT_RESULT_ERROR;
+ *resources = NULL;
+ *restrictions = NULL;
+
+ res = LIBPOLKIT_RESULT_OK;
+
+ return res;
+}
+
+LibPolKitResult
+libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
+ const char *system_bus_unique_name,
+ const char *user,
+ const char *privilege,
+ const char *resource,
+ gboolean *out_is_allowed,
+ gboolean *out_is_temporary,
+ char **out_is_privileged_but_restricted_to_system_bus_unique_name)
+{
+ LibPolKitResult res;
+ const char *myresource = "";
+ const char *mysystem_bus_unique_name = "";
+ char *but_restricted_to = NULL;
+ uid_t uid;
+ struct passwd *pw;
+ char *authname;
+ int i;
+ gboolean authname_free = FALSE;
+
+ LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
+
+ uid = (uid_t)atol (user);
+ if ((pw = getpwuid (uid)) == NULL) {
+ *out_is_allowed = FALSE;
+ *out_is_temporary = FALSE;
+ return LIBPOLKIT_RESULT_NO_SUCH_USER;
+ }
+
+ /* map PolicyKit privilege to RBAC authorization */
+ if (strcmp (privilege, "hal-storage-removable-mount") == 0) {
+ authname = "solaris.device.mount.removable";
+ } else if (strcmp (privilege, "hal-storage-removable-mount-all-options") == 0) {
+ authname = "solaris.device.mount.alloptions.removable";
+ } else if (strcmp (privilege, "hal-storage-fixed-mount") == 0) {
+ authname = "solaris.device.mount.fixed";
+ } else if (strcmp (privilege, "hal-storage-fixed-mount-all-options") == 0) {
+ authname = "solaris.device.mount.alloptions.fixed";
+ } else {
+ /* replace '-' with '.' */
+ authname = g_strdup (privilege);
+ authname_free = TRUE;
+ for (i = 0; i < strlen (authname); i++) {
+ if (authname[i] == '-') {
+ authname[i] = '.';
+ }
+ }
+ }
+
+ *out_is_allowed = (chkauthattr(authname, pw->pw_name) != 0);
+ *out_is_temporary = FALSE;
+
+ if (authname_free) {
+ g_free(authname);
+ }
+
+ return LIBPOLKIT_RESULT_OK;
+}
+
+LibPolKitResult
+libpolkit_get_privilege_list (LibPolKitContext *ctx,
+ GList **result)
+{
+ LibPolKitResult res;
+ char **privilege_list;
+ int num_privileges = 0;
+ int i;
+
+ LIBPOLKIT_CHECK_CONTEXT (ctx, LIBPOLKIT_RESULT_INVALID_CONTEXT);
+
+ *result = NULL;
+
+ for (i = 0; i < num_privileges; i++) {
+ *result = g_list_append (*result, g_strdup (privilege_list[i]));
+ }
+
+ res = LIBPOLKIT_RESULT_OK;
+
+ return res;
+}
+
+LibPolKitResult
+libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx,
+ const char *user,
+ const char *privilege,
+ const char *resource,
+ gboolean *result)
+{
+ return LIBPOLKIT_RESULT_OK;
+}
diff --git a/usr/src/lib/policykit/libpolkit/common/libpolkit.h b/usr/src/lib/policykit/libpolkit/common/libpolkit.h
new file mode 100644
index 0000000000..28b4319c7e
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/common/libpolkit.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ *
+ * libpolkit.h : Wraps a subset of methods on the PolicyKit daemon
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_H
+#define LIBPOLKIT_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <glib.h>
+#include <dbus/dbus.h>
+
+typedef enum {
+ LIBPOLKIT_RESULT_OK,
+ LIBPOLKIT_RESULT_ERROR,
+ LIBPOLKIT_RESULT_INVALID_CONTEXT,
+ LIBPOLKIT_RESULT_NOT_PRIVILEGED,
+ LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE,
+ LIBPOLKIT_RESULT_NO_SUCH_USER
+} LibPolKitResult;
+
+struct LibPolKitContext_s;
+typedef struct LibPolKitContext_s LibPolKitContext;
+
+LibPolKitContext *libpolkit_new_context (DBusConnection *connection);
+
+gboolean libpolkit_free_context (LibPolKitContext *ctx);
+
+LibPolKitResult libpolkit_get_privilege_list (LibPolKitContext *ctx,
+ GList **result);
+
+LibPolKitResult libpolkit_is_uid_allowed_for_privilege (LibPolKitContext *ctx,
+ const char *system_bus_unique_name,
+ const char *user,
+ const char *privilege,
+ const char *resource,
+ gboolean *out_is_allowed,
+ gboolean *out_is_temporary,
+ char **out_is_privileged_but_restricted_to_system_bus_unique_name);
+
+LibPolKitResult libpolkit_revoke_temporary_privilege (LibPolKitContext *ctx,
+ const char *user,
+ const char *privilege,
+ const char *resource,
+ gboolean *result);
+
+LibPolKitResult libpolkit_get_allowed_resources_for_privilege_for_uid (LibPolKitContext *ctx,
+ const char *user,
+ const char *privilege,
+ GList **resources,
+ GList **restrictions,
+ int *num_non_temporary);
+
+#endif /* LIBPOLKIT_H */
+
+
diff --git a/usr/src/lib/policykit/libpolkit/common/llib-lpolkit b/usr/src/lib/policykit/libpolkit/common/llib-lpolkit
new file mode 100644
index 0000000000..5762753ad8
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/common/llib-lpolkit
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <libpolkit/libpolkit.h>
diff --git a/usr/src/lib/policykit/libpolkit/common/mapfile-vers b/usr/src/lib/policykit/libpolkit/common/mapfile-vers
new file mode 100644
index 0000000000..d125ced778
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/common/mapfile-vers
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUNW_1.1 {
+ global:
+ libpolkit_new_context;
+ libpolkit_free_context;
+ libpolkit_get_privilege_list;
+ libpolkit_is_uid_allowed_for_privilege;
+ libpolkit_revoke_temporary_privilege;
+ libpolkit_get_allowed_resources_for_privilege_for_uid;
+};
+
+SUNWprivate_1.1 {
+ global:
+ SUNWprivate_1.1;
+ local:
+ *;
+};
diff --git a/usr/src/lib/policykit/libpolkit/common/polkit.pc.in b/usr/src/lib/policykit/libpolkit/common/polkit.pc.in
new file mode 100644
index 0000000000..c6e8793d4a
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/common/polkit.pc.in
@@ -0,0 +1,19 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Licensed under the Academic Free License version 2.1
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libpolkit
+Description: library for querying and setting system-wide policy
+Version: __VERSION__
+Requires: glib-2.0
+Libs: -L${libdir} -lpolkit
+Cflags: -I${includedir}/libpolkit
diff --git a/usr/src/lib/policykit/libpolkit/i386/Makefile b/usr/src/lib/policykit/libpolkit/i386/Makefile
new file mode 100644
index 0000000000..8643a8305f
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK)
diff --git a/usr/src/lib/policykit/libpolkit/sparc/Makefile b/usr/src/lib/policykit/libpolkit/sparc/Makefile
new file mode 100644
index 0000000000..8643a8305f
--- /dev/null
+++ b/usr/src/lib/policykit/libpolkit/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBPC) $(ROOTMAJLINK)
diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile
index b9e0154dbb..7736ef4850 100644
--- a/usr/src/pkgdefs/Makefile
+++ b/usr/src/pkgdefs/Makefile
@@ -198,7 +198,10 @@ COMMON_SUBDIRS= \
SUNWgssc \
SUNWgss \
SUNWgssk \
+ SUNWhal \
+ SUNWhalr \
SUNWhea \
+ SUNWhwdata \
SUNWib \
SUNWibhca \
SUNWiotu \
@@ -267,6 +270,7 @@ COMMON_SUBDIRS= \
SUNWpcu \
SUNWpd \
SUNWphx \
+ SUNWpolkit \
PHXext \
SUNWperl584core \
SUNWperl584usr \
@@ -299,6 +303,8 @@ COMMON_SUBDIRS= \
SUNWrcmdr \
SUNWrcmds \
SUNWrge \
+ SUNWrmvolmgr \
+ SUNWrmvolmgrr \
SUNWrmwbr \
SUNWrmwbu \
SUNWroute \
@@ -316,6 +322,8 @@ COMMON_SUBDIRS= \
SUNWslpr \
SUNWslpu \
SUNWsmapi \
+ SUNWsmedia \
+ SUNWsmediar \
SUNWsn1rint \
SUNWsn1uint \
SUNWsndmr \
@@ -348,8 +356,6 @@ COMMON_SUBDIRS= \
SUNWusb \
SUNWusbs \
SUNWusbu \
- SUNWvolr \
- SUNWvolu \
SUNWxcu4 \
SUNWwlanr \
SUNWwlanu \
diff --git a/usr/src/pkgdefs/SUNWcsr/Makefile b/usr/src/pkgdefs/SUNWcsr/Makefile
index f1868d0188..9857b2ac24 100644
--- a/usr/src/pkgdefs/SUNWcsr/Makefile
+++ b/usr/src/pkgdefs/SUNWcsr/Makefile
@@ -46,6 +46,7 @@ DATAFILES += \
i.locallogin \
i.localprofile \
i.logadmconf \
+ i.logindevperm \
i.mailxrc \
i.manifest \
r.manifest \
@@ -61,15 +62,13 @@ DATAFILES += \
r.rbac \
i.renamenew \
i.renameold \
- i.rmmconf \
i.services \
i.shadow \
i.syslogconf \
i.tiservices \
i.ttydefs \
i.ttysrch \
- i.vfstab \
- i.voldconf
+ i.vfstab
CHKINSTALLSRC=checkinstall.initd
diff --git a/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl
index 4e78352e2e..e5548d3b31 100644
--- a/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl
@@ -44,7 +44,7 @@ DESC="core software for a specific instruction-set architecture"
VENDOR="Sun Microsystems, Inc."
HOTLINE="Please contact your local service provider"
EMAIL=""
-CLASSES="none ttydefs initd renamenew preserve cronroot passwd tiservices inetdconf definit etcremote nsswitch netconfig deflogin defsu syslogconf ttysrch group inittab etcrpc etcprofile mailxrc shadow voldconf rmmconf locallogin localprofile logadmconf nscd fstypes pamconf services rbac renameold dhcpinittab policyconf pkcs11confbase defpasswd vfstab manifest hosts"
+CLASSES="none ttydefs initd renamenew preserve cronroot passwd tiservices inetdconf definit etcremote nsswitch netconfig deflogin defsu syslogconf ttysrch group inittab etcrpc etcprofile mailxrc shadow locallogin localprofile logadmconf logindevperm nscd fstypes pamconf services rbac renameold dhcpinittab policyconf pkcs11confbase defpasswd vfstab manifest hosts"
BASEDIR=/
SUNW_PKGVERS="1.0"
SUNW_PKG_ALLZONES="true"
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com
index c19d3f3539..0d8f9ecf21 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_com
@@ -63,12 +63,11 @@ i i.group
i i.etcrpc
i i.etcprofile
i i.mailxrc
-i i.voldconf
-i i.rmmconf
i i.initd
i i.locallogin
i i.localprofile
i i.logadmconf
+i i.logindevperm
i i.fstypes
i i.pamconf
i i.services
@@ -190,7 +189,7 @@ s none etc/lib/libdl.so.1=../../lib/libdl.so.1
s none etc/lib/nss_files.so.1=../../lib/nss_files.so.1
s none etc/log=../var/adm/log
e logadmconf etc/logadm.conf 644 root sys
-e preserve etc/logindevperm 644 root sys
+e logindevperm etc/logindevperm 644 root sys
f none etc/magic 444 root bin
d none etc/mail 755 root mail
e mailxrc etc/mail/mailx.rc 644 root bin
@@ -523,5 +522,3 @@ f none var/svc/profile/ns_none.xml 0444 root sys
f none var/svc/profile/platform_none.xml 0444 root sys
f none var/svc/profile/prophist.SUNWcsr 0444 root sys
d none var/tmp 1777 root sys
-e rmmconf etc/rmmount.conf 444 root bin
-e voldconf etc/vold.conf 444 root bin
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index af4c8cbcb1..c3ce9378c2 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -110,7 +110,7 @@ f none usr/bin/echo 555 root bin
f none usr/bin/ed 555 root bin
f none usr/bin/edit 555 root bin
f none usr/bin/egrep 555 root bin
-f none usr/bin/eject 4555 root bin
+f none usr/bin/eject 555 root bin
l none usr/bin/encrypt=../../usr/bin/decrypt
f none usr/bin/env 555 root bin
l none usr/bin/ex=../../usr/bin/edit
@@ -389,7 +389,6 @@ f none usr/lib/fs/fd/mount 555 root bin
d none usr/lib/fs/hsfs 755 root sys
f none usr/lib/fs/hsfs/fstyp.so.1 555 root bin
l none usr/lib/fs/hsfs/fstyp=../../../sbin/fstyp
-f none usr/lib/fs/hsfs/ident_hsfs.so.1 555 root bin
f none usr/lib/fs/hsfs/labelit 555 root bin
s none usr/lib/fs/hsfs/mount=../../../../etc/fs/hsfs/mount
d none usr/lib/fs/lofs 755 root sys
@@ -415,7 +414,6 @@ f none usr/lib/fs/ufs/fsirand 555 root bin
f none usr/lib/fs/ufs/fssnap 555 root bin
f none usr/lib/fs/ufs/fstyp.so.1 555 root bin
l none usr/lib/fs/ufs/fstyp=../../../sbin/fstyp
-f none usr/lib/fs/ufs/ident_ufs.so.1 555 root bin
f none usr/lib/fs/ufs/labelit 555 root bin
f none usr/lib/fs/ufs/lockfs 555 root bin
f none usr/lib/fs/ufs/mkfs 555 root bin
diff --git a/usr/src/pkgdefs/SUNWesu/prototype_com b/usr/src/pkgdefs/SUNWesu/prototype_com
index 170e58bc6e..e61c2b200e 100644
--- a/usr/src/pkgdefs/SUNWesu/prototype_com
+++ b/usr/src/pkgdefs/SUNWesu/prototype_com
@@ -146,7 +146,6 @@ f none usr/lib/adb/adbsub.o 644 root sys
f none usr/lib/diff3prog 555 root bin
d none usr/lib/fs 755 root sys
d none usr/lib/fs/pcfs 755 root sys
-f none usr/lib/fs/pcfs/ident_pcfs.so.1 555 root bin
f none usr/lib/fs/pcfs/mount 555 root bin
f none usr/lib/fs/pcfs/fstyp.so.1 555 root bin
l none usr/lib/fs/pcfs/fstyp=../../../sbin/fstyp
diff --git a/usr/src/pkgdefs/SUNWhal/Makefile b/usr/src/pkgdefs/SUNWhal/Makefile
new file mode 100644
index 0000000000..4c08357aab
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhal/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(FILES) depend
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWhal/depend b/usr/src/pkgdefs/SUNWhal/depend
new file mode 100644
index 0000000000..ffdaef957c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhal/depend
@@ -0,0 +1,61 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+# Required system dependencies
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
+
+# Other packages this package has dependencies
+# upon at install-time or run-time.
+P SUNWhwdata Hardware data files
+P SUNWgnome-base-libs GNOME base GUI libraries - platform dependent files, /usr filesystem
+P SUNWdbus Simple IPC library based on messages
+P SUNWhalr Hardware Abstraction Layer (Root)
+P SUNWlexpt libexpat - XML parser library
+P SUNWlxml The XML library
+P SUNWpolkit PolicyKit
diff --git a/usr/src/pkgdefs/SUNWhal/pkginfo.tmpl b/usr/src/pkgdefs/SUNWhal/pkginfo.tmpl
new file mode 100644
index 0000000000..90bfbc7851
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhal/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWhal"
+NAME="Hardware Abstraction Layer"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Hardware Abstraction Layer, HAL (freedesktop.org)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWhal/prototype_com b/usr/src/pkgdefs/SUNWhal/prototype_com
new file mode 100644
index 0000000000..01b9773467
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhal/prototype_com
@@ -0,0 +1,87 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWhal
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+d none usr/lib/hal 755 root bin
+f none usr/lib/hal/hald 555 root bin
+f none usr/lib/hal/hald-addon-storage 555 root bin
+f none usr/lib/hal/hald-probe-storage 555 root bin
+f none usr/lib/hal/hald-probe-volume 555 root bin
+f none usr/lib/hal/hald-runner 555 root bin
+f none usr/lib/hal/hal-storage-closetray 555 root bin
+f none usr/lib/hal/hal-storage-eject 555 root bin
+f none usr/lib/hal/hal-storage-mount 555 root bin
+f none usr/lib/hal/hal-storage-unmount 555 root bin
+f none usr/lib/hal/hal-storage-cleanup-mountpoint 555 root bin
+f none usr/lib/hal/hal-storage-cleanup-all-mountpoints 555 root bin
+f none usr/lib/hal/hal-storage-zpool-export 555 root bin
+f none usr/lib/hal/hal-storage-zpool-import 555 root bin
+s none usr/lib/libhal.so=./libhal.so.1.0.0
+s none usr/lib/libhal.so.1=./libhal.so.1.0.0
+f none usr/lib/libhal.so.1.0.0 755 root bin
+s none usr/lib/libhal-storage.so=./libhal-storage.so.1.0.0
+s none usr/lib/libhal-storage.so.1=./libhal-storage.so.1.0.0
+f none usr/lib/libhal-storage.so.1.0.0 755 root bin
+f none usr/lib/llib-lhal.ln 644 root bin
+f none usr/lib/llib-lhal 644 root bin
+f none usr/lib/llib-lhal-storage.ln 644 root bin
+f none usr/lib/llib-lhal-storage 644 root bin
+d none usr/lib/pkgconfig 755 root other
+f none usr/lib/pkgconfig/hal.pc 644 root bin
+f none usr/lib/pkgconfig/hal-storage.pc 644 root bin
+d none usr/sbin 755 root bin
+f none usr/sbin/hal-device 555 root bin
+f none usr/sbin/hal-fdi-validate 555 root bin
+f none usr/sbin/hal-find-by-capability 555 root bin
+f none usr/sbin/hal-find-by-property 555 root bin
+f none usr/sbin/hal-get-property 555 root bin
+f none usr/sbin/hal-set-property 555 root bin
+f none usr/sbin/lshal 555 root bin
+d none usr/share 755 root sys
+d none usr/share/lib 755 root sys
+d none usr/share/lib/xml 755 root sys
+d none usr/share/lib/xml/dtd 755 root sys
+f none usr/share/lib/xml/dtd/fdi.dtd.1 444 root bin
diff --git a/usr/src/pkgdefs/SUNWhal/prototype_i386 b/usr/src/pkgdefs/SUNWhal/prototype_i386
new file mode 100644
index 0000000000..3972f13118
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhal/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWhal
+#
diff --git a/usr/src/pkgdefs/SUNWhal/prototype_sparc b/usr/src/pkgdefs/SUNWhal/prototype_sparc
new file mode 100644
index 0000000000..aa399f1f14
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhal/prototype_sparc
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWhal
+#
diff --git a/usr/src/pkgdefs/SUNWhalr/Makefile b/usr/src/pkgdefs/SUNWhalr/Makefile
new file mode 100644
index 0000000000..88887f6450
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/Makefile
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+DATAFILES += i.manifest r.manifest
+
+.KEEP_STATE:
+
+all: $(FILES) depend postinstall preinstall
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWhalr/depend b/usr/src/pkgdefs/SUNWhalr/depend
new file mode 100644
index 0000000000..6409fcaf72
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/depend
@@ -0,0 +1,55 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+# Required system dependencies
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
+
+# Other packages this package has dependencies
+# upon at install-time or run-time.
+P SUNWdbus-root Simple IPC library based on messages - / filesystem
diff --git a/usr/src/pkgdefs/SUNWhalr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWhalr/pkginfo.tmpl
new file mode 100644
index 0000000000..7271c63dde
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWhalr"
+NAME="Hardware Abstraction Layer (Root)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Hardware Abstraction Layer, HAL (freedesktop.org) (Root)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none manifest"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="true"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWhalr/postinstall b/usr/src/pkgdefs/SUNWhalr/postinstall
new file mode 100644
index 0000000000..377cc97d7a
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/postinstall
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+# Preinstall script will create this file if HAL service was already
+# installed, in which case we preserve current service state,
+# be it enabled or disabled.
+if [ -f $PKG_INSTALL_ROOT/var/tmp/hal_installed.tmp ]; then
+ rm -f $PKG_INSTALL_ROOT/var/tmp/hal_installed.tmp
+else
+ # enable HAL only in global zone
+ if [ "$UPDATE" = yes ]; then
+ # upgrade
+ cat >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade <<-EOF
+ /usr/sbin/svcadm enable svc:/system/hal:default
+EOF
+ elif [ "${PKG_INSTALL_ROOT:-/}" = "/" ]; then
+ # live system
+ /usr/sbin/svcadm enable svc:/system/hal:default
+ fi
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWhalr/preinstall b/usr/src/pkgdefs/SUNWhalr/preinstall
new file mode 100644
index 0000000000..128c39589b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/preinstall
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+# Presence of this temp file will tell postinstall script
+# that the HAL service is already installed, in which case
+# the current service state will be preserved, be it enabled
+# or disabled.
+rm -f $PKG_INSTALL_ROOT/var/tmp/hal_installed.tmp > /dev/null 2>&1
+
+if [ -f $PKG_INSTALL_ROOT/var/svc/manifest/system/hal.xml ]; then
+ touch $PKG_INSTALL_ROOT/var/tmp/hal_installed.tmp
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWhalr/prototype_com b/usr/src/pkgdefs/SUNWhalr/prototype_com
new file mode 100644
index 0000000000..b42c35545a
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/prototype_com
@@ -0,0 +1,92 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+i postinstall
+i preinstall
+i i.manifest
+i r.manifest
+#
+# source locations relative to the prototype file
+#
+# SUNWhalr
+#
+d none etc 755 root sys
+d none etc/dbus-1 755 root bin
+d none etc/dbus-1/system.d 755 root bin
+f none etc/dbus-1/system.d/hal.conf 644 root bin
+d none etc/hal 755 root bin
+d none etc/hal/fdi 755 root bin
+d none etc/hal/fdi/information 755 root bin
+d none etc/hal/fdi/information/10freedesktop 755 root bin
+f none etc/hal/fdi/information/10freedesktop/10-camera-ptp.fdi 444 root bin
+f none etc/hal/fdi/information/10freedesktop/10-cd-dvd-burner.fdi 444 root bin
+f none etc/hal/fdi/information/10freedesktop/10-usb-card-readers.fdi 444 root bin
+f none etc/hal/fdi/information/10freedesktop/10-usb-music-players.fdi 444 root bin
+f none etc/hal/fdi/information/10freedesktop/10-usb-pda.fdi 444 root bin
+f none etc/hal/fdi/information/10freedesktop/10-usb-zip-drives.fdi 444 root bin
+f none etc/hal/fdi/information/10freedesktop/10-wireless-mice.fdi 444 root bin
+d none etc/hal/fdi/information/20thirdparty 755 root bin
+d none etc/hal/fdi/information/30user 755 root bin
+d none etc/hal/fdi/policy 755 root bin
+d none etc/hal/fdi/policy/10osvendor 755 root bin
+f none etc/hal/fdi/policy/10osvendor/10-keyboard-policy.fdi 444 root bin
+f none etc/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi 444 root bin
+f none etc/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi 444 root bin
+f none etc/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi 444 root bin
+f none etc/hal/fdi/policy/10osvendor/20-storage-methods.fdi 444 root bin
+f none etc/hal/fdi/policy/10osvendor/20-zfs-methods.fdi 444 root bin
+d none etc/hal/fdi/policy/20thirdparty 755 root bin
+d none etc/hal/fdi/policy/30user 755 root bin
+d none etc/hal/fdi/preprobe 755 root bin
+d none etc/hal/fdi/preprobe/10osvendor 755 root bin
+f none etc/hal/fdi/preprobe/10osvendor/10-ide-drives.fdi 444 root bin
+f none etc/hal/fdi/preprobe/10osvendor/20-ignore-fixed-storage.fdi 444 root bin
+f none etc/hal/fdi/preprobe/10osvendor/20-ignore-lofi.fdi 444 root bin
+d none etc/hal/fdi/preprobe/20thirdparty 755 root bin
+d none etc/hal/fdi/preprobe/30user 755 root bin
+d none lib 755 root bin
+d none lib/svc 0755 root bin
+d none lib/svc/method 0755 root bin
+f none lib/svc/method/svc-hal 555 root bin
+d none var 755 root sys
+d none var/svc 755 root sys
+d none var/svc/manifest 755 root sys
+d none var/svc/manifest/system 755 root sys
+f manifest var/svc/manifest/system/hal.xml 444 root sys
diff --git a/usr/src/pkgdefs/SUNWhalr/prototype_i386 b/usr/src/pkgdefs/SUNWhalr/prototype_i386
new file mode 100644
index 0000000000..cb12dac184
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWhalr
+#
diff --git a/usr/src/pkgdefs/SUNWhalr/prototype_sparc b/usr/src/pkgdefs/SUNWhalr/prototype_sparc
new file mode 100644
index 0000000000..c1b1d6a8dd
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhalr/prototype_sparc
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWhalr
+#
diff --git a/usr/src/pkgdefs/SUNWhea/prototype_com b/usr/src/pkgdefs/SUNWhea/prototype_com
index 6b7280eec4..33ecce0f6f 100644
--- a/usr/src/pkgdefs/SUNWhea/prototype_com
+++ b/usr/src/pkgdefs/SUNWhea/prototype_com
@@ -126,6 +126,9 @@ f none usr/include/grp.h 644 root bin
d none usr/include/gssapi 0755 root bin
f none usr/include/gssapi/gssapi.h 0644 root bin
f none usr/include/gssapi/gssapi_ext.h 0644 root bin
+d none usr/include/hal 755 root bin
+f none usr/include/hal/libhal.h 644 root bin
+f none usr/include/hal/libhal-storage.h 644 root bin
f none usr/include/iconv.h 644 root bin
f none usr/include/ieeefp.h 644 root bin
d none usr/include/inet 755 root bin
@@ -188,6 +191,8 @@ f none usr/include/libgen.h 644 root bin
f none usr/include/libintl.h 644 root bin
f none usr/include/libnvpair.h 644 root bin
f none usr/include/libipp.h 644 root bin
+d none usr/include/libpolkit 755 root bin
+f none usr/include/libpolkit/libpolkit.h 644 root bin
f none usr/include/librcm.h 644 root bin
f none usr/include/libscf.h 0644 root bin
f none usr/include/libscf_priv.h 0644 root bin
@@ -337,7 +342,6 @@ f none usr/include/regexp.h 644 root bin
f none usr/include/regexpr.h 644 root bin
f none usr/include/resolv.h 644 root bin
f none usr/include/rje.h 644 root bin
-f none usr/include/rmmount.h 644 root bin
d none usr/include/iso 755 root bin
s none usr/include/iso/assert_iso.h=../assert.h
f none usr/include/iso/ctype_c99.h 644 root bin
@@ -1171,7 +1175,6 @@ f none usr/include/sys/vmmeter.h 644 root bin
f none usr/include/sys/vmparam.h 644 root bin
f none usr/include/sys/vmsystm.h 644 root bin
f none usr/include/sys/vnode.h 644 root bin
-f none usr/include/sys/vol.h 644 root bin
f none usr/include/sys/vtoc.h 644 root bin
f none usr/include/sys/vtrace.h 644 root bin
f none usr/include/sys/vuid_event.h 644 root bin
diff --git a/usr/src/pkgdefs/SUNWhwdata/Makefile b/usr/src/pkgdefs/SUNWhwdata/Makefile
new file mode 100644
index 0000000000..10b6a968fa
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhwdata/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+DATAFILES += depend
+
+.KEEP_STATE:
+
+all: $(FILES)
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWhwdata/pkginfo.tmpl b/usr/src/pkgdefs/SUNWhwdata/pkginfo.tmpl
new file mode 100644
index 0000000000..42f66bfb91
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhwdata/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWhwdata"
+NAME="Hardware data files"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="ASCII databases describing various PCI, USB and other hardware"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWhwdata/prototype_com b/usr/src/pkgdefs/SUNWhwdata/prototype_com
new file mode 100644
index 0000000000..ed445c216f
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhwdata/prototype_com
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWhwdata
+#
+d none usr 755 root sys
+d none usr/share 755 root sys
+d none usr/share/hwdata 755 root sys
+f none usr/share/hwdata/pci.ids 444 root bin
+f none usr/share/hwdata/usb.ids 444 root bin
diff --git a/usr/src/pkgdefs/SUNWhwdata/prototype_i386 b/usr/src/pkgdefs/SUNWhwdata/prototype_i386
new file mode 100644
index 0000000000..4dd6a10932
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhwdata/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWhwdata
+#
diff --git a/usr/src/pkgdefs/SUNWhwdata/prototype_sparc b/usr/src/pkgdefs/SUNWhwdata/prototype_sparc
new file mode 100644
index 0000000000..0d6610c996
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWhwdata/prototype_sparc
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWhwdata
+#
diff --git a/usr/src/pkgdefs/SUNWpcmem/postinstall b/usr/src/pkgdefs/SUNWpcmem/postinstall
index d1695a459a..e54cc3d448 100644
--- a/usr/src/pkgdefs/SUNWpcmem/postinstall
+++ b/usr/src/pkgdefs/SUNWpcmem/postinstall
@@ -3,9 +3,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -23,109 +22,15 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
PATH="/bin:/usr/bin:/usr/sbin:${PATH}"
export PATH
-TMP=/tmp/$$.pcmemvold
-
EXIT=0
-#
-# manipulate the vold.conf and rmmount.conf configurations file
-#
-
-add_to_file()
-{
-
- cp $1 $TMP
-
- ( echo "/$2"
- echo 'a'
- echo "$3"
- echo '.'
- echo 'w'
- echo 'q'
- ) | ed -s $TMP >/dev/null
-
- cp $TMP $1
- rm -f $TMP
-}
-
-add_token()
-{
-
- cp $1 $TMP
-
- ( echo "/$2"
- echo 'a'
- echo "$3"
- echo '.'
- echo '-1,.j'
- echo 'w'
- echo 'q'
- ) | ed -s $TMP >/dev/null
-
- cp $TMP $1
- rm -f $TMP
-}
-
-#
-# vold.conf processing
-#
-FILE="$BASEDIR/etc/vold.conf"
-
-if test -f $FILE ; then
-
- #
- # add the entries to vold.conf
- #
- # label dos label_dos.so floppy pcmem <--- NEW ADD
- # label cdrom label_cdrom.so cdrom
- # label sun label_sun.so floppy pcmem <--- NEW ADD
- #
- add_token "$FILE" 'label_dos.so' ' pcmem'
- add_token "$FILE" 'label_sun.so' ' pcmem'
-
- #
- # add the line of "use pcmem drive ..." after following lines:
- #
- # "use cdrom drive ..."
- # "use floppy drive ..."
- #
- # Default adding after this line
- USELINE="Devices to use"
-
- if (fgrep -s "use cdrom" $FILE) then
- USELINE="use cdrom"
- fi
-
- if (fgrep -s "use floppy" $FILE) then
- USELINE="use floppy"
- fi
-
- add_to_file "$FILE" "$USELINE" \
- 'use pcmem drive /dev/rdsk/c*s2 dev_pcmem.so pcmem%d forceload=true'
-
-fi
-
-#
-# rmmount.conf processing
-#
-FILE="$BASEDIR/etc/rmmount.conf"
-
-if test -f $FILE ; then
- #
- # add the new pcmem entries to rmmount.conf
- # Note the spaces in here --v
- add_token "$FILE" 'ident_ufs.so' ' pcmem'
- add_token "$FILE" 'ident_pcfs.so' ' pcmem'
-
-fi
-
grep '^pcmem\>' ${BASEDIR}/etc/name_to_major > /dev/null && \
rem_drv -b ${BASEDIR} pcmem
add_drv -b ${BASEDIR} -n -m '* 0666 bin bin' \
diff --git a/usr/src/pkgdefs/SUNWpcmem/preremove b/usr/src/pkgdefs/SUNWpcmem/preremove
index f6bfee6654..1d800120de 100644
--- a/usr/src/pkgdefs/SUNWpcmem/preremove
+++ b/usr/src/pkgdefs/SUNWpcmem/preremove
@@ -3,9 +3,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -23,69 +22,13 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
PATH="/bin:/usr/bin:/usr/sbin:${PATH}"
export PATH
-TMP=/tmp/$$.pcmemvold
-
-#
-# manipulate the vold.conf and rmmount.conf configuration file
-#
-
-remove_token()
-{
-
- cp $1 $TMP
-
- ( echo "g/$2/s///g"
- echo 'g/ $/s///g'
- echo 'w'
- echo 'q'
- ) | ed -s $TMP >/dev/null
-
- cp $TMP $1
- rm -f $TMP
-}
-
-#
-# vold.conf processing
-#
-FILE="$BASEDIR/etc/vold.conf"
-
-if test -f $FILE ; then
-
- #
- # clear out any old pcmem lines in vold.conf
- #
- fgrep -v "use pcmem" $FILE >$TMP
- cp $TMP $FILE
- rm -f $TMP
-
- #
- # clear out any old pcmem entries in vold.conf
- #
- remove_token "$FILE" 'pcmem'
-
-fi
-
-#
-# rmmount.conf processing
-#
-FILE="$BASEDIR/etc/rmmount.conf"
-
-if test -f $FILE ; then
-
- #
- # clear out any old pcmem entries in rmmount.conf
- #
- remove_token "$FILE" 'pcmem'
-
-fi
-
rem_drv -b ${BASEDIR} pcmem
rem_drv -b ${BASEDIR} pcram
diff --git a/usr/src/pkgdefs/SUNWpcmem/prototype_com b/usr/src/pkgdefs/SUNWpcmem/prototype_com
index caae3def16..e0fe9ff961 100644
--- a/usr/src/pkgdefs/SUNWpcmem/prototype_com
+++ b/usr/src/pkgdefs/SUNWpcmem/prototype_com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2000,2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# This required package information file contains a list of package contents.
@@ -37,13 +36,12 @@
i pkginfo
i copyright
i depend
-i preinstall
i postinstall
i preremove
#
# source locations relative to the prototype file
#
-# SUNWpcmcu
+# SUNWpcmem
#
d none kernel 0755 root sys
d none kernel/drv 0755 root sys
diff --git a/usr/src/pkgdefs/SUNWpolkit/Makefile b/usr/src/pkgdefs/SUNWpolkit/Makefile
new file mode 100644
index 0000000000..4c08357aab
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpolkit/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(FILES) depend
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWpolkit/depend b/usr/src/pkgdefs/SUNWpolkit/depend
new file mode 100644
index 0000000000..3db04e7829
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpolkit/depend
@@ -0,0 +1,56 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+# Required system dependencies
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
+
+# Other packages this package has dependencies
+# upon at install-time or run-time.
+P SUNWgnome-base-libs GNOME base GUI libraries - platform dependent files, /usr filesystem
+P SUNWdbus Simple IPC library based on messages
diff --git a/usr/src/pkgdefs/SUNWpolkit/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpolkit/pkginfo.tmpl
new file mode 100644
index 0000000000..3590d62fbd
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpolkit/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWpolkit"
+NAME="PolicyKit"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Toolkit for controlling privileges (freedesktop.org)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWpolkit/prototype_com b/usr/src/pkgdefs/SUNWpolkit/prototype_com
new file mode 100644
index 0000000000..9c1b02403a
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpolkit/prototype_com
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpolkit
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+s none usr/lib/libpolkit.so=./libpolkit.so.0.0.0
+s none usr/lib/libpolkit.so.0=./libpolkit.so.0.0.0
+f none usr/lib/libpolkit.so.0.0.0 755 root bin
+f none usr/lib/llib-lpolkit.ln 644 root bin
+f none usr/lib/llib-lpolkit 644 root bin
+d none usr/lib/pkgconfig 755 root other
+f none usr/lib/pkgconfig/polkit.pc 644 root bin
+d none usr/sbin 755 root bin
+f none usr/sbin/polkit-is-privileged 555 root bin
diff --git a/usr/src/pkgdefs/SUNWpolkit/prototype_i386 b/usr/src/pkgdefs/SUNWpolkit/prototype_i386
new file mode 100644
index 0000000000..b13d8f0722
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpolkit/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpolkit
+#
diff --git a/usr/src/pkgdefs/SUNWpolkit/prototype_sparc b/usr/src/pkgdefs/SUNWpolkit/prototype_sparc
new file mode 100644
index 0000000000..448452f368
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpolkit/prototype_sparc
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpolkit
+#
diff --git a/usr/src/pkgdefs/SUNWrmvolmgr/Makefile b/usr/src/pkgdefs/SUNWrmvolmgr/Makefile
new file mode 100644
index 0000000000..4c08357aab
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgr/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(FILES) depend
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWrmvolmgr/depend b/usr/src/pkgdefs/SUNWrmvolmgr/depend
new file mode 100644
index 0000000000..3ac644624f
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgr/depend
@@ -0,0 +1,57 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+# Required system dependencies
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
+
+# Other packages this package has dependencies
+# upon at install-time or run-time.
+P SUNWgnome-base-libs GNOME base GUI libraries - platform dependent files, /usr filesystem
+P SUNWdbus Simple IPC library based on messages
+P SUNWhal Hardware Abstraction Layer
diff --git a/usr/src/pkgdefs/SUNWrmvolmgr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWrmvolmgr/pkginfo.tmpl
new file mode 100644
index 0000000000..6c0f21d458
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgr/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWrmvolmgr"
+NAME="Removable volume manager"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Non-graphical removable volume manager"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWrmvolmgr/prototype_com b/usr/src/pkgdefs/SUNWrmvolmgr/prototype_com
new file mode 100644
index 0000000000..3f40da8090
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgr/prototype_com
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWrmvolmgr
+#
+d none usr 755 root sys
+d none usr/bin 755 root bin
+f none usr/bin/rmformat 4555 root bin
+f none usr/bin/rmmount 555 root bin
+s none usr/bin/rmumount=./rmmount
+f none usr/bin/volrmmount 555 root bin
+f none usr/bin/volcheck 555 root bin
+d none usr/lib 755 root bin
+f none usr/lib/rmvolmgr 555 root bin
+d none usr/sbin 755 root bin
+s none usr/sbin/rmmount=../bin/rmmount
diff --git a/usr/src/pkgdefs/SUNWrmvolmgr/prototype_i386 b/usr/src/pkgdefs/SUNWrmvolmgr/prototype_i386
new file mode 100644
index 0000000000..ec51835f66
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgr/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWrmvolmgr
+#
diff --git a/usr/src/pkgdefs/SUNWrmvolmgr/prototype_sparc b/usr/src/pkgdefs/SUNWrmvolmgr/prototype_sparc
new file mode 100644
index 0000000000..9c96beb954
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgr/prototype_sparc
@@ -0,0 +1,48 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWrmvolmgr
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/Makefile b/usr/src/pkgdefs/SUNWrmvolmgrr/Makefile
new file mode 100644
index 0000000000..88887f6450
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/Makefile
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+DATAFILES += i.manifest r.manifest
+
+.KEEP_STATE:
+
+all: $(FILES) depend postinstall preinstall
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/depend b/usr/src/pkgdefs/SUNWrmvolmgrr/depend
new file mode 100644
index 0000000000..3a0af12beb
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/depend
@@ -0,0 +1,56 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+# Required system dependencies
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
+
+# Other packages this package has dependencies
+# upon at install-time or run-time.
+P SUNWdbus-root Simple IPC library based on messages - / filesystem
+P SUNWhalr Hardware Abstraction Layer (Root)
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWrmvolmgrr/pkginfo.tmpl
new file mode 100644
index 0000000000..388d170f30
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWrmvolmgrr"
+NAME="Removable volume manager (Root)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Non-graphical removable volume manager (Root)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none manifest"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="true"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/postinstall b/usr/src/pkgdefs/SUNWrmvolmgrr/postinstall
new file mode 100644
index 0000000000..2aad094792
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/postinstall
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+# Preinstall script will create this file if rmvolmgr service was already
+# installed, in which case we preserve current service state,
+# be it enabled or disabled.
+if [ -f $PKG_INSTALL_ROOT/var/tmp/rmvolmgr_installed.tmp ]; then
+ rm -f $PKG_INSTALL_ROOT/var/tmp/rmvolmgr_installed.tmp
+else
+ if [ "$UPDATE" = yes ]; then
+ # upgrade
+ cat >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade <<-EOF
+ /usr/sbin/svcadm enable svc:/system/filesystem/rmvolmgr:default
+EOF
+ elif [ "${PKG_INSTALL_ROOT:-/}" = "/" ]; then
+ # live system
+ /usr/sbin/svcadm enable svc:/system/filesystem/rmvolmgr:default
+ fi
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/preinstall b/usr/src/pkgdefs/SUNWrmvolmgrr/preinstall
new file mode 100644
index 0000000000..301f50007b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/preinstall
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+# Presence of this temp file will tell postinstall script
+# that the rmvolmgr service is already installed, in which case
+# the current service state will be preserved, be it enabled
+# or disabled.
+rm -f $PKG_INSTALL_ROOT/var/tmp/rmvolmgr_installed.tmp > /dev/null 2>&1
+
+if [ -f $PKG_INSTALL_ROOT/var/svc/manifest/system/filesystem/rmvolmgr.xml ]; then
+ touch $PKG_INSTALL_ROOT/var/tmp/rmvolmgr_installed.tmp
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_com b/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_com
new file mode 100644
index 0000000000..d79f5d6f3b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_com
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+i postinstall
+i preinstall
+i i.manifest
+i r.manifest
+#
+# source locations relative to the prototype file
+#
+# SUNWrmvolmgrr
+#
+d none lib 755 root bin
+d none lib/svc 0755 root bin
+d none lib/svc/method 0755 root bin
+f none lib/svc/method/svc-rmvolmgr 555 root bin
+d none var 755 root sys
+d none var/svc 755 root sys
+d none var/svc/manifest 755 root sys
+d none var/svc/manifest/system 755 root sys
+d none var/svc/manifest/system/filesystem 755 root sys
+f manifest var/svc/manifest/system/filesystem/rmvolmgr.xml 444 root sys
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_i386 b/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_i386
new file mode 100644
index 0000000000..7c185ce642
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWrmvolmgrr
+#
diff --git a/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_sparc b/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_sparc
new file mode 100644
index 0000000000..9960c43169
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWrmvolmgrr/prototype_sparc
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWrmvolmgrr
+#
diff --git a/usr/src/pkgdefs/SUNWsmedia/Makefile b/usr/src/pkgdefs/SUNWsmedia/Makefile
new file mode 100644
index 0000000000..5a4be447b5
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmedia/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(FILES) depend
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWsmedia/depend b/usr/src/pkgdefs/SUNWsmedia/depend
new file mode 100644
index 0000000000..51ae61205c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmedia/depend
@@ -0,0 +1,54 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+
+P SUNWcar Core Architecture, (Root)
+P SUNWcakr Core Solaris Kernel Architecture (Root)
+P SUNWkvm Core Architecture, (Kvm)
+P SUNWcsr Core Solaris, (Root)
+P SUNWckr Core Solaris Kernel (Root)
+P SUNWcnetr Core Solaris Network Infrastructure (Root)
+P SUNWcsu Core Solaris, (Usr)
+P SUNWcsd Core Solaris Devices
+P SUNWcsl Core Solaris Libraries
+P SUNWnfscr Network File System (NFS) client support (Root)
+P SUNWnfsckr Network File System (NFS) client kernel support (Root)
+P SUNWnfscu Network File System (NFS) client support (Usr)
diff --git a/usr/src/pkgdefs/SUNWsmedia/pkginfo.tmpl b/usr/src/pkgdefs/SUNWsmedia/pkginfo.tmpl
new file mode 100644
index 0000000000..2775c5d337
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmedia/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWsmedia"
+NAME="Storage media management library"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Storage media management library"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWsmedia/prototype_com b/usr/src/pkgdefs/SUNWsmedia/prototype_com
new file mode 100644
index 0000000000..c169ea0bc0
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmedia/prototype_com
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWsmedia
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+s none usr/lib/libsmedia.so=./libsmedia.so.1
+f none usr/lib/libsmedia.so.1 755 root bin
+f none usr/lib/llib-lsmedia.ln 644 root bin
+f none usr/lib/llib-lsmedia 644 root bin
+d none usr/lib/smedia 755 root bin
+f none usr/lib/smedia/sm_scsi.so.1 555 root bin
+f none usr/lib/smedia/sm_pcmem.so.1 555 root bin
+f none usr/lib/smedia/sm_pcata.so.1 555 root bin
+f none usr/lib/smedia/sm_fd.so.1 555 root bin
+f none usr/lib/smedia/rpc.smserverd 555 root bin
diff --git a/usr/src/pkgdefs/SUNWsmedia/prototype_i386 b/usr/src/pkgdefs/SUNWsmedia/prototype_i386
new file mode 100644
index 0000000000..57ee7e9cc6
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmedia/prototype_i386
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWsmedia
+#
+d none usr/lib/amd64 755 root bin
+s none usr/lib/amd64/libsmedia.so=./libsmedia.so.1
+f none usr/lib/amd64/libsmedia.so.1 755 root bin
+f none usr/lib/amd64/llib-lsmedia.ln 644 root bin
+d none usr/lib/smedia/amd64 755 root bin
+f none usr/lib/smedia/amd64/sm_scsi.so.1 555 root bin
+f none usr/lib/smedia/amd64/sm_pcmem.so.1 555 root bin
+f none usr/lib/smedia/amd64/sm_fd.so.1 555 root bin
+f none usr/lib/smedia/amd64/sm_pcata.so.1 555 root bin
diff --git a/usr/src/pkgdefs/SUNWsmedia/prototype_sparc b/usr/src/pkgdefs/SUNWsmedia/prototype_sparc
new file mode 100644
index 0000000000..287a95adfe
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmedia/prototype_sparc
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWsmedia
+#
+d none usr/lib/sparcv9 755 root bin
+s none usr/lib/sparcv9/libsmedia.so=./libsmedia.so.1
+f none usr/lib/sparcv9/libsmedia.so.1 755 root bin
+f none usr/lib/sparcv9/llib-lsmedia.ln 644 root bin
+d none usr/lib/smedia/sparcv9 755 root bin
+f none usr/lib/smedia/sparcv9/sm_scsi.so.1 555 root bin
+f none usr/lib/smedia/sparcv9/sm_pcmem.so.1 555 root bin
+f none usr/lib/smedia/sparcv9/sm_fd.so.1 555 root bin
+f none usr/lib/smedia/sparcv9/sm_pcata.so.1 555 root bin
diff --git a/usr/src/pkgdefs/SUNWsmediar/Makefile b/usr/src/pkgdefs/SUNWsmediar/Makefile
new file mode 100644
index 0000000000..357c4a7885
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/Makefile
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES += depend i.manifest r.manifest
+
+.KEEP_STATE:
+
+all: $(FILES) postinstall preinstall
+
+install: all pkg
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWsmediar/pkginfo.tmpl b/usr/src/pkgdefs/SUNWsmediar/pkginfo.tmpl
new file mode 100644
index 0000000000..8e16d31bc7
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWsmediar"
+NAME="Storage media management library (Root)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Storage media management library (Root)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none manifest"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWsmediar/postinstall b/usr/src/pkgdefs/SUNWsmediar/postinstall
new file mode 100644
index 0000000000..1f6acc1e1c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/postinstall
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+# Preinstall script will create this file if service was already
+# installed, in which case we preserve current service state,
+# be it enabled or disabled.
+if [ -f $PKG_INSTALL_ROOT/var/tmp/smserver_installed.tmp ]; then
+ rm -f $PKG_INSTALL_ROOT/var/tmp/smserver_installed.tmp
+else
+ # enable only in global zone
+ if [ "$UPDATE" = yes ]; then
+ # upgrade
+ cat >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade <<-EOF
+ if [ \`/sbin/zonename\` = global ]; then
+ /usr/sbin/svcadm enable svc:/network/rpc/smserver:default
+ fi
+EOF
+ elif [ "${PKG_INSTALL_ROOT:-/}" = "/" ]; then
+ # live system
+ if [ -z "$SUNW_PKG_INSTALL_ZONENAME" -o "$SUNW_PKG_INSTALL_ZONENAME" = "global" ]; then
+ /usr/sbin/svcadm enable svc:/network/rpc/smserver:default
+ fi
+ fi
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWsmediar/preinstall b/usr/src/pkgdefs/SUNWsmediar/preinstall
new file mode 100644
index 0000000000..bd499b503c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/preinstall
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+# Presence of this temp file will tell postinstall script
+# that the service is already installed, in which case
+# the current service state will be preserved, be it enabled
+# or disabled.
+rm -f $PKG_INSTALL_ROOT/var/tmp/smserver_installed.tmp > /dev/null 2>&1
+
+if [ -f $PKG_INSTALL_ROOT/var/svc/manifest/network/rpc/smserver.xml ]; then
+ touch $PKG_INSTALL_ROOT/var/tmp/smserver_installed.tmp
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWsmediar/prototype_com b/usr/src/pkgdefs/SUNWsmediar/prototype_com
new file mode 100644
index 0000000000..b7cc7a156d
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/prototype_com
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+i preinstall
+i postinstall
+i i.manifest
+i r.manifest
+#
+# source locations relative to the prototype file
+#
+# SUNWsmediar
+#
+d none var 0755 root sys
+d none var/svc 0755 root sys
+d none var/svc/manifest 0755 root sys
+d none var/svc/manifest/network 0755 root sys
+d none var/svc/manifest/network/rpc 0755 root sys
+f manifest var/svc/manifest/network/rpc/smserver.xml 0444 root sys
diff --git a/usr/src/pkgdefs/SUNWsmediar/prototype_i386 b/usr/src/pkgdefs/SUNWsmediar/prototype_i386
new file mode 100644
index 0000000000..4b8bc7a5de
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/prototype_i386
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWsmediar
+#
diff --git a/usr/src/pkgdefs/SUNWsmediar/prototype_sparc b/usr/src/pkgdefs/SUNWsmediar/prototype_sparc
new file mode 100644
index 0000000000..e815bb2dab
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWsmediar/prototype_sparc
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWsmediar
+#
diff --git a/usr/src/pkgdefs/SUNWudf/prototype_com b/usr/src/pkgdefs/SUNWudf/prototype_com
index c91572f67c..bb019ddb0c 100644
--- a/usr/src/pkgdefs/SUNWudf/prototype_com
+++ b/usr/src/pkgdefs/SUNWudf/prototype_com
@@ -51,7 +51,6 @@ f none usr/lib/fs/udfs/fsck 555 root bin
f none usr/lib/fs/udfs/fsdb 555 root bin
f none usr/lib/fs/udfs/fstyp.so.1 555 root bin
l none usr/lib/fs/udfs/fstyp=../../../sbin/fstyp
-f none usr/lib/fs/udfs/ident_udfs.so.1 555 root bin
f none usr/lib/fs/udfs/labelit 555 root bin
f none usr/lib/fs/udfs/mkfs 555 root bin
f none usr/lib/fs/udfs/mount 555 root bin
diff --git a/usr/src/pkgdefs/common_files/i.logindevperm b/usr/src/pkgdefs/common_files/i.logindevperm
new file mode 100644
index 0000000000..c816efa70c
--- /dev/null
+++ b/usr/src/pkgdefs/common_files/i.logindevperm
@@ -0,0 +1,90 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+PATH="/usr/bin:/usr/sbin:${PATH}"
+export PATH
+
+while read src dest; do
+ if [ ! -f $dest ]; then
+ cp -p $src $dest
+ continue;
+ fi
+
+ newdest=/tmp/i.logindevperm.$$
+ cat /dev/null > $newdest
+
+ while read line; do
+ # if not an entry, just print as is and move to next record
+ entry=`echo "$line" | egrep "^[# ]*/[a-zA-Z0-9\/]+[ ]+[0-9]+[ ]+"`
+ if [ -z "$entry" ]; then
+ echo "$line"
+ continue
+ fi
+
+ # extract 'devices' field
+ devices=`echo "$line" | awk '{print $3}'`
+ if [ -z "$devices" ]; then
+ echo "$line"
+ continue
+ fi
+
+ # if dest has an entry for these devices, preserve that
+ dest_entry=`egrep "^[# ]*/[a-zA-Z0-9\/]+[ ]+[0-9]+[ ]+$devices" $dest | tail -1 2>/dev/null`
+ if [ -n "$dest_entry" ]; then
+ echo "$dest_entry"
+ else
+ echo "$line"
+ fi
+ done < $src > $newdest
+
+ # now carry over user's own entries
+ while read line; do
+ # skip non-entries
+ entry=`echo "$line" | egrep "^[# ]*/[a-zA-Z0-9\/]+[ ]+[0-9]+[ ]+"`
+ if [ -z "$entry" ]; then
+ continue
+ fi
+
+ # extract 'devices' field
+ devices=`echo "$line" | awk '{print $3}'`
+ if [ -z "$devices" ]; then
+ continue
+ fi
+
+ # if dest has an entry for these devices, preserve that
+ dest_entry=`egrep "^[# ]*/[a-zA-Z0-9\/]+[ ]+[0-9]+[ ]+$devices" $newdest | tail -1 2>/dev/null`
+ if [ -z "$dest_entry" ]; then
+ echo "$line"
+ fi
+ done < $dest >> $newdest
+
+ cp $newdest $dest
+ rm -f $newdest
+done
+
+exit 0
diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh
index 1bd2408409..2d5ad24656 100644
--- a/usr/src/tools/scripts/bfu.sh
+++ b/usr/src/tools/scripts/bfu.sh
@@ -163,7 +163,6 @@ all_zones_files="
etc/user_attr
etc/uucp/[A-Z]*
etc/vfstab
- etc/vold.conf
var/spool/cron/crontabs/*
var/yp/Makefile
var/yp/aliases
@@ -325,6 +324,7 @@ superfluous_local_zone_files="
lib/svc/method/svc-dscp
lib/svc/method/svc-dumpadm
lib/svc/method/svc-intrd
+ lib/svc/method/svc-hal
lib/svc/method/svc-mdmonitor
lib/svc/method/svc-metainit
lib/svc/method/svc-metasync
@@ -332,6 +332,7 @@ superfluous_local_zone_files="
lib/svc/method/svc-poold
lib/svc/method/svc-pools
lib/svc/method/svc-power
+ lib/svc/method/svc-rmvolmgr
lib/svc/method/svc-scheduler
lib/svc/method/svc-sckmd
lib/svc/method/svc-syseventd
@@ -392,6 +393,7 @@ superfluous_local_zone_files="
var/svc/manifest/system/cvc.xml
var/svc/manifest/system/dumpadm.xml
var/svc/manifest/system/fmd.xml
+ var/svc/manifest/system/hal.xml
var/svc/manifest/system/intrd.xml
var/svc/manifest/system/mdmonitor.xml
var/svc/manifest/system/metainit.xml
@@ -403,6 +405,7 @@ superfluous_local_zone_files="
var/svc/manifest/system/scheduler.xml
var/svc/manifest/system/sysevent.xml
var/svc/manifest/system/zones.xml
+ var/svc/manifest/system/filesystem/rmvolmgr.xml
"
#
@@ -908,6 +911,7 @@ smf_obsolete_rc_files="
etc/init.d/sysid.sys
etc/init.d/syslog
etc/init.d/utmpd
+ etc/init.d/volmgt
etc/init.d/xntpd
etc/init.d/zones
etc/rc0.d/K00ANNOUNCE
@@ -1066,6 +1070,7 @@ smf_obsolete_rc_files="
smf_obsolete_manifests="
var/svc/manifest/network/tftp.xml
var/svc/manifest/network/lp.xml
+ var/svc/manifest/system/filesystem/volfs.xml
"
# smf services whose manifests have been renamed
@@ -1077,6 +1082,7 @@ smf_renamed_manifests="
# Obsolete smf methods
smf_obsolete_methods="
lib/svc/method/print-server
+ lib/svc/method/svc-volfs
"
smf_cleanup () {
@@ -1133,13 +1139,18 @@ smf_handle_new_services () {
$rootprefix/var/svc/profile/upgrade
fi
if [[ $zone = global &&
- ! -f $rootprefix/var/svc/profile/system/filesystem/volfs.xml ]]; then
- echo /usr/sbin/svcadm enable system/filesystem/volfs >> \
+ ! -f $rootprefix/var/svc/manifest/system/scheduler.xml ]]; then
+ echo /usr/sbin/svcadm enable system/scheduler >> \
$rootprefix/var/svc/profile/upgrade
fi
if [[ $zone = global &&
- ! -f $rootprefix/var/svc/manifest/system/scheduler.xml ]]; then
- echo /usr/sbin/svcadm enable system/scheduler >> \
+ ! -f $rootprefix/var/svc/manifest/system/hal.xml ]]; then
+ echo /usr/sbin/svcadm enable system/hal >> \
+ $rootprefix/var/svc/profile/upgrade
+ fi
+ if [[ $zone = global &&
+ ! -f $rootprefix/var/svc/manifest/system/filesystem/rmvolmgr.xml ]]; then
+ echo /usr/sbin/svcadm enable system/filesystem/rmvolmgr >> \
$rootprefix/var/svc/profile/upgrade
fi
}
@@ -2112,6 +2123,11 @@ if ifconfig -a | egrep '^ce' >/dev/null 2>/dev/null; then
fi
fi
+update_script="/ws/onnv-gate/public/bin/update_dbus"
+if [ ! -x /usr/lib/dbus-daemon ]; then
+ fail "Run $update_script to update D-Bus."
+fi
+
if [[ $target_isa = i386 && -f $cpiodir/i86pc.root$ZFIX ]] && \
$ZCAT $cpiodir/i86pc.root$ZFIX | cpio -it 2>/dev/null | \
grep multiboot >/dev/null 2>&1 ; then
@@ -2991,6 +3007,31 @@ remove_eof_dmi() {
rm -f $rootprefix/etc/rc3.d/S77dmi
}
+#
+# Remove vold
+#
+remove_eof_vold()
+{
+ printf 'Removing vold... '
+
+ rm -rf $usr/lib/vold
+ rm -rf $usr/lib/rmmount
+ rm -f $usr/lib/fs/hsfs/ident_hsfs.so.1
+ rm -f $usr/lib/fs/pcfs/ident_pcfs.so.1
+ rm -f $usr/lib/fs/udfs/ident_udfs.so.1
+ rm -f $usr/lib/fs/ufs/ident_ufs.so.1
+ rm -f $usr/sbin/vold
+ rm -f $usr/kernel/drv/vol
+ rm -f $usr/kernel/drv/amd64/vol
+ rm -f $usr/kernel/drv/sparcv9/vol
+ rm -f $usr/include/rmmount.h
+ rm -f $usr/include/vol.h
+ rm -f $rootprefix/etc/vold.conf
+ rm -f $rootprefix/etc/rmmount.conf
+
+ printf '\n'
+}
+
remove_properties() {
#
@@ -5082,6 +5123,13 @@ mondo_loop() {
rm -f /tmp/nssw.$$
#
+ # Remove vold
+ #
+ if [ -f $rootprefix/etc/vold.conf -o -d $usr/lib/vold ]; then
+ remove_eof_vold
+ fi
+
+ #
# Remove SUNWcoff package
#
pkgroot=${rootprefix:+-R $rootprefix}
diff --git a/usr/src/tools/scripts/check_rtime.pl b/usr/src/tools/scripts/check_rtime.pl
index e1cdb4e105..4dd4ef86e7 100644
--- a/usr/src/tools/scripts/check_rtime.pl
+++ b/usr/src/tools/scripts/check_rtime.pl
@@ -111,8 +111,6 @@ $SkipTextrelFiles = qr{ ^(?:
$SkipUndefDirs = qr{
usr/lib/inet/ppp/ | # pppd plugins have callbacks
usr/lib/libp/ | # libc.so.1 requires _mcount
- usr/lib/vold/ | # vold dependencies have callbacks
- usr/lib/rmmount | # rmmount actions have callbacks
/lib/mdb/ | # mdb modules have callbacks
/lib/fm/fmd/plugins/ | # fmd modules have callbacks
/lib/fm/fmd/schemes/ | # fmd schemes have callbacks
@@ -157,8 +155,6 @@ $SkipUnusedFiles = qr{ ^(?:
devlinks | # " "
drvconfig | # " "
ntptrace | # on intel doesn't need libmd5
- rmmount | # 4418770, volmgt dependency is required
- # to compensate for SunPCi.
ocfserv | # libsched unreference by libjvm,
poold | # see 4952319.
libc\.so\.1\.9 | # 4lib/libc versions have private
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index cb22fa717d..bf13c494df 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -562,8 +562,6 @@ MM_OBJS += mem.o
OPTIONS_OBJS += options.o
-VOL_OBJS += vol.o
-
WINLOCK_OBJS += winlockio.o
PM_OBJS += pm.o
diff --git a/usr/src/uts/common/fs/pcfs/pc_vfsops.c b/usr/src/uts/common/fs/pcfs/pc_vfsops.c
index 52d1ba3f19..b18b8aadab 100644
--- a/usr/src/uts/common/fs/pcfs/pc_vfsops.c
+++ b/usr/src/uts/common/fs/pcfs/pc_vfsops.c
@@ -58,7 +58,6 @@
#include <sys/fs/pc_node.h>
#include <fs/fs_subr.h>
#include <sys/modctl.h>
-#include <sys/vol.h>
#include <sys/dkio.h>
#include <sys/open.h>
#include <sys/mntent.h>
@@ -299,8 +298,6 @@ pcfs_mount(
int fattype;
int spnlen;
int wantbootpart = 0;
- struct vioc_info info;
- int rval; /* set but not used */
minor_t minor;
int oflag, aflag;
@@ -554,15 +551,6 @@ pcfs_mount(
fsp->pcfs_dosstart = dosstart;
mutex_init(&fsp->pcfs_lock, NULL, MUTEX_DEFAULT, NULL);
- /* set the "nocheck" flag if volmgt is managing this volume */
- info.vii_pathlen = 0;
- info.vii_devpath = 0;
- error = cdev_ioctl(fsp->pcfs_xdev, VOLIOCINFO, (intptr_t)&info,
- FKIOCTL|FREAD, kcred, &rval);
- if (error == 0) {
- fsp->pcfs_flags |= PCFS_NOCHK;
- }
-
if (vfs_optionisset(vfsp, MNTOPT_PCFS_HIDDEN, NULL))
fsp->pcfs_flags |= PCFS_HIDDEN;
if (vfs_optionisset(vfsp, MNTOPT_PCFS_FOLDCASE, NULL))
diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c
index b74e0c7a47..2d9d01c4e4 100644
--- a/usr/src/uts/common/io/lofi.c
+++ b/usr/src/uts/common/io/lofi.c
@@ -106,7 +106,6 @@
#include <sys/debug.h>
#include <sys/vnode.h>
#include <sys/lofi.h>
-#include <sys/vol.h>
#include <sys/fcntl.h>
#include <sys/pathname.h>
#include <sys/filio.h>
@@ -1092,10 +1091,6 @@ lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
/* these are for faking out utilities like newfs */
switch (cmd) {
- case VOLIOCINFO:
- /* pcfs does this to see if it needs to set PCFS_NOCHK */
- /* 0 means it should set it */
- return (0);
case DKIOCGVTOC:
switch (ddi_model_convert_from(flag & FMODELS)) {
case DDI_MODEL_ILP32: {
diff --git a/usr/src/uts/common/io/ramdisk.c b/usr/src/uts/common/io/ramdisk.c
index 91b6787a55..80c729a5a5 100644
--- a/usr/src/uts/common/io/ramdisk.c
+++ b/usr/src/uts/common/io/ramdisk.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -81,7 +80,6 @@
#include <sys/cmn_err.h>
#include <sys/stat.h>
#include <sys/file.h>
-#include <sys/vol.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/ramdisk.h>
@@ -1251,10 +1249,6 @@ rd_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp)
* These are for faking out utilities like newfs.
*/
switch (cmd) {
- case VOLIOCINFO:
- /* pcfs does this to see if it needs to set PCFS_NOCHK */
- /* 0 means it should set it */
- return (0);
case DKIOCGVTOC:
switch (ddi_model_convert_from(mode & FMODELS)) {
case DDI_MODEL_ILP32: {
diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c
index d618466710..cb709be9d3 100644
--- a/usr/src/uts/common/io/scsi/targets/sd.c
+++ b/usr/src/uts/common/io/scsi/targets/sd.c
@@ -21583,18 +21583,7 @@ skip_ready_valid:
case DKIOCREMOVABLE:
SD_TRACE(SD_LOG_IOCTL, un, "DKIOCREMOVABLE\n");
- /*
- * At present, vold only does automount for removable-media
- * devices, in order not to break current applications, we
- * still let hopluggable devices pretend to be removable media
- * devices for vold. In the near future, once vold is EOL'ed,
- * we should remove this workaround.
- */
- if (un->un_f_has_removable_media || un->un_f_is_hotpluggable) {
- i = 1;
- } else {
- i = 0;
- }
+ i = un->un_f_has_removable_media ? 1 : 0;
if (ddi_copyout(&i, (void *)arg, sizeof (int), flag) != 0) {
err = EFAULT;
} else {
@@ -21604,11 +21593,7 @@ skip_ready_valid:
case DKIOCHOTPLUGGABLE:
SD_TRACE(SD_LOG_IOCTL, un, "DKIOCHOTPLUGGABLE\n");
- if (un->un_f_is_hotpluggable) {
- i = 1;
- } else {
- i = 0;
- }
+ i = un->un_f_is_hotpluggable ? 1 : 0;
if (ddi_copyout(&i, (void *)arg, sizeof (int), flag) != 0) {
err = EFAULT;
} else {
@@ -31234,25 +31219,14 @@ sd_faultinjection(struct scsi_pkt *pktp)
* -----------------------------------------------------------
*
*
- * 6. Automatic mount & unmount (i.e. vold)
+ * 6. Automatic mount & unmount
*
* Sd(7d) driver provides DKIOCREMOVABLE ioctl. This ioctl is used to query
* if a device is removable media device. It return 1 for removable media
* devices, and 0 for others.
*
- * Vold treats a device as removable one only if DKIOREMOVABLE returns 1.
- * And it does automounting only for removable media devices. In order to
- * preserve users' experience and let vold continue to do automounting for
- * USB disk devices, DKIOCREMOVABLE ioctl still returns 1 for USB/1394 disk
- * devices.
- *
- * ------------------------------------------------------
- * removable media hotpluggable | automatic mount
- * ------------------------------------------------------
- * false false | No
- * false true | Yes
- * true x | Yes
- * ------------------------------------------------------
+ * The automatic mounting subsystem should distinguish between the types
+ * of devices and apply automounting policies to each.
*
*
* 7. fdisk partition management
@@ -31437,7 +31411,7 @@ sd_set_unit_attributes(struct sd_lun *un, dev_info_t *devi)
if (un->un_sd->sd_inq->inq_rmb) {
/*
* The media of this device is removable. And for this kind
- * of devices, it is possible to change medium after openning
+ * of devices, it is possible to change medium after opening
* devices. Thus we should support this operation.
*/
un->un_f_has_removable_media = TRUE;
@@ -31589,8 +31563,9 @@ sd_set_unit_attributes(struct sd_lun *un, dev_info_t *devi)
#endif
/*
- * Temporarily, let hotpluggable devices pretend to be
- * removable-media devices for vold.
+ * Have to watch hotpluggable devices as well, since
+ * that's the only way for userland applications to
+ * detect hot removal while device is busy/mounted.
*/
un->un_f_monitor_media_state = TRUE;
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index 4219734efa..e133c8a49e 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -542,7 +542,6 @@ CHKHDRS= \
vmmeter.h \
vmsystm.h \
vnode.h \
- vol.h \
vtoc.h \
vtrace.h \
vuid_event.h \
diff --git a/usr/src/uts/intel/Makefile.intel.shared b/usr/src/uts/intel/Makefile.intel.shared
index 39aa24a3f4..e0064013fe 100644
--- a/usr/src/uts/intel/Makefile.intel.shared
+++ b/usr/src/uts/intel/Makefile.intel.shared
@@ -294,7 +294,6 @@ DRV_KMODS += udp
DRV_KMODS += udp6
DRV_KMODS += vgatext
DRV_KMODS += vni
-DRV_KMODS += vol
DRV_KMODS += wc
DRV_KMODS += winlock
DRV_KMODS += xge
diff --git a/usr/src/uts/intel/os/name_to_major b/usr/src/uts/intel/os/name_to_major
index 551c165a18..1bd224f2d5 100644
--- a/usr/src/uts/intel/os/name_to_major
+++ b/usr/src/uts/intel/os/name_to_major
@@ -39,7 +39,6 @@ devinfo 88
lockstat 89
kstat 90
llc1 91
-vol 93
cpc 95
sysmsg 97
vgatext 99
diff --git a/usr/src/uts/sparc/Makefile.sparc.shared b/usr/src/uts/sparc/Makefile.sparc.shared
index 6f17f59124..0aee1eae57 100644
--- a/usr/src/uts/sparc/Makefile.sparc.shared
+++ b/usr/src/uts/sparc/Makefile.sparc.shared
@@ -231,7 +231,7 @@ DRV_KMODS += log logindmux kssl mm nca pm poll pool
DRV_KMODS += pseudo ptc ptm pts ptsl ramdisk random rsm rts sad
DRV_KMODS += sppp sppptun sy sysevent sysmsg
DRV_KMODS += spdsock
-DRV_KMODS += tcp tcp6 tl tnf ttymux udp udp6 vol wc winlock zcons
+DRV_KMODS += tcp tcp6 tl tnf ttymux udp udp6 wc winlock zcons
DRV_KMODS += ippctl sctp sctp6
DRV_KMODS += dld
DRV_KMODS += ipf pfil
diff --git a/usr/src/uts/sparc/os/name_to_major b/usr/src/uts/sparc/os/name_to_major
index 59fd57f5ff..6953ae6833 100644
--- a/usr/src/uts/sparc/os/name_to_major
+++ b/usr/src/uts/sparc/os/name_to_major
@@ -61,7 +61,6 @@ todds1287 87
devinfo 88
lockstat 89
kstat 90
-vol 91
cpc 95
sysmsg 97
isp 102