1*640235e2SEnji Cooper /* $NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $ */ 2*640235e2SEnji Cooper 3*640235e2SEnji Cooper /* 4*640235e2SEnji Cooper * Copyright (c) 2016 Jonathan A. Kollasch 5*640235e2SEnji Cooper * All rights reserved. 6*640235e2SEnji Cooper * 7*640235e2SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*640235e2SEnji Cooper * modification, are permitted provided that the following conditions 9*640235e2SEnji Cooper * are met: 10*640235e2SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*640235e2SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*640235e2SEnji Cooper * documentation and/or other materials provided with the distribution. 15*640235e2SEnji Cooper * 16*640235e2SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17*640235e2SEnji Cooper * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*640235e2SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*640235e2SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20*640235e2SEnji Cooper * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21*640235e2SEnji Cooper * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22*640235e2SEnji Cooper * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23*640235e2SEnji Cooper * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24*640235e2SEnji Cooper * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25*640235e2SEnji Cooper * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26*640235e2SEnji Cooper * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*640235e2SEnji Cooper */ 28*640235e2SEnji Cooper 29*640235e2SEnji Cooper #include <sys/cdefs.h> 30*640235e2SEnji Cooper __RCSID("$NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $"); 31*640235e2SEnji Cooper 32*640235e2SEnji Cooper #include <machine/types.h> 33*640235e2SEnji Cooper #include <stdlib.h> 34*640235e2SEnji Cooper #include <string.h> 35*640235e2SEnji Cooper #include <stdio.h> 36*640235e2SEnji Cooper #include <atf-c.h> 37*640235e2SEnji Cooper 38*640235e2SEnji Cooper #include <rump/rump.h> 39*640235e2SEnji Cooper 40*640235e2SEnji Cooper #define hid_start_parse rumpns_hid_start_parse 41*640235e2SEnji Cooper #define hid_end_parse rumpns_hid_end_parse 42*640235e2SEnji Cooper #define hid_get_item rumpns_hid_get_item 43*640235e2SEnji Cooper #define hid_locate rumpns_hid_locate 44*640235e2SEnji Cooper #define hid_report_size rumpns_hid_report_size 45*640235e2SEnji Cooper #define hid_get_data rumpns_hid_get_data 46*640235e2SEnji Cooper #define hid_get_udata rumpns_hid_get_udata 47*640235e2SEnji Cooper #define uhidevdebug rumpns_uhidevdebug 48*640235e2SEnji Cooper #include <usb.h> 49*640235e2SEnji Cooper #include <usbhid.h> 50*640235e2SEnji Cooper #include <hid.h> 51*640235e2SEnji Cooper 52*640235e2SEnji Cooper #include "../../lib/libusbhid/hid_test_data.c" 53*640235e2SEnji Cooper 54*640235e2SEnji Cooper #define MYd_ATF_CHECK_EQ(d, v) \ 55*640235e2SEnji Cooper ATF_CHECK_EQ_MSG(d, v, "== %d", (d)) 56*640235e2SEnji Cooper 57*640235e2SEnji Cooper #define MYld_ATF_CHECK_EQ(d, v) \ 58*640235e2SEnji Cooper ATF_CHECK_EQ_MSG(d, v, "== %ld", (d)) 59*640235e2SEnji Cooper 60*640235e2SEnji Cooper #define MYu_ATF_CHECK_EQ(d, v) \ 61*640235e2SEnji Cooper ATF_CHECK_EQ_MSG(d, v, "== %u", (d)) 62*640235e2SEnji Cooper 63*640235e2SEnji Cooper #define MYlu_ATF_CHECK_EQ(d, v) \ 64*640235e2SEnji Cooper ATF_CHECK_EQ_MSG(d, v, "== %lu", (d)) 65*640235e2SEnji Cooper 66*640235e2SEnji Cooper #define MYx_ATF_CHECK_EQ(d, v) \ 67*640235e2SEnji Cooper ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d)) 68*640235e2SEnji Cooper 69*640235e2SEnji Cooper #define MYlx_ATF_CHECK_EQ(d, v) \ 70*640235e2SEnji Cooper ATF_CHECK_EQ_MSG(d, v, "== 0x%lx", (d)) 71*640235e2SEnji Cooper 72*640235e2SEnji Cooper int uhidevdebug; 73*640235e2SEnji Cooper 74*640235e2SEnji Cooper ATF_TC(khid); 75*640235e2SEnji Cooper 76*640235e2SEnji Cooper ATF_TC_HEAD(khid, tc) 77*640235e2SEnji Cooper { 78*640235e2SEnji Cooper 79*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "check kernel hid.c"); 80*640235e2SEnji Cooper } 81*640235e2SEnji Cooper 82*640235e2SEnji Cooper static int 83*640235e2SEnji Cooper locate_item(const void *desc, int size, u_int32_t u, u_int8_t id, 84*640235e2SEnji Cooper enum hid_kind k, struct hid_item *hip) 85*640235e2SEnji Cooper { 86*640235e2SEnji Cooper struct hid_data *d; 87*640235e2SEnji Cooper struct hid_item h; 88*640235e2SEnji Cooper 89*640235e2SEnji Cooper h.report_ID = 0; 90*640235e2SEnji Cooper for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) { 91*640235e2SEnji Cooper if (h.kind == k && !(h.flags & HIO_CONST) && 92*640235e2SEnji Cooper (/*XXX*/uint32_t)h.usage == u && h.report_ID == id) { 93*640235e2SEnji Cooper if (hip != NULL) 94*640235e2SEnji Cooper *hip = h; 95*640235e2SEnji Cooper hid_end_parse(d); 96*640235e2SEnji Cooper return (1); 97*640235e2SEnji Cooper } 98*640235e2SEnji Cooper } 99*640235e2SEnji Cooper hid_end_parse(d); 100*640235e2SEnji Cooper return (0); 101*640235e2SEnji Cooper } 102*640235e2SEnji Cooper 103*640235e2SEnji Cooper ATF_TC_BODY(khid, tc) 104*640235e2SEnji Cooper { 105*640235e2SEnji Cooper int ret; 106*640235e2SEnji Cooper struct hid_item hi; 107*640235e2SEnji Cooper 108*640235e2SEnji Cooper uhidevdebug = 0; 109*640235e2SEnji Cooper 110*640235e2SEnji Cooper rump_init(); 111*640235e2SEnji Cooper 112*640235e2SEnji Cooper rump_schedule(); 113*640235e2SEnji Cooper 114*640235e2SEnji Cooper ret = locate_item(range_test_report_descriptor, 115*640235e2SEnji Cooper sizeof(range_test_report_descriptor), 0xff000003, 0, hid_input, 116*640235e2SEnji Cooper &hi); 117*640235e2SEnji Cooper ATF_REQUIRE(ret > 0); 118*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.size, 32); 119*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.count, 1); 120*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.pos, 0); 121*640235e2SEnji Cooper MYx_ATF_CHECK_EQ(hi.flags, 0); 122*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648); 123*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647); 124*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648); 125*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647); 126*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report, 127*640235e2SEnji Cooper &hi.loc), -2147483648); 128*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report, 129*640235e2SEnji Cooper &hi.loc), -1); 130*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report, 131*640235e2SEnji Cooper &hi.loc), 1); 132*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report, 133*640235e2SEnji Cooper &hi.loc), 2147483647); 134*640235e2SEnji Cooper 135*640235e2SEnji Cooper ret = locate_item(range_test_report_descriptor, 136*640235e2SEnji Cooper sizeof(range_test_report_descriptor), 0xff000002, 0, hid_input, 137*640235e2SEnji Cooper &hi); 138*640235e2SEnji Cooper ATF_REQUIRE(ret > 0); 139*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.size, 16); 140*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.count, 1); 141*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.pos, 32); 142*640235e2SEnji Cooper MYx_ATF_CHECK_EQ(hi.flags, 0); 143*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768); 144*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767); 145*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768); 146*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767); 147*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report, 148*640235e2SEnji Cooper &hi.loc), -32768); 149*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report, 150*640235e2SEnji Cooper &hi.loc), -1); 151*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report, 152*640235e2SEnji Cooper &hi.loc), 1); 153*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report, 154*640235e2SEnji Cooper &hi.loc), 32767); 155*640235e2SEnji Cooper 156*640235e2SEnji Cooper ret = locate_item(range_test_report_descriptor, 157*640235e2SEnji Cooper sizeof(range_test_report_descriptor), 0xff000001, 0, hid_input, 158*640235e2SEnji Cooper &hi); 159*640235e2SEnji Cooper ATF_REQUIRE(ret > 0); 160*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.size, 8); 161*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.count, 1); 162*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.pos, 48); 163*640235e2SEnji Cooper MYx_ATF_CHECK_EQ(hi.flags, 0); 164*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.logical_minimum, -128); 165*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.logical_maximum, 127); 166*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.physical_minimum, -128); 167*640235e2SEnji Cooper MYd_ATF_CHECK_EQ(hi.physical_maximum, 127); 168*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report, 169*640235e2SEnji Cooper &hi.loc), -128); 170*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report, 171*640235e2SEnji Cooper &hi.loc), -1); 172*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report, 173*640235e2SEnji Cooper &hi.loc), 1); 174*640235e2SEnji Cooper MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report, 175*640235e2SEnji Cooper &hi.loc), 127); 176*640235e2SEnji Cooper 177*640235e2SEnji Cooper 178*640235e2SEnji Cooper ret = locate_item(unsigned_range_test_report_descriptor, 179*640235e2SEnji Cooper sizeof(unsigned_range_test_report_descriptor), 0xff000013, 0, 180*640235e2SEnji Cooper hid_input, &hi); 181*640235e2SEnji Cooper ATF_REQUIRE(ret > 0); 182*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.size, 32); 183*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.count, 1); 184*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.pos, 0); 185*640235e2SEnji Cooper MYx_ATF_CHECK_EQ(hi.flags, 0); 186*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report, 187*640235e2SEnji Cooper &hi.loc), 0x0); 188*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report, 189*640235e2SEnji Cooper &hi.loc), 0x1); 190*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report, 191*640235e2SEnji Cooper &hi.loc), 0xfffffffe); 192*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report, 193*640235e2SEnji Cooper &hi.loc), 0xffffffff); 194*640235e2SEnji Cooper 195*640235e2SEnji Cooper ret = locate_item(unsigned_range_test_report_descriptor, 196*640235e2SEnji Cooper sizeof(unsigned_range_test_report_descriptor), 0xff000012, 0, 197*640235e2SEnji Cooper hid_input, &hi); 198*640235e2SEnji Cooper ATF_REQUIRE(ret > 0); 199*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.size, 16); 200*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.count, 1); 201*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.pos, 32); 202*640235e2SEnji Cooper MYx_ATF_CHECK_EQ(hi.flags, 0); 203*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report, 204*640235e2SEnji Cooper &hi.loc), 0x0); 205*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report, 206*640235e2SEnji Cooper &hi.loc), 0x1); 207*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report, 208*640235e2SEnji Cooper &hi.loc), 0xfffe); 209*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report, 210*640235e2SEnji Cooper &hi.loc), 0xffff); 211*640235e2SEnji Cooper 212*640235e2SEnji Cooper ret = locate_item(unsigned_range_test_report_descriptor, 213*640235e2SEnji Cooper sizeof(unsigned_range_test_report_descriptor), 0xff000011, 0, 214*640235e2SEnji Cooper hid_input, &hi); 215*640235e2SEnji Cooper ATF_REQUIRE(ret > 0); 216*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.size, 8); 217*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.count, 1); 218*640235e2SEnji Cooper MYu_ATF_CHECK_EQ(hi.loc.pos, 48); 219*640235e2SEnji Cooper MYx_ATF_CHECK_EQ(hi.flags, 0); 220*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report, 221*640235e2SEnji Cooper &hi.loc), 0x0); 222*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report, 223*640235e2SEnji Cooper &hi.loc), 0x1); 224*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report, 225*640235e2SEnji Cooper &hi.loc), 0xfe); 226*640235e2SEnji Cooper MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report, 227*640235e2SEnji Cooper &hi.loc), 0xff); 228*640235e2SEnji Cooper 229*640235e2SEnji Cooper rump_unschedule(); 230*640235e2SEnji Cooper } 231*640235e2SEnji Cooper 232*640235e2SEnji Cooper ATF_TC(khid_parse_just_pop); 233*640235e2SEnji Cooper 234*640235e2SEnji Cooper ATF_TC_HEAD(khid_parse_just_pop, tc) 235*640235e2SEnji Cooper { 236*640235e2SEnji Cooper 237*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "check kernel hid.c for " 238*640235e2SEnji Cooper "Pop on empty stack bug"); 239*640235e2SEnji Cooper } 240*640235e2SEnji Cooper 241*640235e2SEnji Cooper ATF_TC_BODY(khid_parse_just_pop, tc) 242*640235e2SEnji Cooper { 243*640235e2SEnji Cooper struct hid_data *hdp; 244*640235e2SEnji Cooper struct hid_item hi; 245*640235e2SEnji Cooper 246*640235e2SEnji Cooper rump_init(); 247*640235e2SEnji Cooper 248*640235e2SEnji Cooper rump_schedule(); 249*640235e2SEnji Cooper 250*640235e2SEnji Cooper hdp = hid_start_parse(just_pop_report_descriptor, 251*640235e2SEnji Cooper sizeof just_pop_report_descriptor, hid_none); 252*640235e2SEnji Cooper while (hid_get_item(hdp, &hi) > 0) { 253*640235e2SEnji Cooper } 254*640235e2SEnji Cooper hid_end_parse(hdp); 255*640235e2SEnji Cooper 256*640235e2SEnji Cooper rump_unschedule(); 257*640235e2SEnji Cooper } 258*640235e2SEnji Cooper 259*640235e2SEnji Cooper ATF_TP_ADD_TCS(tp) 260*640235e2SEnji Cooper { 261*640235e2SEnji Cooper 262*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, khid); 263*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, khid_parse_just_pop); 264*640235e2SEnji Cooper 265*640235e2SEnji Cooper return atf_no_error(); 266*640235e2SEnji Cooper } 267*640235e2SEnji Cooper 268