~ubuntu-branches/ubuntu/lucid/hal/lucid-proposed

« back to all changes in this revision

Viewing changes to hald/freebsd/hf-usb2.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-12-03 01:21:24 UTC
  • mto: (1.1.18 squeeze)
  • mto: This revision was merged to the branch mainline in revision 165.
  • Revision ID: james.westby@ubuntu.com-20091203012124-3573qknop973uvc2
Tags: upstream-0.5.14
ImportĀ upstreamĀ versionĀ 0.5.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 * CVSID: $Id$
 
3
 *
 
4
 * hf-usb.c : USB support
 
5
 *
 
6
 * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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
 
21
 *
 
22
 **************************************************************************/
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#  include <config.h>
 
26
#endif
 
27
 
 
28
#include <string.h>
 
29
#include <errno.h>
 
30
#include <stdlib.h>
 
31
#include <unistd.h>
 
32
#include <libusb20.h>
 
33
 
 
34
#include "../logger.h"
 
35
#include "../osspec.h"
 
36
 
 
37
#include "hf-usb.h"
 
38
#include "hf-usb2.h"
 
39
#include "hf-devtree.h"
 
40
#include "hf-util.h"
 
41
 
 
42
static struct libusb20_backend *hf_usb2_be = NULL;
 
43
 
 
44
static void
 
45
hf_usb2_copy_parent (HalDevice *parent,
 
46
                     const char *key,
 
47
                     gpointer user_data)
 
48
{
 
49
  HalDevice *device;
 
50
 
 
51
  g_return_if_fail(HAL_IS_DEVICE(parent));
 
52
  g_return_if_fail(HAL_IS_DEVICE(user_data));
 
53
 
 
54
  device = HAL_DEVICE(user_data);
 
55
 
 
56
  if (! strncmp(key, "usb_device.", strlen("usb_device.")))
 
57
    hal_device_copy_property(parent, key, device, key);
 
58
}
 
59
 
 
60
static void
 
61
hf_usb2_probe_interfaces(HalDevice *parent)
 
62
{
 
63
  int num_interfaces;
 
64
  int i;
 
65
 
 
66
  g_return_if_fail(HAL_IS_DEVICE(parent));
 
67
 
 
68
  if (hal_device_property_get_bool(parent, "info.ignore"))
 
69
    return;
 
70
 
 
71
  num_interfaces = hal_device_property_get_int(parent,
 
72
    "usb_device.num_interfaces");
 
73
 
 
74
  for (i = 0; i < num_interfaces; i++)
 
75
    {
 
76
      HalDevice *device;
 
77
 
 
78
      device = hf_device_new(parent);
 
79
 
 
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");
 
85
 
 
86
      if (hf_device_preprobe(device))
 
87
        {
 
88
          const char *driver, *devname;
 
89
 
 
90
          hf_runner_run_sync(device, 0, "hald-probe-usb2-interface", NULL);
 
91
 
 
92
          devname = hal_device_property_get_string(device,
 
93
            "usb.freebsd.devname");
 
94
          if (devname)
 
95
            hf_devtree_device_set_name(device, devname);
 
96
 
 
97
          driver = hal_device_property_get_string(device, "freebsd.driver");
 
98
          if (driver)
 
99
            {
 
100
              if (! strcmp(driver, "ukbd"))
 
101
                hf_device_set_input(device, "keyboard", NULL);
 
102
              else if (! strcmp(driver, "ums"))
 
103
                {
 
104
                  hf_device_set_input(device, "mouse", devname);
 
105
                  hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL);
 
106
                }
 
107
              else if (! strcmp(driver, "uhid"))
 
108
                {
 
109
                  hal_device_property_set_string(device, "info.category",
 
110
                    "hiddev");
 
111
                  hal_device_add_capability(device, "hiddev");
 
112
                  hf_device_property_set_string_printf(device, "hiddev.device",
 
113
                    "/dev/%s", devname);
 
114
                  hal_device_copy_property(device, "info.product", device,
 
115
                    "hiddev.product");
 
116
                  hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL);
 
117
                }
 
118
              else if (! strcmp(driver, "ldev"))
 
119
                {
 
120
                  /* Linux driver (webcam) */
 
121
 
 
122
                  /*
 
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.
 
127
                   */
 
128
                  hf_usb_add_webcam_properties(device);
 
129
                }
 
130
              else if (! strcmp(driver, "pwc"))
 
131
                {
 
132
                  /* Phillips Web Cam */
 
133
                  hf_usb_add_webcam_properties(device);
 
134
                }
 
135
            }
 
136
 
 
137
          hf_usb_device_compute_udi(device);
 
138
          hf_device_add(device);
 
139
        }
 
140
    }
 
141
}
 
142
 
 
143
static void
 
144
hf_usb2_probe_device (HalDevice *parent, int bus, int addr)
 
145
{
 
146
  HalDevice *device;
 
147
 
 
148
  g_return_if_fail(HAL_IS_DEVICE(parent));
 
149
 
 
150
  device = hf_device_new(parent);
 
151
 
 
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);
 
156
 
 
157
  if (hf_device_preprobe(device))
 
158
    {
 
159
      hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL);
 
160
      hf_usb_device_compute_udi(device);
 
161
 
 
162
      hf_device_add(device);
 
163
    }
 
164
  else
 
165
    return;
 
166
 
 
167
  hf_usb2_probe_interfaces(device);
 
168
}
 
169
 
 
170
static void
 
171
hf_usb2_privileged_init (void)
 
172
{
 
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)));
 
176
}
 
177
 
 
178
static void
 
179
hf_usb2_probe (void)
 
180
{
 
181
  struct libusb20_device *pdev = NULL;
 
182
 
 
183
  if (hf_usb2_be == NULL)
 
184
    return;
 
185
 
 
186
  while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev)))
 
187
    {
 
188
      HalDevice *parent;
 
189
      int bus, addr;
 
190
 
 
191
      bus = libusb20_dev_get_bus_number(pdev);
 
192
      addr = libusb20_dev_get_address(pdev);
 
193
 
 
194
      if (addr == 1)
 
195
        parent = hf_devtree_find_parent_from_info(hald_get_gdl(), "usbus", bus);
 
196
      else
 
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"))
 
201
        continue;
 
202
 
 
203
      hf_usb2_probe_device(parent, bus, addr);
 
204
    }
 
205
 
 
206
  libusb20_be_free(hf_usb2_be);
 
207
  hf_usb2_be = NULL;
 
208
}
 
209
 
 
210
static gboolean
 
211
hf_usb2_devd_add (const char *name,
 
212
                  GHashTable *params,
 
213
                  GHashTable *at,
 
214
                  const char *parent)
 
215
{
 
216
  HalDevice *parent_device;
 
217
  int bus, addr, pbus, paddr;
 
218
 
 
219
  if (strncmp(name, "ugen", strlen("ugen")))
 
220
    return FALSE;
 
221
  else if (strncmp(parent, "ugen", strlen("ugen")))
 
222
    return TRUE;
 
223
 
 
224
  if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2)
 
225
    return FALSE;
 
226
 
 
227
  if (sscanf(parent, "ugen%i.%i", &pbus, &paddr) != 2)
 
228
    return FALSE;
 
229
 
 
230
  HAL_INFO(("received devd add event for device '%s' with parent '%s'",
 
231
           name, parent));
 
232
 
 
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);
 
236
 
 
237
  if (parent_device && ! hal_device_property_get_bool(parent_device,
 
238
      "info.ignore"))
 
239
    {
 
240
      hf_usb2_probe_device(parent_device, bus, addr);
 
241
      return TRUE;
 
242
    }
 
243
 
 
244
  return FALSE;
 
245
}
 
246
 
 
247
static gboolean
 
248
hf_usb2_devd_remove (const char *name,
 
249
                     GHashTable *params,
 
250
                     GHashTable *at,
 
251
                     const char *parent)
 
252
{
 
253
  HalDevice *device;
 
254
  int bus, addr;
 
255
 
 
256
  if (strncmp(name, "ugen", strlen("ugen")))
 
257
    return FALSE;
 
258
  else if (strncmp(parent, "ugen", strlen("ugen")))
 
259
    return TRUE;
 
260
 
 
261
  if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2)
 
262
    return FALSE;
 
263
 
 
264
  HAL_INFO(("received devd remove event, device %s", name));
 
265
 
 
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);
 
269
 
 
270
  if (device)
 
271
    {
 
272
      hf_device_remove_tree(device);
 
273
      return TRUE;
 
274
    }
 
275
 
 
276
  return FALSE;
 
277
}
 
278
 
 
279
HFHandler hf_usb2_handler = {
 
280
  .privileged_init      = hf_usb2_privileged_init,
 
281
  .probe                = hf_usb2_probe
 
282
};
 
283
 
 
284
HFDevdHandler hf_usb2_devd_handler = {
 
285
  .add =        hf_usb2_devd_add,
 
286
  .remove =     hf_usb2_devd_remove
 
287
};