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