1
/***************************************************************************
4
* hf-usb.c : USB support
6
* Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
**************************************************************************/
34
#include "../logger.h"
35
#include "../osspec.h"
39
#include "hf-devtree.h"
42
static struct libusb20_backend *hf_usb2_be = NULL;
45
hf_usb2_copy_parent (HalDevice *parent,
51
g_return_if_fail(HAL_IS_DEVICE(parent));
52
g_return_if_fail(HAL_IS_DEVICE(user_data));
54
device = HAL_DEVICE(user_data);
56
if (! strncmp(key, "usb_device.", strlen("usb_device.")))
57
hal_device_copy_property(parent, key, device, key);
61
hf_usb2_probe_interfaces(HalDevice *parent)
66
g_return_if_fail(HAL_IS_DEVICE(parent));
68
if (hal_device_property_get_bool(parent, "info.ignore"))
71
num_interfaces = hal_device_property_get_int(parent,
72
"usb_device.num_interfaces");
74
for (i = 0; i < num_interfaces; i++)
78
device = hf_device_new(parent);
80
hal_device_property_set_string(device, "info.subsystem", "usb");
81
hal_device_property_set_int(device, "usb.interface.number", i);
82
hal_device_property_foreach(parent, hf_usb2_copy_parent, device);
83
hal_device_copy_property(parent, "info.product", device, "info.product");
84
hal_device_copy_property(parent, "info.vendor", device, "info.vendor");
86
if (hf_device_preprobe(device))
88
const char *driver, *devname;
90
hf_runner_run_sync(device, 0, "hald-probe-usb2-interface", NULL);
92
devname = hal_device_property_get_string(device,
93
"usb.freebsd.devname");
95
hf_devtree_device_set_name(device, devname);
97
driver = hal_device_property_get_string(device, "freebsd.driver");
100
if (! strcmp(driver, "ukbd"))
101
hf_device_set_input(device, "keyboard", NULL);
102
else if (! strcmp(driver, "ums"))
104
hf_device_set_input(device, "mouse", devname);
105
hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
107
else if (! strcmp(driver, "uhid"))
109
hal_device_property_set_string(device, "info.category",
111
hal_device_add_capability(device, "hiddev");
112
hf_device_property_set_string_printf(device, "hiddev.device",
114
hal_device_copy_property(device, "info.product", device,
116
hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL);
118
else if (! strcmp(driver, "ldev"))
120
/* Linux driver (webcam) */
123
* XXX This is a hack. Currently, all ldev devices are
124
* webcams. That may not always be the case. Hopefully,
125
* when other Linux driver support is added, there will be
126
* a sysctl or some other way to determine device class.
128
hf_usb_add_webcam_properties(device);
130
else if (! strcmp(driver, "pwc"))
132
/* Phillips Web Cam */
133
hf_usb_add_webcam_properties(device);
137
hf_usb_device_compute_udi(device);
138
hf_device_add(device);
144
hf_usb2_probe_device (HalDevice *parent, int bus, int addr)
148
g_return_if_fail(HAL_IS_DEVICE(parent));
150
device = hf_device_new(parent);
152
hal_device_property_set_string(device, "info.subsystem", "usb_device");
153
hal_device_property_set_int(device, "usb_device.bus_number", bus);
154
hal_device_property_set_int(device, "usb_device.level_number", addr - 1);
155
hal_device_property_set_int(device, "usb_device.port_number", addr);
157
if (hf_device_preprobe(device))
159
hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL);
160
hf_usb_device_compute_udi(device);
162
hf_device_add(device);
167
hf_usb2_probe_interfaces(device);
171
hf_usb2_privileged_init (void)
173
hf_usb2_be = libusb20_be_alloc_default();
174
if (hf_usb2_be == NULL)
175
HAL_INFO(("unable to open USB backend: %s", g_strerror(errno)));
181
struct libusb20_device *pdev = NULL;
183
if (hf_usb2_be == NULL)
186
while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev)))
191
bus = libusb20_dev_get_bus_number(pdev);
192
addr = libusb20_dev_get_address(pdev);
195
parent = hf_devtree_find_parent_from_info(hald_get_gdl(), "usbus", bus);
197
parent = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number",
198
HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number",
199
HAL_PROPERTY_TYPE_INT32, addr - 1, NULL);
200
if (! parent || hal_device_property_get_bool(parent, "info.ignore"))
203
hf_usb2_probe_device(parent, bus, addr);
206
libusb20_be_free(hf_usb2_be);
211
hf_usb2_devd_add (const char *name,
216
HalDevice *parent_device;
217
int bus, addr, pbus, paddr;
219
if (strncmp(name, "ugen", strlen("ugen")))
221
else if (strncmp(parent, "ugen", strlen("ugen")))
224
if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2)
227
if (sscanf(parent, "ugen%i.%i", &pbus, &paddr) != 2)
230
HAL_INFO(("received devd add event for device '%s' with parent '%s'",
233
parent_device = hf_device_store_match(hald_get_gdl(),
234
"usb_device.bus_number", HAL_PROPERTY_TYPE_INT32, pbus,
235
"usb_device.port_number", HAL_PROPERTY_TYPE_INT32, paddr, NULL);
237
if (parent_device && ! hal_device_property_get_bool(parent_device,
240
hf_usb2_probe_device(parent_device, bus, addr);
248
hf_usb2_devd_remove (const char *name,
256
if (strncmp(name, "ugen", strlen("ugen")))
258
else if (strncmp(parent, "ugen", strlen("ugen")))
261
if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2)
264
HAL_INFO(("received devd remove event, device %s", name));
266
device = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number",
267
HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number",
268
HAL_PROPERTY_TYPE_INT32, addr, NULL);
272
hf_device_remove_tree(device);
279
HFHandler hf_usb2_handler = {
280
.privileged_init = hf_usb2_privileged_init,
281
.probe = hf_usb2_probe
284
HFDevdHandler hf_usb2_devd_handler = {
285
.add = hf_usb2_devd_add,
286
.remove = hf_usb2_devd_remove