176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5c6c1ea5440ca78e9fab99d7f3e18a54ba4d7b7f0Wichert Akkerman * Copyright (c) 1996-2001 Wichert Akkerman <wichert@cistron.nl>
676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved.
776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without
976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions
1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met:
1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright
1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    notice, this list of conditions and the following disclaimer.
1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright
1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    notice, this list of conditions and the following disclaimer in the
1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    documentation and/or other materials provided with the distribution.
1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products
1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    derived from this software without specific prior written permission.
1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h"
323460dc486d333231998de0f19918204aacee9ae3Felix Janda#include <linux/ioctl.h>
33924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin#include "xlat/ioctl_dirs.h"
34a966785753cbabaf44b39c75d387adf423e44caaWichert Akkerman
356f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar#ifdef HAVE_LINUX_INPUT_H
366f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar# include <linux/input.h>
376f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar#endif
386f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
396f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar#include "xlat/evdev_abs.h"
406f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar#include "xlat/evdev_ev.h"
416f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int
431201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocompare(const void *a, const void *b)
4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
45d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes	const unsigned int code1 = (const uintptr_t) a;
46c7afb4881f14e44968f3a78ae5988f04ecc66b68Dmitry V. Levin	const unsigned int code2 = ((struct_ioctlent *) b)->code;
47feb40c4543d22468bb6dc7e3c29746ee2d4e06ccDenys Vlasenko	return (code1 > code2) ? 1 : (code1 < code2) ? -1 : 0;
4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
50044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levinstatic const struct_ioctlent *
51df7aa2b19e6f69c19fbe09180bf1ec4fb52e2615Dmitry V. Levinioctl_lookup(const unsigned int code)
5276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
53a9fe13c9437707fa132fde4e51a20d88381e7430Denys Vlasenko	struct_ioctlent *iop;
5476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
55d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes	iop = bsearch((const void *) (const uintptr_t) code, ioctlent,
561c2e912cc3e1be4081334b9ce0114c10a72166c6Denys Vlasenko			nioctlents, sizeof(ioctlent[0]), compare);
571c2e912cc3e1be4081334b9ce0114c10a72166c6Denys Vlasenko	while (iop > ioctlent) {
581c2e912cc3e1be4081334b9ce0114c10a72166c6Denys Vlasenko		iop--;
591c2e912cc3e1be4081334b9ce0114c10a72166c6Denys Vlasenko		if (iop->code != code) {
602843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath			iop++;
612843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath			break;
622843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath		}
631c2e912cc3e1be4081334b9ce0114c10a72166c6Denys Vlasenko	}
642843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath	return iop;
652843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath}
662843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath
67044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levinstatic const struct_ioctlent *
68a9fe13c9437707fa132fde4e51a20d88381e7430Denys Vlasenkoioctl_next_match(const struct_ioctlent *iop)
692843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath{
70c7afb4881f14e44968f3a78ae5988f04ecc66b68Dmitry V. Levin	const unsigned int code = iop->code;
711c2e912cc3e1be4081334b9ce0114c10a72166c6Denys Vlasenko	iop++;
722843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath	if (iop < ioctlent + nioctlents && iop->code == code)
732843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath		return iop;
742843a4e1d2fca851be6e47e7ff2413b45903ac9aRoland McGrath	return NULL;
7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
77044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levinstatic void
78924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levinioctl_print_code(const unsigned int code)
79924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin{
80924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin	tprints("_IOC(");
81924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin	printflags(ioctl_dirs, _IOC_DIR(code), "_IOC_???");
82d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes	tprintf(", %#x, %#x, %#x)",
83924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin		_IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code));
84924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin}
85924996a41e54a3ac6bb90a43a8cebbbf6c0e1319Dmitry V. Levin
866f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskarstatic int
872803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levinevdev_decode_number(const unsigned int code)
886f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar{
892803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin	const unsigned int nr = _IOC_NR(code);
906f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
912803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin	if (_IOC_DIR(code) == _IOC_WRITE) {
926f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
936f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			tprints("EVIOCSABS(");
941f1559e6a95678d02bd62d21c927b8788bfaaffbDmitry V. Levin			printxval(evdev_abs, nr - 0xc0, "ABS_???");
956f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			tprints(")");
966f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
976f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		}
986f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	}
996f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
1002803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin	if (_IOC_DIR(code) != _IOC_READ)
1016f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		return 0;
1026f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
1036f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	if (nr >= 0x20 && nr <= 0x20 + 0x1f) {
1046f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		tprints("EVIOCGBIT(");
1056f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		printxval(evdev_ev, nr - 0x20, "EV_???");
1062803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin		tprintf(", %u)", _IOC_SIZE(code));
1076f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		return 1;
1086f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	} else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
1096f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		tprints("EVIOCGABS(");
1106f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		printxval(evdev_abs, nr - 0x40, "ABS_???");
1116f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		tprints(")");
1126f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		return 1;
1136f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	}
1146f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
1156f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	switch (_IOC_NR(nr)) {
1166f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x06:
1172803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGNAME(%u)", _IOC_SIZE(code));
1186f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1196f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x07:
1202803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGPHYS(%u)", _IOC_SIZE(code));
1216f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1226f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x08:
1232803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGUNIQ(%u)", _IOC_SIZE(code));
1246f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1256f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x09:
1262803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGPROP(%u)", _IOC_SIZE(code));
1276f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1286f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x0a:
1292803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGMTSLOTS(%u)", _IOC_SIZE(code));
1306f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1316f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x18:
1322803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGKEY(%u)", _IOC_SIZE(code));
1336f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1346f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x19:
1352803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGLED(%u)", _IOC_SIZE(code));
1366f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1376f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x1a:
1382803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGSND(%u)", _IOC_SIZE(code));
1396f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1406f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 0x1b:
1412803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			tprintf("EVIOCGSW(%u)", _IOC_SIZE(code));
1426f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 1;
1436f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		default:
1446f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 0;
1456f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	}
1466f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar}
1476f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
1486f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskarstatic int
1492803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levinhiddev_decode_number(const unsigned int code)
1506f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar{
1512803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin	if (_IOC_DIR(code) == _IOC_READ) {
1522803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin		switch (_IOC_NR(code)) {
1536f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			case 0x04:
1542803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("HIDIOCGRAWNAME(%u)", _IOC_SIZE(code));
1556f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1566f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			case 0x05:
1572803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("HIDIOCGRAWPHYS(%u)", _IOC_SIZE(code));
1586f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1596f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			case 0x06:
1602803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
1616f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1626f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			case 0x12:
1632803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("HIDIOCGPHYS(%u)", _IOC_SIZE(code));
1646f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1656f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			default:
1666f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 0;
1676f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		}
1682803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin	} else if (_IOC_DIR(code) == (_IOC_READ | _IOC_WRITE)) {
1692803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin		switch (_IOC_NR(code)) {
1706f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			case 0x06:
1712803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(code));
1726f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1736f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			case 0x07:
1742803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("HIDIOCGFEATURE(%u)", _IOC_SIZE(code));
1756f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1766f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			default:
1776f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 0;
1786f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		}
1796f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	}
1806f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
1816f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	return 0;
1826f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar}
1836f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
184044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levinstatic int
1854f63c113887a738a06e4bd35c7f867e975793f91Dmitry V. Levinioctl_decode_command_number(struct tcb *tcp)
1866f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar{
1874f63c113887a738a06e4bd35c7f867e975793f91Dmitry V. Levin	const unsigned int code = tcp->u_arg[1];
1884f63c113887a738a06e4bd35c7f867e975793f91Dmitry V. Levin
1892803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin	switch (_IOC_TYPE(code)) {
1906f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 'E':
1912803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			return evdev_decode_number(code);
1926f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 'H':
1932803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			return hiddev_decode_number(code);
1946f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 'M':
1952803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			if (_IOC_DIR(code) == _IOC_WRITE) {
1962803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("MIXER_WRITE(%u)", _IOC_NR(code));
1976f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
1982803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			} else if (_IOC_DIR(code) == _IOC_READ) {
1992803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("MIXER_READ(%u)", _IOC_NR(code));
2006f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
2016f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			}
2026f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 0;
2036f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 'U':
2042803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x2c) {
2052803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(code));
2066f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
2076f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			}
2086f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 0;
2096f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 'j':
2102803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x13) {
2112803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("JSIOCGNAME(%u)", _IOC_SIZE(code));
2126f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
2136f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			}
2146f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 0;
2156f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		case 'k':
2162803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin			if (_IOC_DIR(code) == _IOC_WRITE && _IOC_NR(code) == 0) {
2172803e75450880e1d0588872f8a327e51fabe79f8Dmitry V. Levin				tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(code));
2186f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar				return 1;
2196f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			}
2206f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 0;
2216f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar		default:
2226f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar			return 0;
2236f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar	}
2246f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar}
2256f9a01c72121bc0b0fc760d9fea6879fb85f6f02Gabriel Laskar
226044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levinstatic int
227802c942a36df694d83e8f707e5c07527a53c04d0Dmitry V. Levinioctl_decode(struct tcb *tcp)
22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
229802c942a36df694d83e8f707e5c07527a53c04d0Dmitry V. Levin	const unsigned int code = tcp->u_arg[1];
230d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes	const kernel_ulong_t arg = tcp->u_arg[2];
231802c942a36df694d83e8f707e5c07527a53c04d0Dmitry V. Levin
232c7afb4881f14e44968f3a78ae5988f04ecc66b68Dmitry V. Levin	switch (_IOC_TYPE(code)) {
233bb3af52962a322da7cb13966ae66ab9fa5b314d4Roland McGrath#if defined(ALPHA) || defined(POWERPC)
23425f375851087f7340305f7e64452edd6c28be21eDmitry V. Levin	case 'f': {
23525f375851087f7340305f7e64452edd6c28be21eDmitry V. Levin		int ret = file_ioctl(tcp, code, arg);
236398fe0493ee0da44fecd98d0c72fab3627060953Jeff Mahoney		if (ret != RVAL_DECODED)
237398fe0493ee0da44fecd98d0c72fab3627060953Jeff Mahoney			return ret;
23825f375851087f7340305f7e64452edd6c28be21eDmitry V. Levin	}
23925f375851087f7340305f7e64452edd6c28be21eDmitry V. Levin	case 't':
240398fe0493ee0da44fecd98d0c72fab3627060953Jeff Mahoney	case 'T':
241398fe0493ee0da44fecd98d0c72fab3627060953Jeff Mahoney		return term_ioctl(tcp, code, arg);
24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !ALPHA */
243398fe0493ee0da44fecd98d0c72fab3627060953Jeff Mahoney	case 'f':
244398fe0493ee0da44fecd98d0c72fab3627060953Jeff Mahoney		return file_ioctl(tcp, code, arg);
24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	case 0x54:
24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !ALPHA */
24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return term_ioctl(tcp, code, arg);
24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	case 0x89:
24976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		return sock_ioctl(tcp, code, arg);
250d83c50b8e44db2a2e19d048ab7d1e1caf1fa1996Roland McGrath	case 'p':
251d83c50b8e44db2a2e19d048ab7d1e1caf1fa1996Roland McGrath		return rtc_ioctl(tcp, code, arg);
2524ef6db489a8a51ae03ffb78b58c679162a39f3c3Dmitry V. Levin	case 0x03:
253b3f00403c30e2c268d4a7b8d8b37e26f32f41d78Dmitry V. Levin		return hdio_ioctl(tcp, code, arg);
2544ef6db489a8a51ae03ffb78b58c679162a39f3c3Dmitry V. Levin	case 0x12:
2554ef6db489a8a51ae03ffb78b58c679162a39f3c3Dmitry V. Levin		return block_ioctl(tcp, code, arg);
2564dd9f3f038683e9b3b92539c204d6009121dd77aDmitry V. Levin	case 'X':
2574dd9f3f038683e9b3b92539c204d6009121dd77aDmitry V. Levin		return fs_x_ioctl(tcp, code, arg);
258b011af5ef077fcfc2ad967579dcb1e5ed9b3193eDmitry V. Levin	case 0x22:
259b011af5ef077fcfc2ad967579dcb1e5ed9b3193eDmitry V. Levin		return scsi_ioctl(tcp, code, arg);
260ebee04cfb009bdc46599774b4647f6615b6ce3a2Mike Frysinger	case 'L':
261ebee04cfb009bdc46599774b4647f6615b6ce3a2Mike Frysinger		return loop_ioctl(tcp, code, arg);
2620cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger	case 'M':
2630cbed357ab749fa0cf58e8d72230c2ed92334932Mike Frysinger		return mtd_ioctl(tcp, code, arg);
264d648f29cc3aeabf0a0430f8ab12ce35fa6c4e48eMike Frysinger	case 'o':
265d648f29cc3aeabf0a0430f8ab12ce35fa6c4e48eMike Frysinger	case 'O':
266d648f29cc3aeabf0a0430f8ab12ce35fa6c4e48eMike Frysinger		return ubi_ioctl(tcp, code, arg);
2670cc961440b527ff8c16954fc411a1529072edb92Philippe De Muyter	case 'V':
2680cc961440b527ff8c16954fc411a1529072edb92Philippe De Muyter		return v4l2_ioctl(tcp, code, arg);
269b88a6f877eb08e6d45130374fc1a1867371db703Stefan Sørensen	case '=':
270b88a6f877eb08e6d45130374fc1a1867371db703Stefan Sørensen		return ptp_ioctl(tcp, code, arg);
2714f750b9ad1bb870337395355047ac2f89f340febEtienne Gemsa#ifdef HAVE_LINUX_INPUT_H
2724f750b9ad1bb870337395355047ac2f89f340febEtienne Gemsa	case 'E':
2734f750b9ad1bb870337395355047ac2f89f340febEtienne Gemsa		return evdev_ioctl(tcp, code, arg);
2744f750b9ad1bb870337395355047ac2f89f340febEtienne Gemsa#endif
2755d1216a56b3218716cc8192cb08a3a3e817ea57dDr. David Alan Gilbert#ifdef HAVE_LINUX_USERFAULTFD_H
2765d1216a56b3218716cc8192cb08a3a3e817ea57dDr. David Alan Gilbert	case 0xaa:
2775d1216a56b3218716cc8192cb08a3a3e817ea57dDr. David Alan Gilbert		return uffdio_ioctl(tcp, code, arg);
2785d1216a56b3218716cc8192cb08a3a3e817ea57dDr. David Alan Gilbert#endif
2798cc6962216d302525be2ba4575932061bb4abd15Jeff Mahoney#ifdef HAVE_LINUX_BTRFS_H
2808cc6962216d302525be2ba4575932061bb4abd15Jeff Mahoney	case 0x94:
2818cc6962216d302525be2ba4575932061bb4abd15Jeff Mahoney		return btrfs_ioctl(tcp, code, arg);
2828cc6962216d302525be2ba4575932061bb4abd15Jeff Mahoney#endif
283d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#ifdef HAVE_LINUX_DM_IOCTL_H
284d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes	case 0xfd:
285d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes		return dm_ioctl(tcp, code, arg);
286d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#endif
28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	default:
28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		break;
28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return 0;
29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
292044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin
293044eef21867521a9d0340015dc673f2f5909e804Dmitry V. LevinSYS_FUNC(ioctl)
294044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin{
295044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin	const struct_ioctlent *iop;
296204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin	int ret;
297044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin
298044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin	if (entering(tcp)) {
299044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin		printfd(tcp, tcp->u_arg[0]);
300044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin		tprints(", ");
3019c4fc3404cff4c58b7c9707c85da9661f87131c7Gabriel Laskar		ret = ioctl_decode_command_number(tcp);
3028b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar		if (!(ret & IOCTL_NUMBER_STOP_LOOKUP)) {
3038b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar			iop = ioctl_lookup(tcp->u_arg[1]);
3048b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar			if (iop) {
3058b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar				if (ret)
3068b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar					tprints(" or ");
3078b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar				tprints(iop->symbol);
3088b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar				while ((iop = ioctl_next_match(iop)))
3098b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar					tprintf(" or %s", iop->symbol);
3108b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar			} else if (!ret) {
3118b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar				ioctl_print_code(tcp->u_arg[1]);
3128b6046a052255fe71fac200f0f7b3b76419dc16dGabriel Laskar			}
313044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin		}
314204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin		ret = ioctl_decode(tcp);
315204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin	} else {
316204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin		ret = ioctl_decode(tcp) | RVAL_DECODED;
317044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin	}
318204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin
319204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin	if (ret & RVAL_DECODED) {
320204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin		ret &= ~RVAL_DECODED;
321204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin		if (ret)
322204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin			--ret;
323044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin		else
324d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes			tprintf(", %#" PRI_klx, tcp->u_arg[2]);
325204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin		ret |= RVAL_DECODED;
326204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin	} else {
327204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin		if (ret)
328204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin			--ret;
329044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin	}
330204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin
331204c2bc9cb50daf4d3c8b5067a57c071ef55dfc4Dmitry V. Levin	return ret;
332044eef21867521a9d0340015dc673f2f5909e804Dmitry V. Levin}
333