$NetBSD: patch-hald_freebsd_hf-usb2.c,v 1.1 2012/03/31 16:06:56 ryoon Exp $ * From FreeBSD ports repository to fix build on FreeBSD 9.0 RELEASE. --- hald/freebsd/hf-usb2.c.orig 2009-08-24 12:42:29.000000000 +0000 +++ hald/freebsd/hf-usb2.c @@ -22,7 +22,7 @@ **************************************************************************/ #ifdef HAVE_CONFIG_H -# include +#include #endif #include @@ -42,246 +42,200 @@ static struct libusb20_backend *hf_usb2_be = NULL; static void -hf_usb2_copy_parent (HalDevice *parent, - const char *key, - gpointer user_data) +hf_usb2_probe_interfaces(HalDevice * parent) { - HalDevice *device; + int num_interfaces; + int i; - g_return_if_fail(HAL_IS_DEVICE(parent)); - g_return_if_fail(HAL_IS_DEVICE(user_data)); + g_return_if_fail(HAL_IS_DEVICE(parent)); - device = HAL_DEVICE(user_data); - - if (! strncmp(key, "usb_device.", strlen("usb_device."))) - hal_device_copy_property(parent, key, device, key); + if (hal_device_property_get_bool(parent, "info.ignore")) + return; + + num_interfaces = hal_device_property_get_int(parent, + "usb_device.num_interfaces"); + + for (i = 0; i < num_interfaces; i++) { + HalDevice *device; + + device = hf_device_new(parent); + + hal_device_property_set_string(device, "info.subsystem", "usb"); + hal_device_property_set_int(device, "usb.interface.number", i); + hal_device_copy_property(parent, "info.product", device, "info.product"); + hal_device_copy_property(parent, "info.vendor", device, "info.vendor"); + hal_device_merge_with_rewrite(device, parent, "usb.", "usb_device."); + + if (hf_device_preprobe(device)) { + const char *driver, *devname; + + hf_runner_run_sync(device, 0, "hald-probe-usb2-interface", NULL); + + devname = hal_device_property_get_string(device, + "usb.freebsd.devname"); + if (devname) + hf_devtree_device_set_name(device, devname); + + driver = hal_device_property_get_string(device, "freebsd.driver"); + if (driver) { + if (!strcmp(driver, "ukbd")) + hf_device_set_input(device, "keyboard", "keys", NULL); + else if (!strcmp(driver, "ums") || !strcmp(driver, "atp")) { + hf_device_set_input(device, "mouse", NULL, devname); + hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL); + } else if (!strcmp(driver, "uhid")) { + hal_device_property_set_string(device, "info.category", + "hiddev"); + hal_device_add_capability(device, "hiddev"); + hf_device_property_set_string_printf(device, "hiddev.device", + "/dev/%s", devname); + hal_device_copy_property(device, "info.product", device, + "hiddev.product"); + hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL); + } else if (!strcmp(driver, "ldev")) { + /* Linux driver (webcam) */ + + /* + * XXX This is a hack. Currently, all ldev devices are + * webcams. That may not always be the case. Hopefully, + * when other Linux driver support is added, there will be + * a sysctl or some other way to determine device class. + */ + hf_usb_add_webcam_properties(device); + } else if (!strcmp(driver, "pwc")) { + /* Phillips Web Cam */ + hf_usb_add_webcam_properties(device); + } + } else { + /* Try and detect webcamd devices. */ + hf_runner_run_sync(device, 0, "hald-probe-video4linux", NULL); + } + + hf_usb_device_compute_udi(device); + hf_device_add(device); + } + } } static void -hf_usb2_probe_interfaces(HalDevice *parent) +hf_usb2_probe_device(HalDevice * parent, int bus, int addr) { - int num_interfaces; - int i; + HalDevice *device; - g_return_if_fail(HAL_IS_DEVICE(parent)); + g_return_if_fail(HAL_IS_DEVICE(parent)); - if (hal_device_property_get_bool(parent, "info.ignore")) - return; + device = hf_device_new(parent); - num_interfaces = hal_device_property_get_int(parent, - "usb_device.num_interfaces"); - - for (i = 0; i < num_interfaces; i++) - { - HalDevice *device; - - device = hf_device_new(parent); - - hal_device_property_set_string(device, "info.subsystem", "usb"); - hal_device_property_set_int(device, "usb.interface.number", i); - hal_device_property_foreach(parent, hf_usb2_copy_parent, device); - hal_device_copy_property(parent, "info.product", device, "info.product"); - hal_device_copy_property(parent, "info.vendor", device, "info.vendor"); - - if (hf_device_preprobe(device)) - { - const char *driver, *devname; - - hf_runner_run_sync(device, 0, "hald-probe-usb2-interface", NULL); - - devname = hal_device_property_get_string(device, - "usb.freebsd.devname"); - if (devname) - hf_devtree_device_set_name(device, devname); - - driver = hal_device_property_get_string(device, "freebsd.driver"); - if (driver) - { - if (! strcmp(driver, "ukbd")) - hf_device_set_input(device, "keyboard", NULL); - else if (! strcmp(driver, "ums")) - { - hf_device_set_input(device, "mouse", devname); - hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL); - } - else if (! strcmp(driver, "uhid")) - { - hal_device_property_set_string(device, "info.category", - "hiddev"); - hal_device_add_capability(device, "hiddev"); - hf_device_property_set_string_printf(device, "hiddev.device", - "/dev/%s", devname); - hal_device_copy_property(device, "info.product", device, - "hiddev.product"); - hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL); - } - else if (! strcmp(driver, "ldev")) - { - /* Linux driver (webcam) */ - - /* - * XXX This is a hack. Currently, all ldev devices are - * webcams. That may not always be the case. Hopefully, - * when other Linux driver support is added, there will be - * a sysctl or some other way to determine device class. - */ - hf_usb_add_webcam_properties(device); - } - else if (! strcmp(driver, "pwc")) - { - /* Phillips Web Cam */ - hf_usb_add_webcam_properties(device); - } - } + hal_device_property_set_string(device, "info.subsystem", "usb_device"); + hal_device_property_set_int(device, "usb_device.bus_number", bus); + hal_device_property_set_int(device, "usb_device.level_number", 1); + hal_device_property_set_int(device, "usb_device.port_number", addr); - hf_usb_device_compute_udi(device); - hf_device_add(device); + if (hf_device_preprobe(device)) { + hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL); + hf_usb_device_compute_udi(device); + hf_device_add(device); + hf_usb2_probe_interfaces(device); } - } } static void -hf_usb2_probe_device (HalDevice *parent, int bus, int addr) +hf_usb2_privileged_init(void) { - HalDevice *device; - - g_return_if_fail(HAL_IS_DEVICE(parent)); - - device = hf_device_new(parent); + hf_usb2_be = libusb20_be_alloc_default(); + if (hf_usb2_be == NULL) + HAL_INFO(("unable to open USB backend: %s", g_strerror(errno))); +} - hal_device_property_set_string(device, "info.subsystem", "usb_device"); - hal_device_property_set_int(device, "usb_device.bus_number", bus); - hal_device_property_set_int(device, "usb_device.level_number", addr - 1); - hal_device_property_set_int(device, "usb_device.port_number", addr); +static void +hf_usb2_new_device(int bus, int addr) +{ + HalDevice *parent; - if (hf_device_preprobe(device)) - { - hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL); - hf_usb_device_compute_udi(device); + parent = hf_devtree_find_from_info(hald_get_gdl(), "usbus", bus); - hf_device_add(device); - } - else - return; + if (!parent || hal_device_property_get_bool(parent, "info.ignore")) + return; - hf_usb2_probe_interfaces(device); + hf_usb2_probe_device(parent, bus, addr); } static void -hf_usb2_privileged_init (void) +hf_usb2_probe(void) { - hf_usb2_be = libusb20_be_alloc_default(); - if (hf_usb2_be == NULL) - HAL_INFO(("unable to open USB backend: %s", g_strerror(errno))); -} + struct libusb20_device *pdev = NULL; -static void -hf_usb2_probe (void) -{ - struct libusb20_device *pdev = NULL; + if (hf_usb2_be == NULL) + return; - if (hf_usb2_be == NULL) - return; + while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev))) { + hf_usb2_new_device(libusb20_dev_get_bus_number(pdev), + libusb20_dev_get_address(pdev)); + } - while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev))) - { - HalDevice *parent; - int bus, addr; - - bus = libusb20_dev_get_bus_number(pdev); - addr = libusb20_dev_get_address(pdev); - - if (addr == 1) - parent = hf_devtree_find_parent_from_info(hald_get_gdl(), "usbus", bus); - else - parent = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number", - HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number", - HAL_PROPERTY_TYPE_INT32, addr - 1, NULL); - if (! parent || hal_device_property_get_bool(parent, "info.ignore")) - continue; + libusb20_be_free(hf_usb2_be); + hf_usb2_be = NULL; +} - hf_usb2_probe_device(parent, bus, addr); - } +static gboolean +hf_usb2_devd_notify(const char *system, + const char *subsystem, + const char *type, + const char *data) +{ + const char *ugen; + int bus; + int addr; + + if (!data || strcmp(system, "USB") || strcmp(subsystem, "DEVICE") || + (strcmp(type, "ATTACH") && strcmp(type, "DETACH"))) + return FALSE; + + ugen = strstr(data, "ugen="); + if (ugen == NULL) { + /* + * The following case is not required in + * FreeBSD 8-stable and newer: + */ + ugen = strstr(data, "cdev="); + if (ugen == NULL) + return FALSE; + + if (sscanf(ugen, "cdev=ugen%i.%i", &bus, &addr) != 2) + return FALSE; + } else { + if (sscanf(ugen, "ugen=ugen%i.%i", &bus, &addr) != 2) + return FALSE; + } - libusb20_be_free(hf_usb2_be); - hf_usb2_be = NULL; -} + if (strcmp(type, "ATTACH") == 0) { -static gboolean -hf_usb2_devd_add (const char *name, - GHashTable *params, - GHashTable *at, - const char *parent) -{ - HalDevice *parent_device; - int bus, addr, pbus, paddr; + HAL_INFO(("received devd attach event, device %s", data)); - if (strncmp(name, "ugen", strlen("ugen"))) - return FALSE; - else if (strncmp(parent, "ugen", strlen("ugen"))) - return TRUE; - - if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2) - return FALSE; - - if (sscanf(parent, "ugen%i.%i", &pbus, &paddr) != 2) - return FALSE; - - HAL_INFO(("received devd add event for device '%s' with parent '%s'", - name, parent)); - - parent_device = hf_device_store_match(hald_get_gdl(), - "usb_device.bus_number", HAL_PROPERTY_TYPE_INT32, pbus, - "usb_device.port_number", HAL_PROPERTY_TYPE_INT32, paddr, NULL); - - if (parent_device && ! hal_device_property_get_bool(parent_device, - "info.ignore")) - { - hf_usb2_probe_device(parent_device, bus, addr); - return TRUE; - } + hf_usb2_new_device(bus, addr); + } + if (strcmp(type, "DETACH") == 0) { - return FALSE; -} + HalDevice *device; -static gboolean -hf_usb2_devd_remove (const char *name, - GHashTable *params, - GHashTable *at, - const char *parent) -{ - HalDevice *device; - int bus, addr; + HAL_INFO(("received devd detach event, device %s", data)); - if (strncmp(name, "ugen", strlen("ugen"))) - return FALSE; - else if (strncmp(parent, "ugen", strlen("ugen"))) - return TRUE; - - if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2) - return FALSE; - - HAL_INFO(("received devd remove event, device %s", name)); - - device = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number", - HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number", - HAL_PROPERTY_TYPE_INT32, addr, NULL); - - if (device) - { - hf_device_remove_tree(device); - return TRUE; - } + device = hf_device_store_match(hald_get_gdl(), + "usb_device.bus_number", HAL_PROPERTY_TYPE_INT32, bus, + "usb_device.port_number", HAL_PROPERTY_TYPE_INT32, addr, + "info.bus", HAL_PROPERTY_TYPE_STRING, "usb_device", NULL); - return FALSE; + if (device) + hf_device_remove_tree(device); + } + return TRUE; } HFHandler hf_usb2_handler = { - .privileged_init = hf_usb2_privileged_init, - .probe = hf_usb2_probe + .privileged_init = hf_usb2_privileged_init, + .probe = hf_usb2_probe }; HFDevdHandler hf_usb2_devd_handler = { - .add = hf_usb2_devd_add, - .remove = hf_usb2_devd_remove + .notify = hf_usb2_devd_notify };