xref: /netbsd-src/tests/dev/usb/t_hid.c (revision 2d9fbba46cdaf809da07121f9c2b35e82e48a924)
1*2d9fbba4Sjakllsch /*	$NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $	*/
22ba22c93Sjakllsch 
32ba22c93Sjakllsch /*
42ba22c93Sjakllsch  * Copyright (c) 2016 Jonathan A. Kollasch
52ba22c93Sjakllsch  * All rights reserved.
62ba22c93Sjakllsch  *
72ba22c93Sjakllsch  * Redistribution and use in source and binary forms, with or without
82ba22c93Sjakllsch  * modification, are permitted provided that the following conditions
92ba22c93Sjakllsch  * are met:
102ba22c93Sjakllsch  * 1. Redistributions of source code must retain the above copyright
112ba22c93Sjakllsch  *    notice, this list of conditions and the following disclaimer.
122ba22c93Sjakllsch  * 2. Redistributions in binary form must reproduce the above copyright
132ba22c93Sjakllsch  *    notice, this list of conditions and the following disclaimer in the
142ba22c93Sjakllsch  *    documentation and/or other materials provided with the distribution.
152ba22c93Sjakllsch  *
162ba22c93Sjakllsch  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172ba22c93Sjakllsch  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
182ba22c93Sjakllsch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
192ba22c93Sjakllsch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
202ba22c93Sjakllsch  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
212ba22c93Sjakllsch  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
222ba22c93Sjakllsch  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
232ba22c93Sjakllsch  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
242ba22c93Sjakllsch  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
252ba22c93Sjakllsch  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
262ba22c93Sjakllsch  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272ba22c93Sjakllsch  */
282ba22c93Sjakllsch 
292ba22c93Sjakllsch #include <sys/cdefs.h>
30*2d9fbba4Sjakllsch __RCSID("$NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $");
312ba22c93Sjakllsch 
322ba22c93Sjakllsch #include <machine/types.h>
332ba22c93Sjakllsch #include <stdlib.h>
342ba22c93Sjakllsch #include <string.h>
352ba22c93Sjakllsch #include <stdio.h>
362ba22c93Sjakllsch #include <atf-c.h>
37ffe5c1f1Sjakllsch 
38ffe5c1f1Sjakllsch #include <rump/rump.h>
39ffe5c1f1Sjakllsch 
402ba22c93Sjakllsch #define hid_start_parse rumpns_hid_start_parse
412ba22c93Sjakllsch #define hid_end_parse rumpns_hid_end_parse
422ba22c93Sjakllsch #define hid_get_item rumpns_hid_get_item
432ba22c93Sjakllsch #define hid_locate rumpns_hid_locate
442ba22c93Sjakllsch #define hid_report_size rumpns_hid_report_size
452ba22c93Sjakllsch #define hid_get_data rumpns_hid_get_data
462ba22c93Sjakllsch #define hid_get_udata rumpns_hid_get_udata
472ba22c93Sjakllsch #define uhidevdebug rumpns_uhidevdebug
4803e19f65Sjakllsch #include <usb.h>
4903e19f65Sjakllsch #include <usbhid.h>
502ba22c93Sjakllsch #include <hid.h>
512ba22c93Sjakllsch 
522ba22c93Sjakllsch #include "../../lib/libusbhid/hid_test_data.c"
532ba22c93Sjakllsch 
542ba22c93Sjakllsch #define MYd_ATF_CHECK_EQ(d, v) \
552ba22c93Sjakllsch 	ATF_CHECK_EQ_MSG(d, v, "== %d", (d))
562ba22c93Sjakllsch 
572ba22c93Sjakllsch #define MYld_ATF_CHECK_EQ(d, v) \
582ba22c93Sjakllsch 	ATF_CHECK_EQ_MSG(d, v, "== %ld", (d))
592ba22c93Sjakllsch 
602ba22c93Sjakllsch #define MYu_ATF_CHECK_EQ(d, v) \
612ba22c93Sjakllsch 	ATF_CHECK_EQ_MSG(d, v, "== %u", (d))
622ba22c93Sjakllsch 
632ba22c93Sjakllsch #define MYlu_ATF_CHECK_EQ(d, v) \
642ba22c93Sjakllsch 	ATF_CHECK_EQ_MSG(d, v, "== %lu", (d))
652ba22c93Sjakllsch 
662ba22c93Sjakllsch #define MYx_ATF_CHECK_EQ(d, v) \
672ba22c93Sjakllsch 	ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d))
682ba22c93Sjakllsch 
692ba22c93Sjakllsch #define MYlx_ATF_CHECK_EQ(d, v) \
702ba22c93Sjakllsch 	ATF_CHECK_EQ_MSG(d, v, "== 0x%lx", (d))
712ba22c93Sjakllsch 
722ba22c93Sjakllsch int uhidevdebug;
732ba22c93Sjakllsch 
742ba22c93Sjakllsch ATF_TC(khid);
752ba22c93Sjakllsch 
ATF_TC_HEAD(khid,tc)762ba22c93Sjakllsch ATF_TC_HEAD(khid, tc)
772ba22c93Sjakllsch {
782ba22c93Sjakllsch 
792ba22c93Sjakllsch         atf_tc_set_md_var(tc, "descr", "check kernel hid.c");
802ba22c93Sjakllsch }
812ba22c93Sjakllsch 
8203e19f65Sjakllsch static int
locate_item(const void * desc,int size,u_int32_t u,u_int8_t id,enum hid_kind k,struct hid_item * hip)8303e19f65Sjakllsch locate_item(const void *desc, int size, u_int32_t u, u_int8_t id,
84c38078a2Sjakllsch     enum hid_kind k, struct hid_item *hip)
8503e19f65Sjakllsch {
8603e19f65Sjakllsch 	struct hid_data *d;
8703e19f65Sjakllsch 	struct hid_item h;
8803e19f65Sjakllsch 
8903e19f65Sjakllsch 	h.report_ID = 0;
9003e19f65Sjakllsch 	for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
9103e19f65Sjakllsch 		if (h.kind == k && !(h.flags & HIO_CONST) &&
9203e19f65Sjakllsch 		    (/*XXX*/uint32_t)h.usage == u && h.report_ID == id) {
9303e19f65Sjakllsch 			if (hip != NULL)
9403e19f65Sjakllsch 				*hip = h;
9503e19f65Sjakllsch 			hid_end_parse(d);
9603e19f65Sjakllsch 			return (1);
9703e19f65Sjakllsch 		}
9803e19f65Sjakllsch 	}
9903e19f65Sjakllsch 	hid_end_parse(d);
10003e19f65Sjakllsch 	return (0);
10103e19f65Sjakllsch }
10203e19f65Sjakllsch 
ATF_TC_BODY(khid,tc)1032ba22c93Sjakllsch ATF_TC_BODY(khid, tc)
1042ba22c93Sjakllsch {
1052ba22c93Sjakllsch 	int ret;
1062ba22c93Sjakllsch 	struct hid_item hi;
1072ba22c93Sjakllsch 
1082ba22c93Sjakllsch 	uhidevdebug = 0;
1092ba22c93Sjakllsch 
110ffe5c1f1Sjakllsch 	rump_init();
111ffe5c1f1Sjakllsch 
112*2d9fbba4Sjakllsch 	rump_schedule();
113*2d9fbba4Sjakllsch 
11403e19f65Sjakllsch 	ret = locate_item(range_test_report_descriptor,
1152ba22c93Sjakllsch 	    sizeof(range_test_report_descriptor), 0xff000003, 0, hid_input,
116c38078a2Sjakllsch 	    &hi);
1172ba22c93Sjakllsch 	ATF_REQUIRE(ret > 0);
1182ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.size, 32);
1192ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
1202ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
121c38078a2Sjakllsch 	MYx_ATF_CHECK_EQ(hi.flags, 0);
1222ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648);
1232ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647);
1242ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648);
1252ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647);
1262ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
1272ba22c93Sjakllsch 	    &hi.loc), -2147483648);
1282ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
1292ba22c93Sjakllsch 	    &hi.loc), -1);
1302ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
1312ba22c93Sjakllsch 	    &hi.loc), 1);
1322ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
1332ba22c93Sjakllsch 	    &hi.loc), 2147483647);
1342ba22c93Sjakllsch 
13503e19f65Sjakllsch 	ret = locate_item(range_test_report_descriptor,
1362ba22c93Sjakllsch 	    sizeof(range_test_report_descriptor), 0xff000002, 0, hid_input,
137c38078a2Sjakllsch 	    &hi);
1382ba22c93Sjakllsch 	ATF_REQUIRE(ret > 0);
1392ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.size, 16);
1402ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
1412ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
142c38078a2Sjakllsch 	MYx_ATF_CHECK_EQ(hi.flags, 0);
1432ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768);
1442ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767);
1452ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768);
1462ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767);
1472ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
1482ba22c93Sjakllsch 	    &hi.loc), -32768);
1492ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
1502ba22c93Sjakllsch 	    &hi.loc), -1);
1512ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
1522ba22c93Sjakllsch 	    &hi.loc), 1);
1532ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
1542ba22c93Sjakllsch 	    &hi.loc), 32767);
1552ba22c93Sjakllsch 
15603e19f65Sjakllsch 	ret = locate_item(range_test_report_descriptor,
1572ba22c93Sjakllsch 	    sizeof(range_test_report_descriptor), 0xff000001, 0, hid_input,
158c38078a2Sjakllsch 	    &hi);
1592ba22c93Sjakllsch 	ATF_REQUIRE(ret > 0);
1602ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.size, 8);
1612ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
1622ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
163c38078a2Sjakllsch 	MYx_ATF_CHECK_EQ(hi.flags, 0);
1642ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.logical_minimum, -128);
1652ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.logical_maximum, 127);
1662ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.physical_minimum, -128);
1672ba22c93Sjakllsch 	MYd_ATF_CHECK_EQ(hi.physical_maximum, 127);
1682ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report,
1692ba22c93Sjakllsch 	    &hi.loc), -128);
1702ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report,
1712ba22c93Sjakllsch 	    &hi.loc), -1);
1722ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report,
1732ba22c93Sjakllsch 	    &hi.loc), 1);
1742ba22c93Sjakllsch 	MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report,
1752ba22c93Sjakllsch 	    &hi.loc), 127);
1762ba22c93Sjakllsch 
1772ba22c93Sjakllsch 
17803e19f65Sjakllsch 	ret = locate_item(unsigned_range_test_report_descriptor,
1792ba22c93Sjakllsch 	    sizeof(unsigned_range_test_report_descriptor), 0xff000013, 0,
180c38078a2Sjakllsch 	    hid_input, &hi);
1812ba22c93Sjakllsch 	ATF_REQUIRE(ret > 0);
1822ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.size, 32);
1832ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
1842ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.pos, 0);
185c38078a2Sjakllsch 	MYx_ATF_CHECK_EQ(hi.flags, 0);
1862ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
1872ba22c93Sjakllsch 	    &hi.loc), 0x0);
1882ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
1892ba22c93Sjakllsch 	    &hi.loc), 0x1);
1902ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
1912ba22c93Sjakllsch 	    &hi.loc), 0xfffffffe);
1922ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
1932ba22c93Sjakllsch 	    &hi.loc), 0xffffffff);
1942ba22c93Sjakllsch 
19503e19f65Sjakllsch 	ret = locate_item(unsigned_range_test_report_descriptor,
1962ba22c93Sjakllsch 	    sizeof(unsigned_range_test_report_descriptor), 0xff000012, 0,
197c38078a2Sjakllsch 	    hid_input, &hi);
1982ba22c93Sjakllsch 	ATF_REQUIRE(ret > 0);
1992ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.size, 16);
2002ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
2012ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.pos, 32);
202c38078a2Sjakllsch 	MYx_ATF_CHECK_EQ(hi.flags, 0);
2032ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
2042ba22c93Sjakllsch 	    &hi.loc), 0x0);
2052ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
2062ba22c93Sjakllsch 	    &hi.loc), 0x1);
2072ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
2082ba22c93Sjakllsch 	    &hi.loc), 0xfffe);
2092ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
2102ba22c93Sjakllsch 	    &hi.loc), 0xffff);
2112ba22c93Sjakllsch 
21203e19f65Sjakllsch 	ret = locate_item(unsigned_range_test_report_descriptor,
2132ba22c93Sjakllsch 	    sizeof(unsigned_range_test_report_descriptor), 0xff000011, 0,
214c38078a2Sjakllsch 	    hid_input, &hi);
2152ba22c93Sjakllsch 	ATF_REQUIRE(ret > 0);
2162ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.size, 8);
2172ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.count, 1);
2182ba22c93Sjakllsch 	MYu_ATF_CHECK_EQ(hi.loc.pos, 48);
219c38078a2Sjakllsch 	MYx_ATF_CHECK_EQ(hi.flags, 0);
2202ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report,
2212ba22c93Sjakllsch 	    &hi.loc), 0x0);
2222ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report,
2232ba22c93Sjakllsch 	    &hi.loc), 0x1);
2242ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report,
2252ba22c93Sjakllsch 	    &hi.loc), 0xfe);
2262ba22c93Sjakllsch 	MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report,
2272ba22c93Sjakllsch 	    &hi.loc), 0xff);
228*2d9fbba4Sjakllsch 
229*2d9fbba4Sjakllsch 	rump_unschedule();
2302ba22c93Sjakllsch }
2312ba22c93Sjakllsch 
2324887406fSjakllsch ATF_TC(khid_parse_just_pop);
2334887406fSjakllsch 
ATF_TC_HEAD(khid_parse_just_pop,tc)2344887406fSjakllsch ATF_TC_HEAD(khid_parse_just_pop, tc)
2354887406fSjakllsch {
2364887406fSjakllsch 
2374887406fSjakllsch         atf_tc_set_md_var(tc, "descr", "check kernel hid.c for "
2384887406fSjakllsch 	    "Pop on empty stack bug");
2394887406fSjakllsch }
2404887406fSjakllsch 
ATF_TC_BODY(khid_parse_just_pop,tc)2414887406fSjakllsch ATF_TC_BODY(khid_parse_just_pop, tc)
2424887406fSjakllsch {
2434887406fSjakllsch 	struct hid_data *hdp;
2444887406fSjakllsch 	struct hid_item hi;
2454887406fSjakllsch 
246ffe5c1f1Sjakllsch 	rump_init();
247ffe5c1f1Sjakllsch 
248*2d9fbba4Sjakllsch 	rump_schedule();
249*2d9fbba4Sjakllsch 
2504887406fSjakllsch 	hdp = hid_start_parse(just_pop_report_descriptor,
2514887406fSjakllsch 	    sizeof just_pop_report_descriptor, hid_none);
2524887406fSjakllsch 	while (hid_get_item(hdp, &hi) > 0) {
2534887406fSjakllsch 	}
2544887406fSjakllsch 	hid_end_parse(hdp);
255*2d9fbba4Sjakllsch 
256*2d9fbba4Sjakllsch 	rump_unschedule();
2574887406fSjakllsch }
2584887406fSjakllsch 
ATF_TP_ADD_TCS(tp)2592ba22c93Sjakllsch ATF_TP_ADD_TCS(tp)
2602ba22c93Sjakllsch {
2612ba22c93Sjakllsch 
2622ba22c93Sjakllsch         ATF_TP_ADD_TC(tp, khid);
2634887406fSjakllsch         ATF_TP_ADD_TC(tp, khid_parse_just_pop);
2642ba22c93Sjakllsch 
2652ba22c93Sjakllsch 	return atf_no_error();
2662ba22c93Sjakllsch }
2672ba22c93Sjakllsch 
268