diff --git a/fdi/policy/10osvendor/10-macbookpro-utils.fdi b/fdi/policy/10osvendor/10-macbookpro-utils.fdi index a6cd78e..60882a2 100644 --- a/fdi/policy/10osvendor/10-macbookpro-utils.fdi +++ b/fdi/policy/10osvendor/10-macbookpro-utils.fdi @@ -6,9 +6,11 @@ <device> <match key="system.kernel.name" string="Linux"> <match key="system.hardware.vendor" contains="Apple"> - <match key="system.hardware.product" string_outof="MacBookPro1,1;MacBookPro1,2;MacBookPro2,1;MacBookPro2,2;MacBookPro3,1"> + <match key="system.hardware.product" string_outof="MacBookPro1,1;MacBookPro1,2;MacBookPro2,1;MacBookPro2,2;MacBookPro3,1;MacBookPro3,2;MacBookPro4,1"> <spawn udi="/org/freedesktop/Hal/devices/macbook_pro_light_sensor"/> <spawn udi="/org/freedesktop/Hal/devices/macbook_pro_keyboard_backlight"/> + </match> + <match key="system.hardware.product" string_outof="MacBookPro1,1;MacBookPro1,2;MacBookPro2,1;MacBookPro2,2"> <spawn udi="/org/freedesktop/Hal/devices/macbook_pro_lcd_panel"/> </match> </match> diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c index 819ab9c..6889275 100644 --- a/hald/hald_dbus.c +++ b/hald/hald_dbus.c @@ -4679,7 +4679,7 @@ do_introspect (DBusConnection *connection, const char *name; const char *sig; const char *argnames; - char **args; + gchar **args; unsigned int n; unsigned int m; @@ -4722,6 +4722,7 @@ do_introspect (DBusConnection *connection, xml, " </method>\n"); + g_strfreev(args); } diff --git a/hald/linux/addons/addon-acpi.c b/hald/linux/addons/addon-acpi.c index ea4ad30..fb4847d 100644 --- a/hald/linux/addons/addon-acpi.c +++ b/hald/linux/addons/addon-acpi.c @@ -143,11 +143,17 @@ handle_ibm_acpi_events (LibHalContext *ctx, int type, int event) button = "Fn+Backspace"; break; case 4110: /* Fn+Insert*/ - button = "Fn=Insert"; + button = "Fn+Insert"; break; case 4111: /* Fn+Delete*/ button = "Fn+Delete"; break; + case 4116: /* Fn+Space */ + button = "zoom"; + break; + case 4120: /* ThinkPad */ + button = "ThinkPad"; + break; case 20489: /* Tablet rotated */ button = "tabletpc_rotate_180"; break; diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c index 18eae78..1d10131 100644 --- a/hald/linux/coldplug.c +++ b/hald/linux/coldplug.c @@ -56,7 +56,7 @@ static GHashTable *sysfs_to_udev_map; static GSList *device_list; static char dev_root[HAL_PATH_MAX]; static gchar *udevinfo_stdout = NULL; - +static unsigned long long coldplug_seqnum = 0; typedef struct _UdevInfo UdevInfo; struct _UdevInfo @@ -309,6 +309,8 @@ no_node: hotplug_event->action = HOTPLUG_ACTION_ADD; hotplug_event->type = type; hotplug_event->sysfs.net_ifindex = -1; + /*emulate sequence numbers for coldplug events*/ + hotplug_event->sysfs.seqnum = coldplug_seqnum++; return hotplug_event; } diff --git a/hald/linux/device.c b/hald/linux/device.c index e48548e..72bff9c 100644 --- a/hald/linux/device.c +++ b/hald/linux/device.c @@ -45,6 +45,10 @@ #include <linux/input.h> #endif +/* for wireless extensions */ +#include <linux/if.h> +#include <linux/wireless.h> + #include <dbus/dbus.h> #include <dbus/dbus-glib.h> @@ -89,7 +93,7 @@ static int input_str_to_bitmask (const char *s, long *bitmask, size_t max_size) { int i, j; - char **v; + gchar **v; int num_bits_set = 0; memset (bitmask, 0, max_size); @@ -105,6 +109,7 @@ input_str_to_bitmask (const char *s, long *bitmask, size_t max_size) val &= (val - 1); } } + g_strfreev(v); return num_bits_set; } @@ -532,10 +537,14 @@ net_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_de const char *addr; const char *parent_subsys; char bridge_path[HAL_PATH_MAX]; - char wireless_path[HAL_PATH_MAX]; - char wiphy_path[HAL_PATH_MAX]; + char phy80211_path[HAL_PATH_MAX]; struct stat s; dbus_uint64_t mac_address = 0; + int ioctl_fd; + struct iwreq iwr; + + ioctl_fd = socket (PF_INET, SOCK_DGRAM, 0); + strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ); addr = hal_device_property_get_string (d, "net.address"); if (addr != NULL) { @@ -554,9 +563,8 @@ net_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_de } snprintf (bridge_path, HAL_PATH_MAX, "%s/bridge", sysfs_path); - snprintf (wireless_path, HAL_PATH_MAX, "%s/wireless", sysfs_path); - /* wireless dscape stack e.g. from rt2500pci driver*/ - snprintf (wiphy_path, HAL_PATH_MAX, "%s/wiphy", sysfs_path); + /* cfg80211 */ + snprintf (phy80211_path, HAL_PATH_MAX, "%s/phy80211", sysfs_path); parent_subsys = hal_device_property_get_string (parent_dev, "info.subsystem"); if (parent_subsys && strcmp(parent_subsys, "bluetooth") == 0) { @@ -564,8 +572,8 @@ net_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_de hal_device_property_set_string (d, "info.category", "net.bluetooth"); hal_device_add_capability (d, "net.bluetooth"); hal_device_property_set_uint64 (d, "net.bluetooth.mac_address", mac_address); - } else if ((stat (wireless_path, &s) == 0 && (s.st_mode & S_IFDIR)) || - (stat (wiphy_path, &s) == 0 && (s.st_mode & S_IFDIR))) { + } else if ((ioctl (ioctl_fd, SIOCGIWNAME, &iwr) == 0) || + (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) { hal_device_property_set_string (d, "info.product", "WLAN Interface"); hal_device_property_set_string (d, "info.category", "net.80211"); hal_device_add_capability (d, "net.80211"); @@ -581,6 +589,8 @@ net_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_de hal_device_add_capability (d, "net.80203"); hal_device_property_set_uint64 (d, "net.80203.mac_address", mac_address); } + + close (ioctl_fd); } else if (media_type == ARPHRD_IRDA) { hal_device_property_set_string (d, "info.product", "Networking Interface"); hal_device_property_set_string (d, "info.category", "net.irda"); @@ -3698,6 +3708,7 @@ vmbus_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_ const gchar *bus_id; const gchar *class_id; const gchar *device_id; + int busnum, devicenum; HAL_INFO (("vmbus_add: sysfs_path=%s device_file=%s parent_dev=0x%08x parent_path=%s", sysfs_path, device_file, parent_dev, parent_path)); @@ -3714,6 +3725,11 @@ vmbus_add (const gchar *sysfs_path, const gchar *device_file, HalDevice *parent_ bus_id = hal_util_get_last_element (sysfs_path); hal_device_property_set_string (d, "vmbus.bus_id", bus_id); + if (sscanf (bus_id, "vmbus_%d_%d", &busnum, &devicenum) == 2) { + hal_device_property_set_int (d, "vmbus.bus_number", busnum); + hal_device_property_set_int (d, "vmbus.device_number", devicenum); + } + device_id = hal_util_get_string_from_file (sysfs_path, "device_id"); hal_device_property_set_string (d, "vmbus.device_id", device_id); class_id = hal_util_get_string_from_file (sysfs_path, "class_id"); diff --git a/hald/linux/hotplug.c b/hald/linux/hotplug.c index bb86898..16ec1b4 100644 --- a/hald/linux/hotplug.c +++ b/hald/linux/hotplug.c @@ -50,19 +50,26 @@ #include "hotplug.h" /** Queue of ordered hotplug events */ -static GQueue *hotplug_event_queue; +static GQueue *hotplug_event_queue = NULL; + +/* Flag indicating if the queue should be reprocessed from the start */ +static gboolean hotplug_event_queue_restart = FALSE; /** List of HotplugEvent objects we are currently processing */ -static GSList *hotplug_events_in_progress = NULL; +static GList *hotplug_events_in_progress = NULL; 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); + hotplug_events_in_progress = g_list_remove (hotplug_events_in_progress, hotplug_event); g_slice_free (HotplugEvent, hotplug_event); + + /* An event is removed. So we need to restart from the beginning of the queue + * as some events are ready to run now */ + hotplug_event_queue_restart = TRUE; } void @@ -71,7 +78,7 @@ hotplug_event_reposted (void *end_token) HotplugEvent *hotplug_event = (HotplugEvent *) end_token; hotplug_event->reposted = TRUE; - hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event); + hotplug_events_in_progress = g_list_remove (hotplug_events_in_progress, hotplug_event); } static void @@ -310,7 +317,7 @@ hotplug_event_begin (HotplugEvent *hotplug_event) void hotplug_event_enqueue (HotplugEvent *hotplug_event) { - if (hotplug_event_queue == NULL) + if (G_UNLIKELY (hotplug_event_queue == NULL)) hotplug_event_queue = g_queue_new (); g_queue_push_tail (hotplug_event_queue, hotplug_event); @@ -319,40 +326,130 @@ hotplug_event_enqueue (HotplugEvent *hotplug_event) void hotplug_event_enqueue_at_front (HotplugEvent *hotplug_event) { - if (hotplug_event_queue == NULL) + if (G_UNLIKELY (hotplug_event_queue == NULL)) hotplug_event_queue = g_queue_new (); g_queue_push_head (hotplug_event_queue, hotplug_event); + + /* New event added at the start, restart processing of the queue from the + * start */ + hotplug_event_queue_restart = TRUE; +} + +static gboolean +compare_sysfspath(const char *running, const char *waiting) +{ + int i; + + for (i = 0; i < HAL_PATH_MAX; i++) { + /* identical device event found */ + if (running[i] == '\0' && waiting[i] == '\0') + return TRUE; + + /* parent device event found */ + if (running[i] == '\0' && waiting[i] == '/') + return TRUE; + + /* child device event found */ + if (running[i] == '/' && waiting[i] == '\0') + return TRUE; + + /* no matching event */ + if (running[i] != waiting[i]) + break; + } + + return FALSE; +} + +/* + * Returns TRUE if @eventl depends on @eventr + */ +static gboolean +compare_event (HotplugEvent *eventl, HotplugEvent *eventr) +{ + if (*eventl->sysfs.sysfs_path_old != '\0') + if (strcmp (eventr->sysfs.sysfs_path_old, eventl->sysfs.sysfs_path_old) == 0) + return TRUE; + return compare_sysfspath (eventr->sysfs.sysfs_path, eventl->sysfs.sysfs_path); +} + +/* + * Returns TRUE if @hotplug_event depends on any event in @events + */ +static gboolean +compare_events (HotplugEvent *hotplug_event, GList *events) +{ + GList *lp; + HotplugEvent *loop_event; + + switch (hotplug_event->type) { + + /* explicit fallthrough */ + case HOTPLUG_EVENT_SYSFS: + case HOTPLUG_EVENT_SYSFS_DEVICE: + case HOTPLUG_EVENT_SYSFS_BLOCK: + + for (lp = events; lp; lp = g_list_next (lp)) { + loop_event = (HotplugEvent*) lp->data; + /* skip ourselves and all later events*/ + if (loop_event->sysfs.seqnum >= hotplug_event->sysfs.seqnum) + break; + if (compare_event (hotplug_event, loop_event)) { + HAL_DEBUG (("event %s dependant on %s", hotplug_event->sysfs.sysfs_path, loop_event->sysfs.sysfs_path)); + return TRUE; + } + } + return FALSE; + + default: + return FALSE; + } } + void hotplug_event_process_queue (void) { HotplugEvent *hotplug_event; + GList *lp, *lp2; + static gboolean processing = FALSE; - while (hotplug_events_in_progress != NULL || - (hotplug_event_queue != NULL && - !g_queue_is_empty (hotplug_event_queue))) { - - /* do not process events if some other event is in progress - * - * TODO: optimize so we can do add events in parallel by inspecting the - * wait_for_sysfs_path parameter and hotplug_events_in_progress list - */ - 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; + if (G_UNLIKELY (hotplug_event_queue == NULL)) + return; - hotplug_events_in_progress = g_slist_append (hotplug_events_in_progress, hotplug_event); - hotplug_event_begin (hotplug_event); + if (processing) + return; + + processing = TRUE; + + lp = hotplug_event_queue->head; + while (lp != NULL) { + hotplug_event = lp->data; + HAL_INFO (("checking event %s", hotplug_event->sysfs.sysfs_path)); + if (!compare_events (hotplug_event, hotplug_event_queue->head) + && !compare_events (hotplug_event, hotplug_events_in_progress)) { + lp2 = lp->prev; + g_queue_unlink(hotplug_event_queue, lp); + hotplug_events_in_progress = g_list_concat (hotplug_events_in_progress, lp); + hotplug_event_begin (hotplug_event); + if (lp2 == NULL || hotplug_event_queue_restart) { + lp = hotplug_event_queue->head; + hotplug_event_queue_restart = FALSE; + } else { + lp = g_list_next(lp2); + } + } else { + HAL_DEBUG (("event held back: %s", hotplug_event->sysfs.sysfs_path)); + lp = g_list_next (lp); + } } + HAL_DEBUG (("events queued = %d, events in progress = %d", hotplug_event_queue->length, g_list_length (hotplug_events_in_progress))); + + processing = FALSE; hotplug_queue_now_empty (); -out: - ; + } gboolean diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c index c753735..e91a8aa 100644 --- a/hald/linux/osspec.c +++ b/hald/linux/osspec.c @@ -329,6 +329,7 @@ osspec_privileged_init_preparse_set_dmi (gboolean set, HalDevice *d) gchar *buf; static char *product_serial; static char *product_uuid; + static char *board_serial; static gboolean parsed = FALSE; if (g_file_test (DMI_SYSFS_PATH, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) { @@ -338,12 +339,15 @@ osspec_privileged_init_preparse_set_dmi (gboolean set, HalDevice *d) product_serial = g_strdup ( buf ); if ((buf = hal_util_get_string_from_file(DMI_SYSFS_PATH, "product_uuid")) != NULL) product_uuid = g_strdup ( buf ); + if ((buf = hal_util_get_string_from_file(DMI_SYSFS_PATH, "board_serial")) != NULL) + board_serial = g_strdup ( buf ); parsed = TRUE; } else { if (d != NULL && parsed) { hal_device_property_set_string (d, "system.hardware.serial", product_serial); hal_device_property_set_string (d, "system.hardware.uuid", product_uuid); + hal_device_property_set_string (d, "system.board.serial", board_serial); g_free (product_serial); g_free (product_uuid); parsed = FALSE; @@ -740,6 +744,9 @@ decode_dmi_from_sysfs (HalDevice *d) hal_util_set_string_from_file(d, "system.hardware.product", DMI_SYSFS_PATH, "product_name"); hal_util_set_string_from_file(d, "system.hardware.version", DMI_SYSFS_PATH, "product_version"); hal_util_set_string_from_file(d, "system.chassis.manufacturer", DMI_SYSFS_PATH, "chassis_vendor"); + hal_util_set_string_from_file(d, "system.board.product", DMI_SYSFS_PATH, "board_name"); + hal_util_set_string_from_file(d, "system.board.version", DMI_SYSFS_PATH, "board_version"); + hal_util_set_string_from_file(d, "system.board.vendor", DMI_SYSFS_PATH, "board_vendor"); computer_dmi_map (d, FALSE); computer_probing_helper_done (d); diff --git a/hald/linux/probing/probe-smbios.c b/hald/linux/probing/probe-smbios.c index 6085599..e6556f2 100644 --- a/hald/linux/probing/probe-smbios.c +++ b/hald/linux/probing/probe-smbios.c @@ -45,6 +45,7 @@ #define DMIPARSER_STATE_BIOS 1 #define DMIPARSER_STATE_SYSTEM 2 #define DMIPARSER_STATE_CHASSIS 3 +#define DMIPARSER_STATE_BOARD 4 #define strbegin(buf, str) (strncmp (buf, str, strlen (str)) == 0) @@ -233,6 +234,8 @@ main (int argc, char *argv[]) dmiparser_state = DMIPARSER_STATE_SYSTEM; else if (!dmiparser_done_chassis && strbegin (buf, "Chassis Information")) dmiparser_state = DMIPARSER_STATE_CHASSIS; + else if (!dmiparser_done_chassis && strbegin (buf, "Base Board Information")) + dmiparser_state = DMIPARSER_STATE_BOARD; else /* * We do not match the other sections, @@ -273,6 +276,12 @@ main (int argc, char *argv[]) setstr (nbuf, "Manufacturer:", "system.chassis.manufacturer"); setstr (nbuf, "Type:", "system.chassis.type"); dmiparser_done_chassis = TRUE; + } else if (dmiparser_state == DMIPARSER_STATE_BOARD) { + setstr (nbuf, "Manufacturer:", "system.board.vendor"); + setstr (nbuf, "Product Name:", "system.board.product"); + setstr (nbuf, "Version:", "system.board.version"); + setstr (nbuf, "Serial Number:", "system.board.serial"); + dmiparser_done_system = TRUE; } } diff --git a/partutil/partutil.c b/partutil/partutil.c index 9c2930f..42280af 100644 --- a/partutil/partutil.c +++ b/partutil/partutil.c @@ -21,6 +21,10 @@ * **************************************************************************/ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include <string.h> #include <sys/types.h> #include <unistd.h> @@ -39,10 +43,6 @@ #include "partutil.h" -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #ifdef USE_PARTED #include <parted/parted.h> diff --git a/tools/hal-storage-shared.c b/tools/hal-storage-shared.c index b10be10..422f00e 100644 --- a/tools/hal-storage-shared.c +++ b/tools/hal-storage-shared.c @@ -706,6 +706,8 @@ lock_hal_mtab (void) if (lock_mtab_fd < 0) return FALSE; + fcntl(lock_mtab_fd, F_SETFD, FD_CLOEXEC); + tryagain: #if sun if (lockf (lock_mtab_fd, F_LOCK, 0) != 0) {