This source file includes following definitions.
- wsmuxattach
- wsmux_getmux
- wsmuxopen
- wsmux_mux_open
- wsmux_do_open
- wsmuxclose
- wsmux_mux_close
- wsmux_do_close
- wsmuxread
- wsmuxioctl
- wsmux_do_ioctl
- wsmuxpoll
- wsmux_add_mux
- wsmux_create
- wsmux_attach_sc
- wsmux_detach_sc
- wsmux_do_displayioctl
- wsmux_evsrc_set_display
- wsmux_set_display
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include "wsmux.h"
41 #include "wsdisplay.h"
42 #include "wskbd.h"
43 #include "wsmouse.h"
44
45
46
47
48
49
50
51
52 #include <sys/param.h>
53 #include <sys/conf.h>
54 #include <sys/ioctl.h>
55 #include <sys/fcntl.h>
56 #include <sys/kernel.h>
57 #include <sys/malloc.h>
58 #include <sys/proc.h>
59 #include <sys/queue.h>
60 #include <sys/syslog.h>
61 #include <sys/systm.h>
62 #include <sys/tty.h>
63 #include <sys/signalvar.h>
64 #include <sys/device.h>
65 #include <sys/poll.h>
66
67 #include <dev/wscons/wsconsio.h>
68 #include <dev/wscons/wsksymdef.h>
69 #include <dev/wscons/wseventvar.h>
70 #include <dev/wscons/wscons_callbacks.h>
71 #include <dev/wscons/wsmuxvar.h>
72
73 #ifdef WSMUX_DEBUG
74 #define DPRINTF(x) if (wsmuxdebug) printf x
75 #define DPRINTFN(n,x) if (wsmuxdebug > (n)) printf x
76 int wsmuxdebug = 0;
77 #else
78 #define DPRINTF(x)
79 #define DPRINTFN(n,x)
80 #endif
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 int wsmux_mux_open(struct wsevsrc *, struct wseventvar *);
97 int wsmux_mux_close(struct wsevsrc *);
98
99 void wsmux_do_open(struct wsmux_softc *, struct wseventvar *);
100
101 void wsmux_do_close(struct wsmux_softc *);
102 #if NWSDISPLAY > 0
103 int wsmux_evsrc_set_display(struct device *, struct device *);
104 #else
105 #define wsmux_evsrc_set_display NULL
106 #endif
107
108 int wsmux_do_displayioctl(struct device *dev, u_long cmd, caddr_t data,
109 int flag, struct proc *p);
110 int wsmux_do_ioctl(struct device *, u_long, caddr_t,int,struct proc *);
111
112 int wsmux_add_mux(int, struct wsmux_softc *);
113
114 void wsmuxattach(int);
115
116 struct wssrcops wsmux_srcops = {
117 WSMUX_MUX,
118 wsmux_mux_open, wsmux_mux_close, wsmux_do_ioctl, wsmux_do_displayioctl,
119 wsmux_evsrc_set_display
120 };
121
122
123 void
124 wsmuxattach(int n)
125 {
126 }
127
128
129 int nwsmux = 0;
130 struct wsmux_softc **wsmuxdevs = NULL;
131
132
133 struct wsmux_softc *
134 wsmux_getmux(int n)
135 {
136 struct wsmux_softc *sc;
137 struct wsmux_softc **new, **old;
138 int i;
139
140
141 if (n >= nwsmux) {
142 old = wsmuxdevs;
143 new = (struct wsmux_softc **)
144 malloc((n + 1) * sizeof (*wsmuxdevs), M_DEVBUF, M_NOWAIT);
145 if (new == NULL) {
146 printf("wsmux_getmux: no memory for mux %d\n", n);
147 return (NULL);
148 }
149 if (old != NULL)
150 bcopy(old, new, nwsmux * sizeof(*wsmuxdevs));
151 for (i = nwsmux; i < (n + 1); i++)
152 new[i] = NULL;
153 wsmuxdevs = new;
154 nwsmux = n + 1;
155 if (old != NULL)
156 free(old, M_DEVBUF);
157 }
158
159 sc = wsmuxdevs[n];
160 if (sc == NULL) {
161 sc = wsmux_create("wsmux", n);
162 if (sc == NULL)
163 printf("wsmux: attach out of memory\n");
164 wsmuxdevs[n] = sc;
165 }
166 return (sc);
167 }
168
169
170
171
172 int
173 wsmuxopen(dev_t dev, int flags, int mode, struct proc *p)
174 {
175 struct wsmux_softc *sc;
176 struct wseventvar *evar;
177 int unit;
178
179 unit = minor(dev);
180 sc = wsmux_getmux(unit);
181 if (sc == NULL)
182 return (ENXIO);
183
184 DPRINTF(("wsmuxopen: %s: sc=%p p=%p\n", sc->sc_base.me_dv.dv_xname, sc, p));
185
186 if ((flags & (FREAD | FWRITE)) == FWRITE) {
187
188 return (0);
189 }
190
191 if (sc->sc_base.me_parent != NULL) {
192
193 DPRINTF(("wsmuxopen: detach\n"));
194 wsmux_detach_sc(&sc->sc_base);
195 }
196
197 if (sc->sc_base.me_evp != NULL)
198
199 return (EBUSY);
200
201 evar = &sc->sc_base.me_evar;
202 wsevent_init(evar);
203 evar->io = p;
204 #ifdef WSDISPLAY_COMPAT_RAWKBD
205 sc->sc_rawkbd = 0;
206 #endif
207
208 wsmux_do_open(sc, evar);
209
210 return (0);
211 }
212
213
214
215
216 int
217 wsmux_mux_open(struct wsevsrc *me, struct wseventvar *evar)
218 {
219 struct wsmux_softc *sc = (struct wsmux_softc *)me;
220
221 #ifdef DIAGNOSTIC
222 if (sc->sc_base.me_evp != NULL) {
223 printf("wsmux_mux_open: busy\n");
224 return (EBUSY);
225 }
226 if (sc->sc_base.me_parent == NULL) {
227 printf("wsmux_mux_open: no parent\n");
228 return (EINVAL);
229 }
230 #endif
231
232 wsmux_do_open(sc, evar);
233
234 return (0);
235 }
236
237
238 void
239 wsmux_do_open(struct wsmux_softc *sc, struct wseventvar *evar)
240 {
241 struct wsevsrc *me;
242 #ifdef DIAGNOSTIC
243 int error;
244 #endif
245
246 sc->sc_base.me_evp = evar;
247
248
249 CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
250 DPRINTF(("wsmuxopen: %s: m=%p dev=%s\n",
251 sc->sc_base.me_dv.dv_xname, me, me->me_dv.dv_xname));
252 #ifdef DIAGNOSTIC
253 if (me->me_evp != NULL) {
254 printf("wsmuxopen: dev already in use\n");
255 continue;
256 }
257 if (me->me_parent != sc) {
258 printf("wsmux_do_open: bad child=%p\n", me);
259 continue;
260 }
261 error = wsevsrc_open(me, evar);
262 if (error) {
263 DPRINTF(("wsmuxopen: open failed %d\n", error));
264 }
265 #else
266
267 (void)wsevsrc_open(me, evar);
268 #endif
269 }
270 }
271
272
273
274
275 int
276 wsmuxclose(dev_t dev, int flags, int mode, struct proc *p)
277 {
278 struct wsmux_softc *sc =
279 (struct wsmux_softc *)wsmuxdevs[minor(dev)];
280 struct wseventvar *evar = sc->sc_base.me_evp;
281
282 if (evar == NULL)
283
284 return (0);
285
286 wsmux_do_close(sc);
287 sc->sc_base.me_evp = NULL;
288 wsevent_fini(evar);
289 return (0);
290 }
291
292
293
294
295 int
296 wsmux_mux_close(struct wsevsrc *me)
297 {
298 me->me_evp = NULL;
299 wsmux_do_close((struct wsmux_softc *)me);
300 return (0);
301 }
302
303
304 void
305 wsmux_do_close(struct wsmux_softc *sc)
306 {
307 struct wsevsrc *me;
308
309 DPRINTF(("wsmuxclose: %s: sc=%p\n", sc->sc_base.me_dv.dv_xname, sc));
310
311
312 CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
313 DPRINTF(("wsmuxclose %s: m=%p dev=%s\n",
314 sc->sc_base.me_dv.dv_xname, me, me->me_dv.dv_xname));
315 #ifdef DIAGNOSTIC
316 if (me->me_parent != sc) {
317 printf("wsmuxclose: bad child=%p\n", me);
318 continue;
319 }
320 #endif
321 (void)wsevsrc_close(me);
322 me->me_evp = NULL;
323 }
324 }
325
326
327
328
329 int
330 wsmuxread(dev_t dev, struct uio *uio, int flags)
331 {
332 struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
333 struct wseventvar *evar;
334 int error;
335
336 evar = sc->sc_base.me_evp;
337 if (evar == NULL) {
338 #ifdef DIAGNOSTIC
339
340 printf("wsmuxread: not open\n");
341 #endif
342 return (EINVAL);
343 }
344
345 DPRINTFN(5,("wsmuxread: %s event read evar=%p\n",
346 sc->sc_base.me_dv.dv_xname, evar));
347 error = wsevent_read(evar, uio, flags);
348 DPRINTFN(5,("wsmuxread: %s event read ==> error=%d\n",
349 sc->sc_base.me_dv.dv_xname, error));
350 return (error);
351 }
352
353
354
355
356 int
357 wsmuxioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
358 {
359 return wsmux_do_ioctl(&wsmuxdevs[minor(dev)]->sc_base.me_dv, cmd, data, flag, p);
360 }
361
362
363
364
365 int
366 wsmux_do_ioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
367 struct proc *p)
368 {
369 struct wsmux_softc *sc = (struct wsmux_softc *)dv;
370 struct wsevsrc *me;
371 int error, ok;
372 int s, put, get, n;
373 struct wseventvar *evar;
374 struct wscons_event *ev;
375 struct wsmux_device_list *l;
376
377 DPRINTF(("wsmux_do_ioctl: %s: enter sc=%p, cmd=%08lx\n",
378 sc->sc_base.me_dv.dv_xname, sc, cmd));
379
380 switch (cmd) {
381 case WSMUXIO_INJECTEVENT:
382 case WSMUXIO_ADD_DEVICE:
383 case WSMUXIO_REMOVE_DEVICE:
384 #ifdef WSDISPLAY_COMPAT_RAWKBD
385 case WSKBDIO_SETMODE:
386 #endif
387 if ((flag & FWRITE) == 0)
388 return (EACCES);
389 }
390
391 switch (cmd) {
392 case WSMUXIO_INJECTEVENT:
393
394 DPRINTF(("%s: inject\n", sc->sc_base.me_dv.dv_xname));
395 evar = sc->sc_base.me_evp;
396 if (evar == NULL) {
397
398 DPRINTF(("wsmux_do_ioctl: event ignored\n"));
399 return (0);
400 }
401
402 s = spltty();
403 get = evar->get;
404 put = evar->put;
405 ev = &evar->q[put];
406 if (++put % WSEVENT_QSIZE == get) {
407 put--;
408 splx(s);
409 return (ENOSPC);
410 }
411 if (put >= WSEVENT_QSIZE)
412 put = 0;
413 *ev = *(struct wscons_event *)data;
414 nanotime(&ev->time);
415 evar->put = put;
416 WSEVENT_WAKEUP(evar);
417 splx(s);
418 return (0);
419 case WSMUXIO_ADD_DEVICE:
420 #define d ((struct wsmux_device *)data)
421 DPRINTF(("%s: add type=%d, no=%d\n", sc->sc_base.me_dv.dv_xname,
422 d->type, d->idx));
423 switch (d->type) {
424 #if NWSMOUSE > 0
425 case WSMUX_MOUSE:
426 return (wsmouse_add_mux(d->idx, sc));
427 #endif
428 #if NWSKBD > 0
429 case WSMUX_KBD:
430 return (wskbd_add_mux(d->idx, sc));
431 #endif
432 case WSMUX_MUX:
433 return (wsmux_add_mux(d->idx, sc));
434 default:
435 return (EINVAL);
436 }
437 case WSMUXIO_REMOVE_DEVICE:
438 DPRINTF(("%s: rem type=%d, no=%d\n", sc->sc_base.me_dv.dv_xname,
439 d->type, d->idx));
440
441 CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
442 if (me->me_ops->type == d->type &&
443 me->me_dv.dv_unit == d->idx) {
444 DPRINTF(("wsmux_do_ioctl: detach\n"));
445 wsmux_detach_sc(me);
446 return (0);
447 }
448 }
449 return (EINVAL);
450 #undef d
451
452 case WSMUXIO_LIST_DEVICES:
453 DPRINTF(("%s: list\n", sc->sc_base.me_dv.dv_xname));
454 l = (struct wsmux_device_list *)data;
455 n = 0;
456 CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
457 if (n >= WSMUX_MAXDEV)
458 break;
459 l->devices[n].type = me->me_ops->type;
460 l->devices[n].idx = me->me_dv.dv_unit;
461 n++;
462 }
463 l->ndevices = n;
464 return (0);
465 #ifdef WSDISPLAY_COMPAT_RAWKBD
466 case WSKBDIO_SETMODE:
467 sc->sc_rawkbd = *(int *)data;
468 DPRINTF(("wsmux_do_ioctl: save rawkbd = %d\n", sc->sc_rawkbd));
469 break;
470 #endif
471 case FIONBIO:
472 DPRINTF(("%s: FIONBIO\n", sc->sc_base.me_dv.dv_xname));
473 return (0);
474
475 case FIOASYNC:
476 DPRINTF(("%s: FIOASYNC\n", sc->sc_base.me_dv.dv_xname));
477 evar = sc->sc_base.me_evp;
478 if (evar == NULL)
479 return (EINVAL);
480 evar->async = *(int *)data != 0;
481 return (0);
482 case FIOSETOWN:
483 DPRINTF(("%s: FIOSETOWN\n", sc->sc_base.me_dv.dv_xname));
484 evar = sc->sc_base.me_evp;
485 if (evar == NULL)
486 return (EINVAL);
487 if (-*(int *)data != evar->io->p_pgid
488 && *(int *)data != evar->io->p_pid)
489 return (EPERM);
490 return (0);
491 case TIOCSPGRP:
492 DPRINTF(("%s: TIOCSPGRP\n", sc->sc_base.me_dv.dv_xname));
493 evar = sc->sc_base.me_evp;
494 if (evar == NULL)
495 return (EINVAL);
496 if (*(int *)data != evar->io->p_pgid)
497 return (EPERM);
498 return (0);
499 default:
500 DPRINTF(("%s: unknown\n", sc->sc_base.me_dv.dv_xname));
501 break;
502 }
503
504 if (sc->sc_base.me_evp == NULL
505 #if NWSDISPLAY > 0
506 && sc->sc_displaydv == NULL
507 #endif
508 )
509 return (EACCES);
510
511
512 error = 0;
513 ok = 0;
514 CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
515 #ifdef DIAGNOSTIC
516
517 if (me->me_parent != sc) {
518 printf("wsmux_do_ioctl: bad child %p\n", me);
519 continue;
520 }
521 #endif
522 error = wsevsrc_ioctl(me, cmd, data, flag, p);
523 DPRINTF(("wsmux_do_ioctl: %s: me=%p dev=%s ==> %d\n",
524 sc->sc_base.me_dv.dv_xname, me, me->me_dv.dv_xname,
525 error));
526 if (!error)
527 ok = 1;
528 }
529 if (ok) {
530 error = 0;
531 if (cmd == WSKBDIO_SETENCODING) {
532 sc->sc_kbd_layout = *((kbd_t *)data);
533 }
534
535 }
536
537 return (error);
538 }
539
540
541
542
543 int
544 wsmuxpoll(dev_t dev, int events, struct proc *p)
545 {
546 struct wsmux_softc *sc = wsmuxdevs[minor(dev)];
547
548 if (sc->sc_base.me_evp == NULL) {
549 #ifdef DIAGNOSTIC
550 printf("wsmuxpoll: not open\n");
551 #endif
552 return (POLLERR);
553 }
554
555 return (wsevent_poll(sc->sc_base.me_evp, events, p));
556 }
557
558
559
560
561 int
562 wsmux_add_mux(int unit, struct wsmux_softc *muxsc)
563 {
564 struct wsmux_softc *sc, *m;
565
566 sc = wsmux_getmux(unit);
567 if (sc == NULL)
568 return (ENXIO);
569
570 DPRINTF(("wsmux_add_mux: %s(%p) to %s(%p)\n",
571 sc->sc_base.me_dv.dv_xname, sc, muxsc->sc_base.me_dv.dv_xname,
572 muxsc));
573
574 if (sc->sc_base.me_parent != NULL || sc->sc_base.me_evp != NULL)
575 return (EBUSY);
576
577
578 for (m = muxsc; m != NULL ; m = m->sc_base.me_parent)
579 if (m == sc)
580 return (EINVAL);
581
582 return (wsmux_attach_sc(muxsc, &sc->sc_base));
583 }
584
585
586 struct wsmux_softc *
587 wsmux_create(const char *name, int unit)
588 {
589 struct wsmux_softc *sc;
590
591 DPRINTF(("wsmux_create: allocating\n"));
592 sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
593 if (sc == NULL)
594 return (NULL);
595 bzero(sc, sizeof *sc);
596 CIRCLEQ_INIT(&sc->sc_cld);
597 snprintf(sc->sc_base.me_dv.dv_xname, sizeof sc->sc_base.me_dv.dv_xname,
598 "%s%d", name, unit);
599 sc->sc_base.me_dv.dv_unit = unit;
600 sc->sc_base.me_ops = &wsmux_srcops;
601 sc->sc_kbd_layout = KB_NONE;
602 return (sc);
603 }
604
605
606 int
607 wsmux_attach_sc(struct wsmux_softc *sc, struct wsevsrc *me)
608 {
609 int error;
610
611 if (sc == NULL)
612 return (EINVAL);
613
614 DPRINTF(("wsmux_attach_sc: %s(%p): type=%d\n",
615 sc->sc_base.me_dv.dv_xname, sc, me->me_ops->type));
616
617 #ifdef DIAGNOSTIC
618 if (me->me_parent != NULL) {
619 printf("wsmux_attach_sc: busy\n");
620 return (EBUSY);
621 }
622 #endif
623 me->me_parent = sc;
624 CIRCLEQ_INSERT_TAIL(&sc->sc_cld, me, me_next);
625
626 error = 0;
627 #if NWSDISPLAY > 0
628 if (sc->sc_displaydv != NULL) {
629
630 DPRINTF(("wsmux_attach_sc: %s: set display %p\n",
631 sc->sc_base.me_dv.dv_xname, sc->sc_displaydv));
632 if (me->me_ops->dsetdisplay != NULL) {
633 error = wsevsrc_set_display(me, sc->sc_displaydv);
634
635 if (error == EBUSY)
636 error = 0;
637 if (!error) {
638 #ifdef WSDISPLAY_COMPAT_RAWKBD
639 DPRINTF(("wsmux_attach_sc: %s set rawkbd=%d\n",
640 me->me_dv.dv_xname, sc->sc_rawkbd));
641 (void)wsevsrc_ioctl(me, WSKBDIO_SETMODE,
642 &sc->sc_rawkbd, FWRITE, 0);
643 #endif
644 if (sc->sc_kbd_layout != KB_NONE)
645 (void)wsevsrc_ioctl(me,
646 WSKBDIO_SETENCODING,
647 &sc->sc_kbd_layout, FWRITE, 0);
648 }
649 }
650 }
651 #endif
652 if (sc->sc_base.me_evp != NULL) {
653
654 DPRINTF(("wsmux_attach_sc: %s: calling open of %s\n",
655 sc->sc_base.me_dv.dv_xname, me->me_dv.dv_xname));
656 error = wsevsrc_open(me, sc->sc_base.me_evp);
657 } else {
658 DPRINTF(("wsmux_attach_sc: %s not open\n",
659 sc->sc_base.me_dv.dv_xname));
660 }
661
662 if (error) {
663 me->me_parent = NULL;
664 CIRCLEQ_REMOVE(&sc->sc_cld, me, me_next);
665 }
666
667 DPRINTF(("wsmux_attach_sc: %s(%p) done, error=%d\n",
668 sc->sc_base.me_dv.dv_xname, sc, error));
669 return (error);
670 }
671
672
673 void
674 wsmux_detach_sc(struct wsevsrc *me)
675 {
676 struct wsmux_softc *sc = me->me_parent;
677
678 DPRINTF(("wsmux_detach_sc: %s(%p) parent=%p\n",
679 me->me_dv.dv_xname, me, sc));
680
681 #ifdef DIAGNOSTIC
682 if (sc == NULL) {
683 printf("wsmux_detach_sc: %s has no parent\n",
684 me->me_dv.dv_xname);
685 return;
686 }
687 #endif
688
689 #if NWSDISPLAY > 0
690 if (sc->sc_displaydv != NULL) {
691 if (me->me_ops->dsetdisplay != NULL)
692
693 (void)wsevsrc_set_display(me, NULL);
694 } else
695 #endif
696 if (me->me_evp != NULL) {
697 DPRINTF(("wsmux_detach_sc: close\n"));
698
699 (void)wsevsrc_close(me);
700 }
701
702 CIRCLEQ_REMOVE(&sc->sc_cld, me, me_next);
703 me->me_parent = NULL;
704
705 DPRINTF(("wsmux_detach_sc: done sc=%p\n", sc));
706 }
707
708
709
710
711 int
712 wsmux_do_displayioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
713 struct proc *p)
714 {
715 struct wsmux_softc *sc = (struct wsmux_softc *)dv;
716 struct wsevsrc *me;
717 int error, ok;
718
719 DPRINTF(("wsmux_displayioctl: %s: sc=%p, cmd=%08lx\n",
720 sc->sc_base.me_dv.dv_xname, sc, cmd));
721
722 #ifdef WSDISPLAY_COMPAT_RAWKBD
723 if (cmd == WSKBDIO_SETMODE) {
724 sc->sc_rawkbd = *(int *)data;
725 DPRINTF(("wsmux_displayioctl: rawkbd = %d\n", sc->sc_rawkbd));
726 }
727 #endif
728
729
730
731
732
733 error = -1;
734 ok = 0;
735 CIRCLEQ_FOREACH(me, &sc->sc_cld, me_next) {
736 DPRINTF(("wsmux_displayioctl: me=%p\n", me));
737 #ifdef DIAGNOSTIC
738 if (me->me_parent != sc) {
739 printf("wsmux_displayioctl: bad child %p\n", me);
740 continue;
741 }
742 #endif
743 if (me->me_ops->ddispioctl != NULL) {
744 error = wsevsrc_display_ioctl(me, cmd, data, flag, p);
745 DPRINTF(("wsmux_displayioctl: me=%p dev=%s ==> %d\n",
746 me, me->me_dv.dv_xname, error));
747 if (!error)
748 ok = 1;
749 }
750 }
751 if (ok)
752 error = 0;
753
754 return (error);
755 }
756
757 #if NWSDISPLAY > 0
758
759
760
761 int
762 wsmux_evsrc_set_display(struct device *dv, struct device *displaydv)
763 {
764 struct wsmux_softc *sc = (struct wsmux_softc *)dv;
765
766 DPRINTF(("wsmux_set_display: %s: displaydv=%p\n",
767 sc->sc_base.me_dv.dv_xname, displaydv));
768
769 if (displaydv != NULL) {
770 if (sc->sc_displaydv != NULL)
771 return (EBUSY);
772 } else {
773 if (sc->sc_displaydv == NULL)
774 return (ENXIO);
775 }
776
777 return wsmux_set_display(sc, displaydv);
778 }
779
780 int
781 wsmux_set_display(struct wsmux_softc *sc, struct device *displaydv)
782 {
783 struct device *odisplaydv;
784 struct wsevsrc *me;
785 struct wsmux_softc *nsc = displaydv ? sc : NULL;
786 int error, ok;
787
788 odisplaydv = sc->sc_displaydv;
789 sc->sc_displaydv = displaydv;
790
791 if (displaydv) {
792 DPRINTF(("%s: connecting to %s\n",
793 sc->sc_base.me_dv.dv_xname, displaydv->dv_xname));
794 }
795 ok = 0;
796 error = 0;
797 CIRCLEQ_FOREACH(me, &sc->sc_cld,me_next) {
798 #ifdef DIAGNOSTIC
799 if (me->me_parent != sc) {
800 printf("wsmux_set_display: bad child parent %p\n", me);
801 continue;
802 }
803 #endif
804 if (me->me_ops->dsetdisplay != NULL) {
805 error = wsevsrc_set_display(me, nsc->sc_displaydv);
806 DPRINTF(("wsmux_set_display: m=%p dev=%s error=%d\n",
807 me, me->me_dv.dv_xname, error));
808 if (!error) {
809 ok = 1;
810 #ifdef WSDISPLAY_COMPAT_RAWKBD
811 DPRINTF(("wsmux_set_display: %s set rawkbd=%d\n"
812 ,
813 me->me_dv.dv_xname, sc->sc_rawkbd));
814 (void)wsevsrc_ioctl(me, WSKBDIO_SETMODE,
815 &sc->sc_rawkbd, FWRITE, 0);
816 #endif
817 }
818 }
819 }
820 if (ok)
821 error = 0;
822
823 if (displaydv == NULL) {
824 DPRINTF(("%s: disconnecting from %s\n",
825 sc->sc_base.me_dv.dv_xname, odisplaydv->dv_xname));
826 }
827
828 return (error);
829 }
830 #endif