118c2aff7Sartem /***************************************************************************
218c2aff7Sartem  *
318c2aff7Sartem  * sysevent.c : Solaris sysevents
418c2aff7Sartem  *
5*112cd14aSqz  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
618c2aff7Sartem  * Use is subject to license terms.
718c2aff7Sartem  *
818c2aff7Sartem  * Licensed under the Academic Free License version 2.1
918c2aff7Sartem  *
1018c2aff7Sartem  **************************************************************************/
1118c2aff7Sartem 
1292f38132Sartem #pragma ident	"%Z%%M%	%I%	%E% SMI"
1318c2aff7Sartem 
1400687e57Sartem #ifdef HAVE_CONFIG_H
1500687e57Sartem #  include <config.h>
1600687e57Sartem #endif
1700687e57Sartem 
1818c2aff7Sartem #include <stdio.h>
1918c2aff7Sartem #include <unistd.h>
2018c2aff7Sartem #include <stdlib.h>
2118c2aff7Sartem #include <string.h>
2218c2aff7Sartem #include <errno.h>
2318c2aff7Sartem #include <fcntl.h>
2418c2aff7Sartem #include <sys/dkio.h>
2518c2aff7Sartem #include <sys/stat.h>
2618c2aff7Sartem #include <libdevinfo.h>
2718c2aff7Sartem #include <libsysevent.h>
2818c2aff7Sartem #include <sys/sysevent/dev.h>
297b840e52Sphitran #include <sys/sysevent/acpiev.h>
3018c2aff7Sartem #include <glib.h>
3118c2aff7Sartem 
3218c2aff7Sartem #include "../osspec.h"
3318c2aff7Sartem #include "../logger.h"
3418c2aff7Sartem #include "../hald.h"
3518c2aff7Sartem #include "../hald_dbus.h"
3618c2aff7Sartem #include "../device_info.h"
3718c2aff7Sartem #include "../util.h"
3818c2aff7Sartem #include "osspec_solaris.h"
3918c2aff7Sartem #include "hotplug.h"
4018c2aff7Sartem #include "devinfo.h"
4118c2aff7Sartem #include "devinfo_storage.h"
427b840e52Sphitran #include "devinfo_acpi.h"
43*112cd14aSqz #include "devinfo_usb.h"
4418c2aff7Sartem #include "sysevent.h"
4518c2aff7Sartem 
4618c2aff7Sartem #ifndef ESC_LOFI
47*112cd14aSqz #define	ESC_LOFI "lofi"
4818c2aff7Sartem #endif
4918c2aff7Sartem 
5018c2aff7Sartem static void	sysevent_dev_handler(sysevent_t *);
5118c2aff7Sartem static gboolean sysevent_iochannel_data(GIOChannel *, GIOCondition, gpointer);
5218c2aff7Sartem static void	sysevent_dev_add(gchar *, gchar *);
5318c2aff7Sartem static void	sysevent_dev_remove(gchar *, gchar *);
5418c2aff7Sartem static void	sysevent_dev_branch(gchar *);
5518c2aff7Sartem static void	sysevent_lofi_add(gchar *, gchar *);
5618c2aff7Sartem static void	sysevent_lofi_remove(gchar *, gchar *);
57*112cd14aSqz static void	sysevent_devfs_add(gchar *);
5818c2aff7Sartem 
5918c2aff7Sartem static sysevent_handle_t	*shp;
6018c2aff7Sartem 
6118c2aff7Sartem static int sysevent_pipe_fds[2];
6218c2aff7Sartem static GIOChannel *sysevent_iochannel;
6318c2aff7Sartem static guint sysevent_source_id;
6418c2aff7Sartem 
6518c2aff7Sartem gboolean
6618c2aff7Sartem sysevent_init(void)
6718c2aff7Sartem {
6818c2aff7Sartem 	GError *err = NULL;
6942a7bdedSjacobs 	const char	*subcl[3];
7018c2aff7Sartem 
71*112cd14aSqz 	/*
7218c2aff7Sartem 	 * pipe used to serialize sysevents through the main loop
73*112cd14aSqz 	 */
74*112cd14aSqz 	if (pipe (sysevent_pipe_fds) != 0) {
75*112cd14aSqz 		HAL_INFO (("pipe() failed errno=%d", errno));
7618c2aff7Sartem 		return (FALSE);
77*112cd14aSqz 	}
78*112cd14aSqz 	sysevent_iochannel = g_io_channel_unix_new (sysevent_pipe_fds[0]);
7918c2aff7Sartem 	if (sysevent_iochannel == NULL) {
80*112cd14aSqz 		HAL_INFO (("g_io_channel_unix_new failed"));
8118c2aff7Sartem 		return (FALSE);
8218c2aff7Sartem 	}
8318c2aff7Sartem 	g_io_channel_set_flags (sysevent_iochannel, G_IO_FLAG_NONBLOCK, &err);
84*112cd14aSqz 	sysevent_source_id = g_io_add_watch (
85*112cd14aSqz 	    sysevent_iochannel, G_IO_IN, sysevent_iochannel_data, NULL);
8618c2aff7Sartem 
8718c2aff7Sartem 	shp = sysevent_bind_handle(sysevent_dev_handler);
8818c2aff7Sartem 	if (shp == NULL) {
8918c2aff7Sartem 		HAL_INFO (("sysevent_bind_handle failed %d", errno));
9018c2aff7Sartem 		return (FALSE);
9118c2aff7Sartem 	}
9218c2aff7Sartem 
9318c2aff7Sartem 	subcl[0] = ESC_DISK;
9418c2aff7Sartem 	subcl[1] = ESC_LOFI;
9542a7bdedSjacobs 	subcl[2] = ESC_PRINTER;
9642a7bdedSjacobs 	if (sysevent_subscribe_event(shp, EC_DEV_ADD, subcl, 3) != 0) {
9718c2aff7Sartem 		HAL_INFO (("subscribe(dev_add) failed %d", errno));
9818c2aff7Sartem 		sysevent_unbind_handle(shp);
9918c2aff7Sartem 		return (FALSE);
10018c2aff7Sartem 	}
10142a7bdedSjacobs 	if (sysevent_subscribe_event(shp, EC_DEV_REMOVE, subcl, 3) != 0) {
10218c2aff7Sartem 		HAL_INFO (("subscribe(dev_remove) failed %d", errno));
10318c2aff7Sartem 		sysevent_unbind_handle(shp);
10418c2aff7Sartem 		return (FALSE);
10518c2aff7Sartem 	}
10618c2aff7Sartem 
10718c2aff7Sartem 	subcl[0] = ESC_DEV_BRANCH_REMOVE;
10818c2aff7Sartem 	if (sysevent_subscribe_event(shp, EC_DEV_BRANCH, subcl, 1) != 0) {
10918c2aff7Sartem 		HAL_INFO (("subscribe(dev_branch) failed %d", errno));
11018c2aff7Sartem 		sysevent_unbind_handle(shp);
11118c2aff7Sartem 		return (FALSE);
11218c2aff7Sartem 	}
11318c2aff7Sartem 
1147b840e52Sphitran 	subcl[0] = ESC_ACPIEV_ADD;
115*112cd14aSqz 	subcl[1] = ESC_ACPIEV_REMOVE;
116*112cd14aSqz 	subcl[2] = ESC_ACPIEV_STATE_CHANGE;
1177b840e52Sphitran 	if (sysevent_subscribe_event(shp, EC_ACPIEV, subcl, 3) != 0) {
118*112cd14aSqz 		HAL_INFO(("subscribe(dev_add) failed %d", errno));
119*112cd14aSqz 		sysevent_unbind_handle(shp);
120*112cd14aSqz 		return (FALSE);
121*112cd14aSqz 	}
122*112cd14aSqz 
123*112cd14aSqz 	subcl[0] = ESC_DEVFS_DEVI_ADD;
124*112cd14aSqz 	if (sysevent_subscribe_event(shp, EC_DEVFS, subcl, 1) != 0) {
125*112cd14aSqz 		HAL_INFO (("subscribe(EC_DEVFS) failed %d", errno));
126*112cd14aSqz 		sysevent_unbind_handle(shp);
127*112cd14aSqz 		return (FALSE);
128*112cd14aSqz 	}
1297b840e52Sphitran 
13018c2aff7Sartem 	return (B_TRUE);
13118c2aff7Sartem }
13218c2aff7Sartem 
13318c2aff7Sartem void
13418c2aff7Sartem sysevent_fini(void)
13518c2aff7Sartem {
13618c2aff7Sartem 	sysevent_unbind_handle(shp);
13718c2aff7Sartem 	shp = NULL;
13818c2aff7Sartem }
13918c2aff7Sartem 
14018c2aff7Sartem static void
14118c2aff7Sartem sysevent_dev_handler(sysevent_t *ev)
14218c2aff7Sartem {
14318c2aff7Sartem 	char		*class;
14418c2aff7Sartem 	char		*subclass;
14518c2aff7Sartem 	nvlist_t	*attr_list;
14618c2aff7Sartem 	char		*phys_path;
14718c2aff7Sartem 	char		*dev_name;
1487b840e52Sphitran 	char		*dev_hid;
1497b840e52Sphitran 	char		*dev_uid;
1507b840e52Sphitran 	uint_t		dev_index;
15118c2aff7Sartem 	char		s[1024];
15218c2aff7Sartem 	ssize_t		nwritten;
15318c2aff7Sartem 
15418c2aff7Sartem 	if ((class = sysevent_get_class_name(ev)) == NULL)
15518c2aff7Sartem 		return;
15618c2aff7Sartem 
15718c2aff7Sartem 	if ((subclass = sysevent_get_subclass_name(ev)) == NULL)
15818c2aff7Sartem 		return;
15918c2aff7Sartem 
16018c2aff7Sartem 	if (sysevent_get_attr_list(ev, &attr_list) != 0)
16118c2aff7Sartem 		return;
16218c2aff7Sartem 
163*112cd14aSqz 	if (strcmp(class, EC_DEVFS) == 0) {
164*112cd14aSqz 		if (nvlist_lookup_string(attr_list, DEVFS_PATHNAME, &phys_path) != 0) {
165*112cd14aSqz 			goto out;
166*112cd14aSqz 		}
167*112cd14aSqz 
168*112cd14aSqz 		snprintf(s, sizeof (s), "%s %s %s\n",
169*112cd14aSqz 		    class, subclass, phys_path);
170*112cd14aSqz 		nwritten = write(sysevent_pipe_fds[1], s, strlen(s) + 1);
171*112cd14aSqz 
172*112cd14aSqz 		HAL_INFO (("sysevent_dev_handler: wrote %d bytes", nwritten));
173*112cd14aSqz 		goto out;
174*112cd14aSqz 	}
175*112cd14aSqz 
176*112cd14aSqz 	if (strcmp(class, EC_ACPIEV) == 0) {
1777b840e52Sphitran 		if (nvlist_lookup_string(attr_list, ACPIEV_DEV_PHYS_PATH,
1787b840e52Sphitran 		    &phys_path) != 0) {
1797b840e52Sphitran 			goto out;
1807b840e52Sphitran 		}
1817b840e52Sphitran 	} else if (nvlist_lookup_string(attr_list, DEV_PHYS_PATH, &phys_path)
1827b840e52Sphitran 	    != 0) {
18318c2aff7Sartem 		goto out;
1847b840e52Sphitran 	}
1857b840e52Sphitran 
1867b840e52Sphitran 	if (nvlist_lookup_string(attr_list, DEV_NAME, &dev_name) != 0) {
1877b840e52Sphitran 		if (strcmp(class, EC_ACPIEV) == 0) {
1887b840e52Sphitran 			dev_name = "noname";
1897b840e52Sphitran 		} else {
1907b840e52Sphitran 			dev_name = "";
1917b840e52Sphitran 		}
1927b840e52Sphitran 	}
19318c2aff7Sartem 
1947b840e52Sphitran 	if (nvlist_lookup_string(attr_list, ACPIEV_DEV_HID, &dev_hid) != 0) {
195*112cd14aSqz 		dev_hid = "";
1967b840e52Sphitran 	}
197*112cd14aSqz 	if (nvlist_lookup_string(attr_list, ACPIEV_DEV_UID, &dev_uid) != 0) {
198*112cd14aSqz 		dev_uid = "";
1997b840e52Sphitran 	}
200*112cd14aSqz 	if (nvlist_lookup_uint32(attr_list, ACPIEV_DEV_INDEX, &dev_index)
2017b840e52Sphitran 	    != 0) {
202*112cd14aSqz 		dev_index = 0;
2037b840e52Sphitran 	}
20418c2aff7Sartem 
2057b840e52Sphitran 	snprintf(s, sizeof (s), "%s %s %s %s %s %s %d\n",
2067b840e52Sphitran 	    class, subclass, phys_path, dev_name, dev_hid, dev_uid, dev_index);
20718c2aff7Sartem 	nwritten = write(sysevent_pipe_fds[1], s, strlen(s) + 1);
20818c2aff7Sartem 
20918c2aff7Sartem 	HAL_INFO (("sysevent_dev_handler: wrote %d bytes", nwritten));
21018c2aff7Sartem 
21118c2aff7Sartem out:
21218c2aff7Sartem 	nvlist_free(attr_list);
21318c2aff7Sartem }
21418c2aff7Sartem 
21518c2aff7Sartem static gboolean
21618c2aff7Sartem sysevent_iochannel_data (GIOChannel *source,
217*112cd14aSqz 		    GIOCondition condition,
218*112cd14aSqz 		    gpointer user_data)
21918c2aff7Sartem {
220*112cd14aSqz 	GError *err = NULL;
22118c2aff7Sartem 	gchar *s = NULL;
22218c2aff7Sartem 	gsize len;
22318c2aff7Sartem 	int matches;
22418c2aff7Sartem 	gchar class[1024];
22518c2aff7Sartem 	gchar subclass[1024];
22618c2aff7Sartem 	gchar phys_path[1024];
22718c2aff7Sartem 	gchar dev_name[1024];
228*112cd14aSqz 	gchar dev_uid[1024];
229*112cd14aSqz 	gchar dev_hid[1024];
230*112cd14aSqz 	gchar udi[1024];
2317b840e52Sphitran 	uint_t dev_index;
23218c2aff7Sartem 
23318c2aff7Sartem 	HAL_INFO (("sysevent_iochannel_data"));
23418c2aff7Sartem 
23518c2aff7Sartem 	while (g_io_channel_read_line (sysevent_iochannel, &s, &len, NULL,
236*112cd14aSqz 	    &err) == G_IO_STATUS_NORMAL) {
23718c2aff7Sartem 		if (len == 0) {
23818c2aff7Sartem 			break;
23918c2aff7Sartem 		}
24018c2aff7Sartem 
2417b840e52Sphitran 		class[0] = subclass[0] = phys_path[0] = dev_name[0] =
2427b840e52Sphitran 		    dev_hid[0] = dev_uid[0] = '\0';
2437b840e52Sphitran 		matches = sscanf(s, "%s %s %s %s %s %s %d", class, subclass,
2447b840e52Sphitran 		    phys_path, dev_name, dev_hid, dev_uid, &dev_index);
24518c2aff7Sartem 		g_free (s);
24618c2aff7Sartem 		s = NULL;
24718c2aff7Sartem 		if (matches < 3) {
24818c2aff7Sartem 			continue;
24918c2aff7Sartem 		}
25018c2aff7Sartem 		HAL_INFO (("sysevent: class=%s, sub=%s", class, subclass));
25118c2aff7Sartem 
25218c2aff7Sartem 		if (strcmp(class, EC_DEV_ADD) == 0) {
25342a7bdedSjacobs 			if ((strcmp(subclass, ESC_DISK) == 0) ||
25442a7bdedSjacobs 			    (strcmp(subclass, ESC_PRINTER) == 0)) {
25518c2aff7Sartem 				sysevent_dev_add(phys_path, dev_name);
25618c2aff7Sartem 			} else if (strcmp(subclass, ESC_LOFI) == 0) {
25718c2aff7Sartem 				sysevent_lofi_add(phys_path, dev_name);
25818c2aff7Sartem 			}
25918c2aff7Sartem 		} else if (strcmp(class, EC_DEV_REMOVE) == 0) {
26042a7bdedSjacobs 			if ((strcmp(subclass, ESC_DISK) == 0) ||
26142a7bdedSjacobs 			    (strcmp(subclass, ESC_PRINTER) == 0)) {
26218c2aff7Sartem 				sysevent_dev_remove(phys_path, dev_name);
26318c2aff7Sartem 			} else if (strcmp(subclass, ESC_LOFI) == 0) {
26418c2aff7Sartem 				sysevent_lofi_remove(phys_path, dev_name);
26518c2aff7Sartem 			}
26618c2aff7Sartem 		} else if (strcmp(class, EC_DEV_BRANCH) == 0) {
26718c2aff7Sartem 			sysevent_dev_branch(phys_path);
2687b840e52Sphitran 		} else if (strcmp(class, EC_ACPIEV) == 0) {
2697b840e52Sphitran 			if (strcmp(dev_hid, "PNP0C0A") == 0) {
2707b840e52Sphitran 				snprintf(udi, sizeof(udi),
2717b840e52Sphitran 				    "/org/freedesktop/Hal/devices/pseudo/"
2727b840e52Sphitran 				    "battery_0_battery%d_0", dev_index);
2737b840e52Sphitran 			} else if (strcmp(dev_hid, "ACPI0003") == 0) {
2747b840e52Sphitran 				snprintf(udi, sizeof(udi),
2757b840e52Sphitran 				    "/org/freedesktop/Hal/devices/pseudo/"
2767b840e52Sphitran 				    "battery_0_ac%d_0", dev_index);
277*112cd14aSqz 			} else {
2787b840e52Sphitran 				HAL_INFO(("dev_hid %s unknown", dev_hid));
2797b840e52Sphitran 				continue;
2807b840e52Sphitran 			}
2817b840e52Sphitran 			devinfo_battery_device_rescan(phys_path, udi);
282*112cd14aSqz 		} else if (strcmp(class, EC_DEVFS) == 0) {
283*112cd14aSqz 			if (strcmp(subclass, ESC_DEVFS_DEVI_ADD) == 0) {
284*112cd14aSqz 				sysevent_devfs_add(phys_path);
285*112cd14aSqz 			}
286*112cd14aSqz 		}
28718c2aff7Sartem 	}
28818c2aff7Sartem 
28918c2aff7Sartem 	if (err) {
29018c2aff7Sartem 		g_error_free (err);
29118c2aff7Sartem 	}
29218c2aff7Sartem 
29318c2aff7Sartem 	return (TRUE);
29418c2aff7Sartem }
29518c2aff7Sartem 
29618c2aff7Sartem static void
29718c2aff7Sartem sysevent_dev_add(gchar *devfs_path, gchar *name)
29818c2aff7Sartem {
29918c2aff7Sartem 	gchar	*parent_devfs_path, *hotplug_devfs_path;
30018c2aff7Sartem 	HalDevice *parent;
30118c2aff7Sartem 
30218c2aff7Sartem 	HAL_INFO (("dev_add: %s %s", name, devfs_path));
30318c2aff7Sartem 
304*112cd14aSqz 	parent = hal_util_find_closest_ancestor (devfs_path, &parent_devfs_path, &hotplug_devfs_path);
30518c2aff7Sartem 	if (parent == NULL) {
30618c2aff7Sartem 		return;
30718c2aff7Sartem 	}
30818c2aff7Sartem 
30918c2aff7Sartem 	HAL_INFO (("dev_add: parent=%s", parent_devfs_path));
31018c2aff7Sartem 	HAL_INFO (("dev_add: real=%s", hotplug_devfs_path));
31118c2aff7Sartem 
31218c2aff7Sartem 	devinfo_add (parent, hotplug_devfs_path);
31318c2aff7Sartem 
31418c2aff7Sartem 	g_free (parent_devfs_path);
31518c2aff7Sartem 	g_free (hotplug_devfs_path);
31618c2aff7Sartem 
31718c2aff7Sartem 	hotplug_event_process_queue ();
31818c2aff7Sartem }
31918c2aff7Sartem 
32018c2aff7Sartem static void
32118c2aff7Sartem sysevent_dev_remove(gchar *devfs_path, gchar *name)
32218c2aff7Sartem {
32318c2aff7Sartem 	HAL_INFO (("dev_remove: %s %s", name, devfs_path));
32418c2aff7Sartem 
32518c2aff7Sartem 	devinfo_remove_branch (devfs_path, NULL);
32618c2aff7Sartem 	hotplug_event_process_queue ();
32718c2aff7Sartem }
32818c2aff7Sartem 
32918c2aff7Sartem static void
33018c2aff7Sartem sysevent_dev_branch(gchar *devfs_path)
33118c2aff7Sartem {
33218c2aff7Sartem 	HAL_INFO (("branch_remove: %s", devfs_path));
33318c2aff7Sartem 
33418c2aff7Sartem 	devinfo_remove_branch (devfs_path, NULL);
33518c2aff7Sartem 	hotplug_event_process_queue ();
33618c2aff7Sartem }
33718c2aff7Sartem 
33818c2aff7Sartem static void
33918c2aff7Sartem sysevent_lofi_add(gchar *devfs_path, gchar *name)
34018c2aff7Sartem {
34118c2aff7Sartem 	di_node_t node;
34218c2aff7Sartem 	const char *parent_udi;
34318c2aff7Sartem 	HalDevice *d, *parent;
34418c2aff7Sartem 
34518c2aff7Sartem 	HAL_INFO (("lofi_add: %s %s", name, devfs_path));
34618c2aff7Sartem 
34718c2aff7Sartem 	if ((d = hal_device_store_match_key_value_string (hald_get_gdl (),
34818c2aff7Sartem 	    "solaris.devfs_path", devfs_path)) == NULL) {
34918c2aff7Sartem 		HAL_INFO (("device not found in GDL %s", devfs_path));
35018c2aff7Sartem 		return;
35118c2aff7Sartem 	}
35218c2aff7Sartem 	parent_udi = hal_device_property_get_string (d, "info.parent");
35318c2aff7Sartem 	if ((parent_udi == NULL) || (strlen(parent_udi) == 0)) {
35418c2aff7Sartem 		HAL_INFO (("parent not found in GDL %s", parent_udi));
35518c2aff7Sartem 		return;
35618c2aff7Sartem 	}
35718c2aff7Sartem 	if ((parent = hal_device_store_match_key_value_string (hald_get_gdl (),
35818c2aff7Sartem 	    "info.udi", parent_udi)) == NULL) {
35918c2aff7Sartem 		HAL_INFO (("parent not found in GDL %s", parent_udi));
36018c2aff7Sartem 		return;
36118c2aff7Sartem 	}
36218c2aff7Sartem 
36318c2aff7Sartem 	if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
36418c2aff7Sartem 		HAL_INFO (("device not found in devinfo %s", devfs_path));
36518c2aff7Sartem 		return;
36618c2aff7Sartem 	}
36718c2aff7Sartem 
36800687e57Sartem 	HAL_INFO (("device %s parent %s", hal_device_get_udi (d), parent_udi));
36918c2aff7Sartem 	devinfo_lofi_add_major (parent, node, devfs_path, NULL, TRUE, d);
37018c2aff7Sartem 
37118c2aff7Sartem 	di_fini (node);
37218c2aff7Sartem 
37318c2aff7Sartem 	hotplug_event_process_queue ();
37418c2aff7Sartem }
37518c2aff7Sartem 
37618c2aff7Sartem static void
37718c2aff7Sartem sysevent_lofi_remove(gchar *parent_devfs_path, gchar *name)
37818c2aff7Sartem {
37918c2aff7Sartem 	devinfo_lofi_remove_minor(parent_devfs_path, name);
38018c2aff7Sartem 	hotplug_event_process_queue ();
38118c2aff7Sartem }
382*112cd14aSqz 
383*112cd14aSqz static HalDevice *
384*112cd14aSqz lookup_parent(char *devfs_path)
385*112cd14aSqz {
386*112cd14aSqz 	gchar		*path = NULL;
387*112cd14aSqz 	HalDevice	*parent = NULL;
388*112cd14aSqz 	char *p;
389*112cd14aSqz 
390*112cd14aSqz 	path = strdup (devfs_path);
391*112cd14aSqz 	p = strrchr (path, '/');
392*112cd14aSqz 	if (p == NULL) {
393*112cd14aSqz 		free (path);
394*112cd14aSqz 		return (NULL);
395*112cd14aSqz 	}
396*112cd14aSqz 	*p = '\0';
397*112cd14aSqz 
398*112cd14aSqz 	/* Look up the parent node in the gdl. */
399*112cd14aSqz 	parent = hal_device_store_match_key_value_string (hald_get_gdl (),
400*112cd14aSqz 	    "solaris.devfs_path", path);
401*112cd14aSqz 
402*112cd14aSqz 	if (parent == NULL) {
403*112cd14aSqz 		/* Look up the parent node in the tdl. */
404*112cd14aSqz 		parent = hal_device_store_match_key_value_string (hald_get_tdl (),
405*112cd14aSqz 		    "solaris.devfs_path", path);
406*112cd14aSqz 	}
407*112cd14aSqz 
408*112cd14aSqz 	free (path);
409*112cd14aSqz 	return (parent);
410*112cd14aSqz }
411*112cd14aSqz 
412*112cd14aSqz /*
413*112cd14aSqz  * Handle the USB bus devices hot plugging events.
414*112cd14aSqz  */
415*112cd14aSqz static void
416*112cd14aSqz sysevent_devfs_add(gchar *devfs_path)
417*112cd14aSqz {
418*112cd14aSqz 	di_node_t node;
419*112cd14aSqz 	HalDevice *parent;
420*112cd14aSqz 	char *driver_name;
421*112cd14aSqz 
422*112cd14aSqz 	HAL_INFO (("devfs_handle: %s", devfs_path));
423*112cd14aSqz 
424*112cd14aSqz 	if ((node = di_init (devfs_path, DINFOCPYALL)) == DI_NODE_NIL) {
425*112cd14aSqz 		HAL_INFO (("device not found in devinfo %s", devfs_path));
426*112cd14aSqz 		return;
427*112cd14aSqz 	}
428*112cd14aSqz 
429*112cd14aSqz 	if ((driver_name = di_driver_name (node)) == NULL)
430*112cd14aSqz 		goto out;
431*112cd14aSqz 
432*112cd14aSqz 	/* The disk and printer devices are handled by EC_DEV_ADD class. */
433*112cd14aSqz 	if ((strcmp (driver_name, "scsa2usb") == 0) ||
434*112cd14aSqz 	    (strcmp (driver_name, "usbprn") == 0))
435*112cd14aSqz 		goto out;
436*112cd14aSqz 
437*112cd14aSqz 	if ((parent = lookup_parent (devfs_path)) == NULL)
438*112cd14aSqz 		goto out;
439*112cd14aSqz 
440*112cd14aSqz 	devinfo_usb_add (parent, node, devfs_path, NULL);
441*112cd14aSqz 
442*112cd14aSqz 	di_fini (node);
443*112cd14aSqz 
444*112cd14aSqz 	hotplug_event_process_queue ();
445*112cd14aSqz 
446*112cd14aSqz 	return;
447*112cd14aSqz 
448*112cd14aSqz  out:
449*112cd14aSqz 	di_fini (node);
450*112cd14aSqz }
451