USB Device Add reading wrong attributes on Linux
Drew Moseley
dmoseley at mvista.com
Wed Dec 3 13:04:31 PST 2008
Kay Sievers wrote:
> On Wed, Dec 3, 2008 at 18:21, Drew Moseley <dmoseley at mvista.com> wrote:
>> I've noticed a case with a USB device on a linux host where some of the
>> attributes are not being properly initialized. Specifically the
>> can_wake_up and is_self_powered fields are incorrect because when HAL
>> reads the bmAttributes sysfs file it gets a read error. A restart of
>> hal usually brings the correct values in.
>>
>> In the kernel code for the USB sysfs files there is a comment that
>> "Unforunately these attributes cannot be created before the uevent is
>> broadcast". I do see in the kernel where the sysfs file is being read
>> by HAL but getting an error. Has anyone else dealt with this? Should
>> there be a retry of some kind in HAL to handle this?
>
> Yeah, that's a known issue. Things like this can not work without
> tight integration with the kernel, which must send an update event for
> every change. This is just not implemented, not in the kernel and not
> in HAL. Retry implemented in HAL would only help in some cases.
>
> To make it kind of work, all these values could be updated when the
> child devices are created/removed. This would fix a bunch of different
> bugs in this area, like when a device is reconfigured, and HAL will
> not notice it, and exports the wrong values from the initial config.
> In most cases when child devices come and go, the parent device has,
> at that time, all values properly populated. So, per example, "usb
> interface" events could trigger an update of the "usb device" values.
>
> Btw, It was a mistake to mirror any such kernel values in a daemon, we
> didn't know that the time HAL was created. It's really hard to get
> things like this right, and the pseudo "platform abstraction" at that
> fine-grained level just doesn't work in reality. DeviceKit, which will
> replace HAL, will not even try that. It will just use sysfs directly
> on Linux, without any such caching behavior like HAL has.
>
> Thanks,
> Kay
Thanks for the description. I think I will just add a retry to handle
the particular issue I am seeing. The patch is below in case anyone
cares.
Regards,
Drew
diff --git a/hald/linux/device.c b/hald/linux/device.c
index d16ac3a..fb5439f 100644
--- a/hald/linux/device.c
+++ b/hald/linux/device.c
@@ -3584,7 +3584,7 @@ usb_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_de
/* only USB interfaces got a : in the bus_id */
bus_id = hal_util_get_last_element (sysfs_path);
if (strchr (bus_id, ':') == NULL) {
- gint bmAttributes;
+ gint bmAttributes, retries;
hal_device_property_set_string (d, "info.subsystem", "usb_device");
@@ -3592,6 +3592,19 @@ usb_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_de
hal_device_property_set_string (d, "usb_device.linux.sysfs_path", sysfs_path);
+ /*
+ * Delay until the attributes field is set
+ */
+ for (retries = 0; retries < 3; retries++) {
+ int num_ms;
+ if (hal_util_get_int_from_file (sysfs_path, "bmAttributes", &bmAttributes, 16))
+ break;
+ num_ms = 10 * (1<<retries);
+ HAL_INFO (("spinning %d ms waiting for bmAttributes file for sysfs path %s",
+ num_ms, sysfs_path));
+ usleep (1000 * num_ms);
+ }
+
hal_util_set_string_from_file(d, "usb_device.configuration", sysfs_path, "configuration");
hal_util_set_int_from_file (d, "usb_device.configuration_value", sysfs_path, "bConfigurationValue", 10);
hal_util_set_int_from_file (d, "usb_device.num_configurations", sysfs_path, "bNumConfigurations", 10);
More information about the hal
mailing list