View | Details | Raw Unified | Return to bug 196678 | Differences between
and this patch

Collapse All | Expand All

(-)files/patch-config_devd.c (-202 / +246 lines)
Lines 1-6 Link Here
1
--- config/devd.c.orig	2015-05-19 19:41:49 UTC
1
--- config/devd.c.orig	2015-01-12 10:47:19.000000000 +0100
2
+++ config/devd.c
2
+++ config/devd.c	2015-01-13 12:02:22.000000000 +0100
3
@@ -0,0 +1,531 @@
3
@@ -0,0 +1,575 @@
4
+/*
4
+/*
5
+ * Copyright (c) 2012 Baptiste Daroussin
5
+ * Copyright (c) 2012 Baptiste Daroussin
6
+ * Copyright (c) 2013, 2014 Alex Kozlov
6
+ * Copyright (c) 2013, 2014 Alex Kozlov
Lines 41-52 Link Here
41
+#include <sys/un.h>
41
+#include <sys/un.h>
42
+
42
+
43
+#include <ctype.h>
43
+#include <ctype.h>
44
+#include <dirent.h>
44
+#include <errno.h>
45
+#include <errno.h>
45
+#include <fcntl.h>
46
+#include <fcntl.h>
46
+#include <stdlib.h>
47
+#include <stdlib.h>
47
+#include <stdio.h>
48
+#include <stdio.h>
48
+#include <stdbool.h>
49
+#include <stdbool.h>
49
+#include <unistd.h>
50
+#include <unistd.h>
51
+#include <paths.h>
50
+
52
+
51
+#include "input.h"
53
+#include "input.h"
52
+#include "inputstr.h"
54
+#include "inputstr.h"
Lines 56-68 Link Here
56
+
58
+
57
+#define DEVD_SOCK_PATH "/var/run/devd.pipe"
59
+#define DEVD_SOCK_PATH "/var/run/devd.pipe"
58
+
60
+
59
+#define DEVD_EVENT_ADD		'+'
61
+#define RECONNECT_DELAY		(5 * 1000)
60
+#define DEVD_EVENT_REMOVE	'-'
61
+
62
+#define RECONNECT_DELAY		5 * 1000
63
+
62
+
64
+static int sock_devd;
63
+static int sock_devd;
65
+static bool is_console_kbd = false;
66
+static bool is_kbdmux = false;
64
+static bool is_kbdmux = false;
67
+OsTimerPtr rtimer;
65
+OsTimerPtr rtimer;
68
+
66
+
Lines 70-140 Link Here
70
+	const char *driver;
68
+	const char *driver;
71
+	int flag;
69
+	int flag;
72
+	const char *xdriver;
70
+	const char *xdriver;
71
+	const char *sysctldesc;
73
+};
72
+};
74
+
73
+
75
+static struct hw_type hw_types[] = {
74
+static const struct hw_type hw_types0[] = {
76
+	{ "ukbd", ATTR_KEYBOARD, "kbd" },
75
+	{ _PATH_DEV "sysmouse", ATTR_POINTER, "mouse", NULL },
77
+	{ "atkbd", ATTR_KEYBOARD, "kbd" },
76
+	{ NULL, 0, NULL, NULL },
78
+	{ "kbdmux", ATTR_KEYBOARD, "kbd" },
79
+	{ "sysmouse", ATTR_POINTER, "mouse" },
80
+	{ "ums", ATTR_POINTER, "mouse" },
81
+	{ "psm", ATTR_POINTER, "mouse" },
82
+	{ "vboxguest", ATTR_POINTER, "vboxmouse" },
83
+	{ "joy", ATTR_JOYSTICK, NULL },
84
+	{ "atp", ATTR_TOUCHPAD, NULL },
85
+	{ "uep", ATTR_TOUCHSCREEN, NULL },
86
+	{ NULL, -1, NULL },
87
+};
77
+};
88
+
78
+
89
+static bool
79
+static const struct hw_type hw_types1[] = {
90
+sysctl_exists(const struct hw_type *device, int unit,
80
+	{ _PATH_DEV "ukbd%d", ATTR_KEYBOARD, "kbd", "dev.ukbd.%d.%%desc" },
91
+	char *devname, size_t devname_len)
81
+	{ _PATH_DEV "atkbd%d", ATTR_KEYBOARD, "kbd", "dev.atkbd.%d.%%desc" },
92
+{
82
+	{ _PATH_DEV "kbdmux%d", ATTR_KEYBOARD, "kbd", NULL },
93
+	char sysctlname[PATH_MAX];
83
+	{ _PATH_DEV "ums%d", ATTR_POINTER, "mouse", "dev.ums.%d.%%desc" },
94
+	size_t len;
84
+	{ _PATH_DEV "psm%d", ATTR_POINTER, "mouse", "dev.psm.%d.%%desc" },
95
+	int ret;
85
+	{ _PATH_DEV "joy%d", ATTR_JOYSTICK, "mouse", "dev.joy.%d.%%desc" },
96
+
86
+	{ _PATH_DEV "atp%d", ATTR_TOUCHPAD, "mouse", "dev.atp.%d.%%desc" },
97
+	if (device == NULL || device->driver == NULL)
87
+	{ _PATH_DEV "wsp%d", ATTR_TOUCHPAD, "mouse", "dev.wsp.%d.%%desc" },
98
+		return false;
88
+	{ _PATH_DEV "uep%d", ATTR_TOUCHSCREEN, "mouse", "dev.uep.%d.%%desc" },
99
+
89
+	{ _PATH_DEV "vboxguest", ATTR_POINTER, "vboxmouse", NULL },
100
+	/* Check if a sysctl exists. */
90
+	{ _PATH_DEV "input/event%d", ATTR_TOUCHPAD, "evdev", NULL },
101
+	snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc",
91
+	{ NULL, 0, NULL, NULL },
102
+	    device->driver, unit);
92
+};
103
+	ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0);
104
+
93
+
105
+	if (ret == 0 && len > 0) {
94
+static void
106
+		snprintf(devname, devname_len, "%s%i", device->driver, unit);
95
+get_usb_id(char **pptr, int fd)
107
+		return true;
96
+{
97
+	unsigned short vendor;
98
+	unsigned short product;
99
+	unsigned int speed;
100
+#define	WEBCAMD_IOCTL_GET_USB_VENDOR_ID _IOR('q', 250, unsigned short)
101
+#define	WEBCAMD_IOCTL_GET_USB_PRODUCT_ID _IOR('q', 251, unsigned short)
102
+#define	WEBCAMD_IOCTL_GET_USB_SPEED _IOR('q', 252, unsigned int)
103
+	if (ioctl(fd, WEBCAMD_IOCTL_GET_USB_VENDOR_ID, &vendor) == 0 &&
104
+	    ioctl(fd, WEBCAMD_IOCTL_GET_USB_PRODUCT_ID, &product) == 0 &&
105
+	    ioctl(fd, WEBCAMD_IOCTL_GET_USB_SPEED, &speed) == 0) {
106
+		if (asprintf(pptr, "%04x:%04x", vendor, product) == -1)
107
+			*pptr = NULL;
108
+	}
108
+	}
109
+
110
+	return false;
111
+}
109
+}
112
+
110
+
113
+static bool
111
+static const char *
114
+devpath_exists(const struct hw_type *device,
112
+skip_path_dev(const char *ptr)
115
+	char *devname, size_t devname_len)
113
+{
116
+{
114
+	if (strstr(ptr, _PATH_DEV) == ptr)
117
+	char *devpath;
115
+		ptr += strlen(_PATH_DEV);
118
+	struct stat st;
116
+	return (ptr);
119
+	int ret;
120
+
121
+	if (device == NULL || device->driver == NULL)
122
+		return false;
123
+
124
+	/* Check if /dev/$driver exists. */
125
+	asprintf(&devpath, "/dev/%s", device->driver);
126
+	if (devpath == NULL)
127
+		return false;
128
+
129
+	ret = stat(devpath, &st);
130
+	free(devpath);
131
+
132
+	if (ret == 0) {
133
+		strncpy(devname, device->driver, devname_len);
134
+		return true;
135
+	}
136
+
137
+	return false;
138
+}
117
+}
139
+
118
+
140
+static char *
119
+static char *
Lines 162-219 Link Here
162
+}
141
+}
163
+
142
+
164
+static void
143
+static void
165
+device_added(const char *devname)
144
+device_added(const char *devicename, bool allow_no_device)
166
+{
145
+{
167
+	char path[PATH_MAX];
168
+	char sysctlname[PATH_MAX];
169
+	char *vendor;
170
+	char *product = NULL;
171
+	char *config_info = NULL;
172
+	char *walk;
173
+	InputOption *options = NULL;
174
+	InputAttributes attrs = { };
146
+	InputAttributes attrs = { };
147
+	InputOption *options = NULL;
148
+	char *config_info = NULL;
175
+	DeviceIntPtr dev = NULL;
149
+	DeviceIntPtr dev = NULL;
150
+	struct hw_type hw_type;
151
+	char *product = NULL;
152
+	char sysctlname[64];
153
+	char *vendor = NULL;
154
+	int unit = 0;
155
+	int fd = -1;
156
+	char *walk;
176
+	int i;
157
+	int i;
177
+	int fd;
178
+
179
+	for (i = 0; hw_types[i].driver != NULL; i++) {
180
+		size_t len;
181
+
158
+
182
+		len = strlen(hw_types[i].driver);
159
+	for (i = 0; hw_types0[i].driver != NULL; i++) {
183
+		if (strcmp(devname, hw_types[i].driver) == 0 ||
160
+		if (strcmp(devicename, hw_types0[i].driver) == 0) {
184
+			(strncmp(devname, hw_types[i].driver, len) == 0 &&
161
+			hw_type = hw_types0[i];
185
+				isnumber(*(devname + len)))) {
162
+			goto found;
186
+			attrs.flags |= hw_types[i].flag;
187
+			break;
188
+		}
163
+		}
189
+	}
164
+	}
190
+
165
+	for (i = 0; hw_types1[i].driver != NULL; i++) {
191
+	if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) {
166
+		if (sscanf(devicename, hw_types1[i].driver, &unit) == 1) {
192
+		LogMessage(X_INFO, "config/devd: ignoring device %s\n",
167
+			hw_type = hw_types1[i];
193
+				devname);
168
+			goto found;
194
+		return;
169
+		}
195
+	}
170
+	}
171
+	goto ignore;
196
+
172
+
197
+	/* Skip keyboard devices if kbdmux is enabled */
173
+found:
198
+	if (is_kbdmux && is_console_kbd && hw_types[i].flag & ATTR_KEYBOARD) {
174
+	if (hw_type.xdriver == NULL)
199
+		LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n",
175
+		goto ignore;
200
+				devname);
176
+
201
+		return;
177
+	if (strcmp(hw_type.xdriver, "kbd") == 0) {
178
+		bool match = (strstr(hw_type.driver,
179
+		    _PATH_DEV "kbdmux") == hw_type.driver);
180
+
181
+		if (is_kbdmux) {
182
+			if (!match)
183
+				goto ignore;
184
+		} else {
185
+			if (match)
186
+				goto ignore;
187
+		}
202
+	}
188
+	}
203
+
189
+
204
+	snprintf(path, sizeof(path), "/dev/%s", devname);
205
+
206
+	options = input_option_new(NULL, "_source", "server/devd");
190
+	options = input_option_new(NULL, "_source", "server/devd");
207
+	if (!options)
191
+	if (options == NULL)
208
+		return;
192
+		goto error;
209
+
193
+
210
+	snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%s.%%desc",
194
+	if (hw_type.sysctldesc != NULL) {
211
+	    hw_types[i].driver, devname + strlen(hw_types[i].driver));
195
+		snprintf(sysctlname, sizeof(sysctlname),
212
+	vendor = sysctl_get_str(sysctlname);
196
+		    hw_type.sysctldesc, unit);
213
+	if (vendor == NULL) {
197
+		vendor = sysctl_get_str(sysctlname);
214
+		options = input_option_new(options, "name", devname);
215
+	}
198
+	}
216
+	else {
199
+
200
+	if (vendor == NULL) {
201
+		options = input_option_new(options, "name",
202
+		    skip_path_dev(devicename));
203
+	} else {
217
+		if ((walk = strchr(vendor, ' ')) != NULL) {
204
+		if ((walk = strchr(vendor, ' ')) != NULL) {
218
+			walk[0] = '\0';
205
+			walk[0] = '\0';
219
+			walk++;
206
+			walk++;
Lines 223-315 Link Here
223
+		}
210
+		}
224
+
211
+
225
+		attrs.vendor = strdup(vendor);
212
+		attrs.vendor = strdup(vendor);
226
+		if (product) {
213
+		if (product != NULL) {
227
+			attrs.product = strdup(product);
214
+			attrs.product = strdup(product);
228
+			options = input_option_new(options, "name", product);
215
+			options = input_option_new(options,
216
+			    "name", product);
217
+		} else {
218
+			options = input_option_new(options,
219
+			    "name", "Unknown");
229
+		}
220
+		}
230
+		else
231
+			options = input_option_new(options, "name", "(unnamed)");
232
+
233
+		free(vendor);
234
+	}
221
+	}
222
+	attrs.device = strdup(devicename);
235
+
223
+
236
+	/* XXX implement usb_id */
224
+	fd = open(devicename, O_RDONLY);
237
+	attrs.usb_id = NULL;
225
+	if (fd > -1) {
238
+	attrs.device = strdup(path);
226
+	  	get_usb_id(&attrs.usb_id, fd);
239
+	options = input_option_new(options, "driver", hw_types[i].xdriver);
240
+
241
+	fd = open(path, O_RDONLY);
242
+	if (fd > 0) {
243
+		close(fd);
227
+		close(fd);
244
+		options = input_option_new(options, "device", path);
228
+		options = input_option_new(options, "device", devicename);
245
+	}
229
+		if (options == NULL)
246
+	else {
230
+			goto error;
247
+		if (attrs.flags & ~ATTR_KEYBOARD) {
231
+	} else if (allow_no_device) {
248
+			LogMessage(X_INFO, "config/devd: device %s already opened\n",
232
+		/*
249
+					 path);
233
+		 * Don't pass "device" option if the keyboard is
250
+
234
+		 * already attached to the console (ie. open() fails).
251
+			/*
235
+		 * This would activate a special logic in
252
+			 * Fail if cannot open device, it breaks AllowMouseOpenFail,
236
+		 * xf86-input-keyboard. Prevent any other attached to
253
+			 * but it should not matter when config/devd enabled
237
+		 * console keyboards being processed. There can be
254
+			 */
238
+		 * only one such device.
255
+			goto unwind;
239
+		 */
256
+		}
240
+	} else {
257
+
241
+		goto ignore;
258
+		if (is_console_kbd) {
242
+	}
259
+			/*
243
+
260
+			 * There can be only one keyboard attached to console and
244
+	options = input_option_new(options, "driver", hw_type.xdriver);
261
+			 * it is already added.
245
+	if (options == NULL)
262
+			 */
246
+		goto error;
263
+			LogMessage(X_WARNING, "config/devd: console keyboard is "
264
+					"already added, ignoring %s (%s)\n",
265
+					attrs.product, path);
266
+			goto unwind;
267
+		}
268
+		else
269
+			/*
270
+			 * Don't pass "device" option if the keyboard is already
271
+			 * attached to the console (ie. open() fails).
272
+			 * This would activate a special logic in xf86-input-keyboard.
273
+			 * Prevent any other attached to console keyboards being
274
+			 * processed. There can be only one such device.
275
+			 */
276
+			is_console_kbd = true;
277
+	}
278
+
247
+
279
+	if (asprintf(&config_info, "devd:%s", devname) == -1) {
248
+	if (asprintf(&config_info, "devd:%s",
249
+	    skip_path_dev(devicename)) == -1) {
280
+		config_info = NULL;
250
+		config_info = NULL;
281
+		goto unwind;
251
+		goto error;
282
+	}
252
+	}
283
+
253
+
284
+	if (device_is_duplicate(config_info)) {
254
+	if (device_is_duplicate(config_info))
285
+		LogMessage(X_WARNING, "config/devd: device %s (%s) already added. "
255
+		goto duplicate;
286
+				"ignoring\n", attrs.product, path);
287
+		goto unwind;
288
+	}
289
+
256
+
290
+	options = input_option_new(options, "config_info", config_info);
257
+	options = input_option_new(options, "config_info", config_info);
291
+	LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n",
258
+	if (options == NULL)
292
+			attrs.product, path);
259
+		goto error;
260
+
261
+	LogMessage(X_INFO, "config/devd: adding input device '%s'\n",
262
+	    devicename);
293
+
263
+
294
+	NewInputDeviceRequest(options, &attrs, &dev);
264
+	NewInputDeviceRequest(options, &attrs, &dev);
265
+	goto done;
266
+
267
+duplicate:
268
+	LogMessage(X_WARNING, "config/devd: device '%s' already "
269
+	    "added. Ignoring\n", devicename);
270
+	goto done;
271
+
272
+error:
273
+	LogMessage(X_INFO, "config/devd: error adding device '%s'\n",
274
+	    devicename);
275
+	goto done;
276
+
277
+ignore:
278
+	LogMessage(X_INFO, "config/devd: ignoring device '%s'\n",
279
+	    devicename);
280
+	goto done;
295
+
281
+
296
+unwind:
282
+done:
297
+	free(config_info);
283
+	free(config_info);
298
+	input_option_free_list(&options);
284
+	input_option_free_list(&options);
299
+	free(attrs.usb_id);
285
+	free(attrs.usb_id);
300
+	free(attrs.product);
286
+	free(attrs.product);
301
+	free(attrs.device);
287
+	free(attrs.device);
302
+	free(attrs.vendor);
288
+	free(attrs.vendor);
289
+	free(vendor);
290
+}
291
+
292
+static void
293
+devpath_scan_sub(char *path, int off, int rem)
294
+{
295
+	struct dirent *entry;
296
+	DIR *dp;
297
+
298
+	if ((dp = opendir(path)) == NULL) {
299
+		LogMessage(X_INFO, "Cannot open directory '%s'\n", path);
300
+		return;
301
+	}
302
+	while ((entry = readdir(dp)) != NULL) {
303
+		int len = strlen(entry->d_name);
304
+		if (len > rem)
305
+			continue;
306
+		strcpy(path + off, entry->d_name);
307
+		off += len;
308
+		rem -= len;
309
+		switch (entry->d_type) {
310
+		case DT_DIR:
311
+			if (strcmp(entry->d_name, ".") == 0 ||
312
+			    strcmp(entry->d_name, "..") == 0)
313
+				break;
314
+			if (rem < 1)
315
+				break;
316
+			path[off] = '/';
317
+			path[off+1] = '\0';
318
+			off++;
319
+			rem--;
320
+			/* recurse */
321
+			devpath_scan_sub(path, off, rem);
322
+			off--;
323
+			rem++;
324
+			break;
325
+		case DT_SOCK:
326
+		case DT_FIFO:
327
+		case DT_LNK:
328
+		case DT_CHR:
329
+			/* add device, if any */			
330
+			device_added(path, false);
331
+			break;
332
+		default:
333
+			break;
334
+		}
335
+		off -= len;
336
+		rem += len;
337
+	}
338
+	closedir(dp);
303
+}
339
+}
304
+
340
+
305
+static void
341
+static void
306
+device_removed(char *devname)
342
+devpath_scan(void)
343
+{
344
+	char path[PATH_MAX + 1];
345
+
346
+	strlcpy(path, _PATH_DEV, sizeof(path));
347
+
348
+	devpath_scan_sub(path, strlen(path), PATH_MAX - strlen(path));
349
+}
350
+
351
+static void
352
+device_removed(char *devicename)
307
+{
353
+{
308
+	char *config_info;
354
+	char *config_info;
309
+
355
+
310
+	if (asprintf(&config_info, "devd:%s", devname) == -1)
356
+	if (asprintf(&config_info, "devd:%s",
357
+	    skip_path_dev(devicename)) == -1)
311
+		return;
358
+		return;
312
+
359
+
360
+	if (device_is_duplicate(config_info)) {
361
+		LogMessage(X_INFO, "config/devd: removing input device '%s'\n",
362
+		    devicename);
363
+	}
313
+	remove_devices("devd", config_info);
364
+	remove_devices("devd", config_info);
314
+
365
+
315
+	free(config_info);
366
+	free(config_info);
Lines 318-325 Link Here
318
+static bool is_kbdmux_enabled(void)
369
+static bool is_kbdmux_enabled(void)
319
+{
370
+{
320
+	/* Xorg uses /dev/ttyv0 as a console device */
371
+	/* Xorg uses /dev/ttyv0 as a console device */
321
+	/* const char device[]="/dev/console"; */
372
+	static const char device[]= { _PATH_DEV "ttyv0" };
322
+	const char device[]="/dev/ttyv0";
323
+	keyboard_info_t info;
373
+	keyboard_info_t info;
324
+	int fd;
374
+	int fd;
325
+
375
+
Lines 448-454 Link Here
448
+static void
498
+static void
449
+wakeup_handler(void *data, int err, void *read_mask)
499
+wakeup_handler(void *data, int err, void *read_mask)
450
+{
500
+{
501
+	static const char cdev_create[] = { "!system=DEVFS subsystem=CDEV type=CREATE cdev=" };
502
+	static const char cdev_destroy[] = { "!system=DEVFS subsystem=CDEV type=DESTROY cdev=" };
503
+	static const char cdev_path[] = { _PATH_DEV };
451
+	char *line = NULL;
504
+	char *line = NULL;
505
+	char *devicename;
452
+	char *walk;
506
+	char *walk;
453
+
507
+
454
+	if (err < 0)
508
+	if (err < 0)
Lines 457-476 Link Here
457
+	if (FD_ISSET(sock_devd, (fd_set *) read_mask)) {
511
+	if (FD_ISSET(sock_devd, (fd_set *) read_mask)) {
458
+		if (socket_getline(sock_devd, &line) < 0)
512
+		if (socket_getline(sock_devd, &line) < 0)
459
+			return;
513
+			return;
460
+
514
+		if (strstr(line, cdev_create) == line) {
461
+		walk = strchr(line + 1, ' ');
515
+			devicename = line + strlen(cdev_create) - strlen(cdev_path);
462
+		if (walk != NULL)
516
+			memcpy(devicename, cdev_path, strlen(cdev_path));
463
+			walk[0] = '\0';
517
+			walk = strchr(devicename, ' ');
464
+
518
+			if (walk != NULL)
465
+		switch (*line) {
519
+				walk[0] = '\0';
466
+		case DEVD_EVENT_ADD:
520
+			device_added(devicename, false);
467
+			device_added(line + 1);
521
+		} else if (strstr(line, cdev_destroy) == line) {
468
+			break;
522
+			devicename = line + strlen(cdev_destroy) - strlen(cdev_path);
469
+		case DEVD_EVENT_REMOVE:
523
+			memcpy(devicename, cdev_path, strlen(cdev_path));
470
+			device_removed(line + 1);
524
+			walk = strchr(devicename, ' ');
471
+			break;
525
+			if (walk != NULL)
472
+		default:
526
+				walk[0] = '\0';
473
+			break;
527
+			device_removed(devicename);
474
+		}
528
+		}
475
+		free(line);
529
+		free(line);
476
+	}
530
+	}
Lines 484-517 Link Here
484
+int
538
+int
485
+config_devd_init(void)
539
+config_devd_init(void)
486
+{
540
+{
487
+	char devicename[1024];
488
+	int i, j;
489
+
490
+	LogMessage(X_INFO, "config/devd: probing input devices...\n");
541
+	LogMessage(X_INFO, "config/devd: probing input devices...\n");
491
+
542
+
492
+	/*
543
+	/* Check if kbdmux is enabled */
493
+	 * Add fake keyboard and give up on keyboards management
544
+	is_kbdmux = is_kbdmux_enabled();
494
+	 * if kbdmux is enabled
495
+	 */
496
+	if ((is_kbdmux = is_kbdmux_enabled()) == true)
497
+		device_added("kbdmux");
498
+
499
+	for (i = 0; hw_types[i].driver != NULL; i++) {
500
+		/* First scan the sysctl to determine the hardware */
501
+		for (j = 0; j < 16; j++) {
502
+			if (sysctl_exists(&hw_types[i], j,
503
+					devicename, sizeof(devicename)) != 0)
504
+				device_added(devicename);
505
+		}
506
+
545
+
507
+		if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0)
546
+	/* Try to add kbdmux device first */
508
+			device_added(devicename);
547
+	if (is_kbdmux)
509
+	}
548
+		device_added(_PATH_DEV "kbdmux0", true);
510
+
549
+
550
+	/* Connect to devd, so that we don't loose any events */
511
+	if ((sock_devd = connect_devd()) < 0)
551
+	if ((sock_devd = connect_devd()) < 0)
512
+		return 0;
552
+		return 0;
513
+
553
+
514
+	RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
554
+	/* Scan what is currently connected */
555
+	devpath_scan();
556
+
557
+	/* Register wakeup handler */
558
+	RegisterBlockAndWakeupHandlers(block_handler,
559
+	    wakeup_handler, NULL);
515
+
560
+
516
+	return 1;
561
+	return 1;
517
+}
562
+}
Lines 528-534 Link Here
528
+
573
+
529
+	disconnect_devd(sock_devd);
574
+	disconnect_devd(sock_devd);
530
+
575
+
531
+	RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
576
+	RemoveBlockAndWakeupHandlers(block_handler,
532
+
577
+	    wakeup_handler, NULL);
533
+	is_console_kbd = false;
534
+}
578
+}

Return to bug 196678