From owner-freebsd-bugs@FreeBSD.ORG Mon Jan 21 06:10:01 2013 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 947048B9 for ; Mon, 21 Jan 2013 06:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 86C42BF7 for ; Mon, 21 Jan 2013 06:10:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.6/8.14.6) with ESMTP id r0L6A09h094510 for ; Mon, 21 Jan 2013 06:10:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.6/8.14.6/Submit) id r0L6A01Q094506; Mon, 21 Jan 2013 06:10:00 GMT (envelope-from gnats) Date: Mon, 21 Jan 2013 06:10:00 GMT Message-Id: <201301210610.r0L6A01Q094506@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Yuri Subject: Re: misc/175425: kbdcontrol(1) printout about kbdmux isn't informative X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: Yuri List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jan 2013 06:10:01 -0000 The following reply was made to PR misc/175425; it has been noted by GNATS. From: Yuri To: bug-followup@FreeBSD.org Cc: Subject: Re: misc/175425: kbdcontrol(1) printout about kbdmux isn't informative Date: Sun, 20 Jan 2013 22:01:14 -0800 This is a multi-part message in MIME format. --------------070002040502000102020100 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Patches: * patch-ioctl-var-size.txt : implements variable size ioctl(2) data parameter. This is used by the ioctl in the second patch. Userland truss(1) is updated accordingly. * patch-kbd-mux-contents.txt : implements new ioctl KBLSTKBD listing contents of the kbd mux. Userland kbdcontrol is updated with the new option -I using KBLSTKBD. --------------070002040502000102020100 Content-Type: text/plain; charset=UTF-8; name="patch-ioctl-var-size.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch-ioctl-var-size.txt" Index: sys/kern/sys_generic.c =================================================================== --- sys/kern/sys_generic.c (revision 245654) +++ sys/kern/sys_generic.c (working copy) @@ -640,6 +640,7 @@ int arg, error; u_int size; caddr_t data; + int vsize; if (uap->com > 0xffffffff) { printf( @@ -654,18 +655,30 @@ * copied to/from the user's address space. */ size = IOCPARM_LEN(com); + /* Both IOC_VOID and IOC_INOUT mean that data has variable size */ + if (com & IOC_VOID && com & IOC_INOUT) { + if (size != 0) + return (EINVAL); + /* first integer has the length of the memory */ + error = copyin(uap->data, (caddr_t)&vsize, sizeof(vsize)); + if (error) + return (error); + size = (u_int)vsize; + if (size > IOCPARM_MAX) + return (EINVAL); + } if ((size > IOCPARM_MAX) || - ((com & (IOC_VOID | IOC_IN | IOC_OUT)) == 0) || + ((com & IOC_DIRMASK) == 0) || #if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43) ((com & IOC_OUT) && size == 0) || #else ((com & (IOC_IN | IOC_OUT)) && size == 0) || #endif - ((com & IOC_VOID) && size > 0 && size != sizeof(int))) + (((com & IOC_DIRMASK) == IOC_VOID) && size > 0 && size != sizeof(int))) return (ENOTTY); if (size > 0) { - if (com & IOC_VOID) { + if ((com & IOC_DIRMASK) == IOC_VOID) { /* Integer argument. */ arg = (intptr_t)uap->data; data = (void *)&arg; Index: sys/netgraph/ng_eiface.c =================================================================== --- sys/netgraph/ng_eiface.c (revision 245654) +++ sys/netgraph/ng_eiface.c (working copy) @@ -325,6 +325,15 @@ case IOC_INOUT: str = "IORW"; break; + case IOC_OUT_EXT: + str = "IORE"; + break; + case IOC_IN_EXT: + str = "IOWE"; + break; + case IOC_INOUT_EXT: + str = "IORWE"; + break; default: str = "IO??"; } Index: sys/netgraph/ng_fec.c =================================================================== --- sys/netgraph/ng_fec.c (revision 245654) +++ sys/netgraph/ng_fec.c (working copy) @@ -1167,6 +1167,15 @@ case IOC_INOUT: str = "IORW"; break; + case IOC_OUT_EXT: + str = "IORE"; + break; + case IOC_IN_EXT: + str = "IOWE"; + break; + case IOC_INOUT_EXT: + str = "IORWE"; + break; default: str = "IO??"; } Index: sys/netgraph/ng_iface.c =================================================================== --- sys/netgraph/ng_iface.c (revision 245654) +++ sys/netgraph/ng_iface.c (working copy) @@ -505,6 +505,15 @@ case IOC_INOUT: str = "IORW"; break; + case IOC_OUT_EXT: + str = "IORE"; + break; + case IOC_IN_EXT: + str = "IOWE"; + break; + case IOC_INOUT_EXT: + str = "IORWE"; + break; default: str = "IO??"; } Index: sys/sys/ioccom.h =================================================================== --- sys/sys/ioccom.h (revision 245654) +++ sys/sys/ioccom.h (working copy) @@ -48,8 +48,11 @@ #define IOC_VOID 0x20000000 /* no parameters */ #define IOC_OUT 0x40000000 /* copy out parameters */ #define IOC_IN 0x80000000 /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) -#define IOC_DIRMASK (IOC_VOID|IOC_OUT|IOC_IN) +#define IOC_INOUT (IOC_IN | IOC_OUT) +#define IOC_DIRMASK (IOC_VOID | IOC_OUT | IOC_IN) +#define IOC_OUT_EXT IOC_OUT | IOC_VOID /* copy out parameters */ +#define IOC_IN_EXT IOC_IN | IOC_VOID /* copy out parameters */ +#define IOC_INOUT_EXT IOC_INOUT | IOC_VOID /* copy out parameters */ #define _IOC(inout,group,num,len) ((unsigned long) \ ((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | (num))) @@ -59,6 +62,9 @@ #define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) /* this should be _IORW, but stdio got there first */ #define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) +#define _IORE(g,n) _IOC(IOC_OUT_EXT, (g), (n), 0) +#define _IOWE(g,n) _IOC(IOC_IN_EXT, (g), (n), 0) +#define _IOWRE(g,n) _IOC(IOC_INOUT_EXT, (g), (n), 0) #ifdef _KERNEL Index: usr.bin/truss/syscalls.c =================================================================== --- usr.bin/truss/syscalls.c (revision 245654) +++ usr.bin/truss/syscalls.c (working copy) @@ -668,9 +668,12 @@ tmp = strdup(temp); else { unsigned long arg = args[sc->offset]; - asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", - arg, arg & IOC_OUT ? "R" : "", - arg & IOC_IN ? "W" : "", IOCGROUP(arg), + asprintf(&tmp, "0x%lx { IO%s%s%s 0x%lx('%c'), %lu, %lu }", + arg, + arg & IOC_OUT ? "R" : "", + arg & IOC_IN ? "W" : "", + (arg & IOC_VOID && arg & IOC_INOUT) ? "E" : "", + IOCGROUP(arg), isprint(IOCGROUP(arg)) ? (char)IOCGROUP(arg) : '?', arg & 0xFF, IOCPARM_LEN(arg)); } --------------070002040502000102020100 Content-Type: text/plain; charset=UTF-8; name="patch-kbd-mux-contents.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch-kbd-mux-contents.txt" Index: sys/dev/kbdmux/kbdmux.c =================================================================== --- sys/dev/kbdmux/kbdmux.c (revision 245654) +++ sys/dev/kbdmux/kbdmux.c (working copy) @@ -943,6 +943,9 @@ kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; kbdmux_kbd_t *k; keyboard_info_t *ki; + keyboard_info_array_t *kia; + keyboard_info_array_t *kia_limit; + int ki_count; int error = 0, mode; #ifdef COMPAT_FREEBSD6 int ival; @@ -1049,6 +1052,35 @@ KBDMUX_UNLOCK(state); break; + case KBLSTKBD: /* list mux contents */ + kia = (keyboard_info_array_t *) arg; + + if (kia == NULL || kia->len <= 0) + return (EINVAL); /* bad input */ + + KBDMUX_LOCK(state); + + kia_limit = (keyboard_info_array_t *) ((char*)arg+kia->len); + ki = kia->kbs; + ki_count = 0; + SLIST_FOREACH(k, &state->ks_kbds, next) { + if (kia+1 > kia_limit) + break; + ki->kb_index = k->kbd->kb_index; + (void) strcpy(ki->kb_name, k->kbd->kb_name); + ki->kb_unit = k->kbd->kb_unit; + ki->kb_type = k->kbd->kb_type; + ki->kb_config = k->kbd->kb_config; + ki->kb_flags = k->kbd->kb_flags; + + ki++; + ki_count++; + } + kia->len = ki_count; + + KBDMUX_UNLOCK(state); + break; + case KDGKBMODE: /* get kyboard mode */ KBDMUX_LOCK(state); *(int *)arg = state->ks_mode; Index: sys/dev/syscons/syscons.c =================================================================== --- sys/dev/syscons/syscons.c (revision 245654) +++ sys/dev/syscons/syscons.c (working copy) @@ -1349,6 +1349,7 @@ case KBADDKBD: /* add/remove keyboard to/from mux */ case KBRELKBD: + case KBLSTKBD: error = kbdd_ioctl(sc->kbd, cmd, data); if (error == ENOIOCTL) error = ENODEV; Index: sys/sys/kbio.h =================================================================== --- sys/sys/kbio.h (revision 245654) +++ sys/sys/kbio.h (working copy) @@ -70,9 +70,16 @@ }; typedef struct keyboard_info keyboard_info_t; +struct keyboard_info_array { + int len; /* array kbs[] length */ + keyboard_info_t kbs[1]; /* variable size array */ +}; +typedef struct keyboard_info_array keyboard_info_array_t; + /* add/remove keyboard to/from mux */ #define KBADDKBD _IOW('K', 68, keyboard_info_t) /* add keyboard */ #define KBRELKBD _IOW('K', 69, keyboard_info_t) /* release keyboard */ +#define KBLSTKBD _IOWRE('K', 70) /* list mux */ /* see console.h for the definition of the following ioctl */ #ifdef notdef Index: usr.sbin/kbdcontrol/kbdcontrol.1 =================================================================== --- usr.sbin/kbdcontrol/kbdcontrol.1 (revision 245654) +++ usr.sbin/kbdcontrol/kbdcontrol.1 (working copy) @@ -146,6 +146,8 @@ Use hexadecimal numbers in keyboard map dump. .It Fl i Print brief information about the keyboard. +.It Fl I +Print contents of the keyboard multiplexer. .It Fl K Disconnect the keyboard from the console. You need to use the Index: usr.sbin/kbdcontrol/kbdcontrol.c =================================================================== --- usr.sbin/kbdcontrol/kbdcontrol.c (revision 245654) +++ usr.sbin/kbdcontrol/kbdcontrol.c (working copy) @@ -138,6 +138,7 @@ void set_keyboard(char *device); void set_keyrates(char *opt); void show_kbd_info(void); +void show_mux_info(void); void usage(void) __dead2; char * @@ -1011,6 +1012,22 @@ return "unknown"; } +static void +print_kbd_info(keyboard_info_t *info) +{ + printf("%.*s%d, type:%s (%d)\n", + (int)sizeof(info->kb_name), info->kb_name, info->kb_unit, + get_kbd_type_name(info->kb_type), info->kb_type); +} + +static void +print_kbd_info_extended(keyboard_info_t *info) +{ + printf("kbd%d:\n", info->kb_index); + printf(" "); + print_kbd_info(info); +} + void show_kbd_info(void) { @@ -1020,13 +1037,41 @@ warn("unable to obtain keyboard information"); return; } - printf("kbd%d:\n", info.kb_index); - printf(" %.*s%d, type:%s (%d)\n", - (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, - get_kbd_type_name(info.kb_type), info.kb_type); + print_kbd_info_extended(&info); } void +show_mux_info(void) +{ + int i; + keyboard_info_t info_mux; + + keyboard_info_array_t *info_arr = (keyboard_info_array_t*) + malloc(IOCPARM_MAX); + info_arr->len = IOCPARM_MAX; + + if (ioctl(0, KDGKBINFO, &info_mux) == -1) { + warn("unable to obtain keyboard information"); + free(info_arr); + return; + } + if (ioctl(0, KBLSTKBD, info_arr) == -1) { + warn("unable to obtain keyboard multiplexer information"); + free(info_arr); + return; + } + + printf("Keyboard multiplexor kbd%d: ", info_mux.kb_index); + print_kbd_info(&info_mux); + for (i=0; ilen; i++) { + printf(" part[%i]: kbd%d: ", i, info_arr->kbs[i].kb_index); + print_kbd_info(&info_arr->kbs[i]); + } + + free(info_arr); +} + +void set_keyboard(char *device) { keyboard_info_t info; @@ -1050,10 +1095,7 @@ ioctl(fd, CONS_RELKBD, 0); close(fd); #if 1 - printf("kbd%d\n", info.kb_index); - printf(" %.*s%d, type:%s (%d)\n", - (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, - get_kbd_type_name(info.kb_type), info.kb_type); + print_kbd_info_extended(&info); #endif if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) @@ -1074,10 +1116,7 @@ return; } #if 1 - printf("kbd%d\n", info.kb_index); - printf(" %.*s%d, type:%s (%d)\n", - (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, - get_kbd_type_name(info.kb_type), info.kb_type); + print_kbd_info_extended(&info); #endif if (ioctl(0, CONS_RELKBD, 0) == -1) warn("unable to release the keyboard"); @@ -1098,10 +1137,7 @@ return; } #if 1 - printf("kbd%d\n", info.kb_index); - printf(" %.*s%d, type:%s (%d)\n", - (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, - get_kbd_type_name(info.kb_type), info.kb_type); + print_kbd_info_extended(&info); #endif /* * split kbd into name and unit. find the right most part of the @@ -1163,7 +1199,7 @@ { int opt; - while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:r:x")) != -1) + while((opt = getopt(argc, argv, "A:a:b:df:iIKk:Fl:L:r:x")) != -1) switch(opt) { case 'A': case 'a': @@ -1191,6 +1227,9 @@ case 'i': show_kbd_info(); break; + case 'I': + show_mux_info(); + break; case 'K': release_keyboard(); break; --------------070002040502000102020100--