1/* $NetBSD: parse.c,v 1.11 2000/09/24 02:19:54 augustss Exp $ */ 2 3/*
| 1/* $NetBSD: parse.c,v 1.11 2000/09/24 02:19:54 augustss Exp $ */ 2 3/*
|
4 * Copyright (c) 1999 Lennart Augustsson
| 4 * Copyright (c) 1999, 2001 Lennart Augustsson <augustss@netbsd.org>
|
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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h>
| 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h>
|
30__FBSDID("$FreeBSD: head/lib/libusbhid/parse.c 113193 2003-04-07 00:49:53Z mdodd $");
| 30__FBSDID("$FreeBSD: head/lib/libusbhid/parse.c 113273 2003-04-09 01:52:49Z mdodd $");
|
31 32#include <assert.h> 33#include <stdlib.h> 34#include <string.h> 35#include <sys/time.h> 36 37#include <dev/usb/usb.h> 38#include <dev/usb/usbhid.h> 39
| 31 32#include <assert.h> 33#include <stdlib.h> 34#include <string.h> 35#include <sys/time.h> 36 37#include <dev/usb/usb.h> 38#include <dev/usb/usbhid.h> 39
|
40#include "libusbhid.h"
| 40#include "usbhid.h"
|
41#include "usbvar.h" 42 43#define MAXUSAGE 100 44struct hid_data { 45 u_char *start; 46 u_char *end; 47 u_char *p; 48 hid_item_t cur; 49 unsigned int usages[MAXUSAGE]; 50 int nusage; 51 int minset;
| 41#include "usbvar.h" 42 43#define MAXUSAGE 100 44struct hid_data { 45 u_char *start; 46 u_char *end; 47 u_char *p; 48 hid_item_t cur; 49 unsigned int usages[MAXUSAGE]; 50 int nusage; 51 int minset;
|
| 52 int logminsize;
|
52 int multi; 53 int multimax; 54 int kindset;
| 53 int multi; 54 int multimax; 55 int kindset;
|
| 56 int reportid;
|
55
| 57
|
56 /* Absolute data position (bits) for input/output/feature. 57 Assumes that hid_input, hid_output and hid_feature have 58 values 0, 1 and 2. */ 59 unsigned int kindpos[3];
| 58 /* 59 * The start of collection item has no report ID set, so save 60 * it until we know the ID. 61 */ 62 hid_item_t savedcoll; 63 u_char hassavedcoll; 64 /* 65 * Absolute data position (bits) for input/output/feature. 66 * Assumes that hid_input, hid_output and hid_feature have 67 * values 0, 1 and 2. 68 */ 69 unsigned int kindpos[3];
|
60}; 61 62static int min(int x, int y) { return x < y ? x : y; } 63
| 70}; 71 72static int min(int x, int y) { return x < y ? x : y; } 73
|
| 74static int hid_get_item_raw(hid_data_t s, hid_item_t *h); 75
|
64static void 65hid_clear_local(hid_item_t *c) 66{ 67 c->usage = 0; 68 c->usage_minimum = 0; 69 c->usage_maximum = 0; 70 c->designator_index = 0; 71 c->designator_minimum = 0; 72 c->designator_maximum = 0; 73 c->string_index = 0; 74 c->string_minimum = 0; 75 c->string_maximum = 0; 76 c->set_delimiter = 0; 77 c->report_size = 0; 78} 79 80hid_data_t
| 76static void 77hid_clear_local(hid_item_t *c) 78{ 79 c->usage = 0; 80 c->usage_minimum = 0; 81 c->usage_maximum = 0; 82 c->designator_index = 0; 83 c->designator_minimum = 0; 84 c->designator_maximum = 0; 85 c->string_index = 0; 86 c->string_minimum = 0; 87 c->string_maximum = 0; 88 c->set_delimiter = 0; 89 c->report_size = 0; 90} 91 92hid_data_t
|
81hid_start_parse(report_desc_t d, int kindset)
| 93hid_start_parse(report_desc_t d, int kindset, int id)
|
82{ 83 struct hid_data *s; 84 85 s = malloc(sizeof *s); 86 memset(s, 0, sizeof *s); 87 s->start = s->p = d->data; 88 s->end = d->data + d->size; 89 s->kindset = kindset;
| 94{ 95 struct hid_data *s; 96 97 s = malloc(sizeof *s); 98 memset(s, 0, sizeof *s); 99 s->start = s->p = d->data; 100 s->end = d->data + d->size; 101 s->kindset = kindset;
|
| 102 s->reportid = id; 103 s->hassavedcoll = 0;
|
90 return (s); 91} 92 93void 94hid_end_parse(hid_data_t s) 95{ 96 while (s->cur.next) { 97 hid_item_t *hi = s->cur.next->next; 98 free(s->cur.next); 99 s->cur.next = hi; 100 } 101 free(s); 102} 103 104int 105hid_get_item(hid_data_t s, hid_item_t *h) 106{
| 104 return (s); 105} 106 107void 108hid_end_parse(hid_data_t s) 109{ 110 while (s->cur.next) { 111 hid_item_t *hi = s->cur.next->next; 112 free(s->cur.next); 113 s->cur.next = hi; 114 } 115 free(s); 116} 117 118int 119hid_get_item(hid_data_t s, hid_item_t *h) 120{
|
| 121 int r; 122 123 for (;;) { 124 r = hid_get_item_raw(s, h); 125 if (r <= 0) 126 break; 127 if (h->report_ID == s->reportid || s->reportid == -1) 128 break; 129 } 130 return (r); 131} 132 133#define REPORT_SAVED_COLL \ 134 do { \ 135 if (s->hassavedcoll) { \ 136 *h = s->savedcoll; \ 137 h->report_ID = c->report_ID; \ 138 s->hassavedcoll = 0; \ 139 return (1); \ 140 } \ 141 } while(/*LINTED*/ 0) 142 143static int 144hid_get_item_raw(hid_data_t s, hid_item_t *h) 145{
|
107 hid_item_t *c; 108 unsigned int bTag = 0, bType = 0, bSize; 109 unsigned char *data; 110 int dval; 111 unsigned char *p; 112 hid_item_t *hi;
| 146 hid_item_t *c; 147 unsigned int bTag = 0, bType = 0, bSize; 148 unsigned char *data; 149 int dval; 150 unsigned char *p; 151 hid_item_t *hi;
|
| 152 hid_item_t nc;
|
113 int i; 114 hid_kind_t retkind; 115 116 c = &s->cur; 117 118 top: 119 if (s->multimax) {
| 153 int i; 154 hid_kind_t retkind; 155 156 c = &s->cur; 157 158 top: 159 if (s->multimax) {
|
| 160 REPORT_SAVED_COLL; 161 if (c->logical_minimum >= c->logical_maximum) { 162 if (s->logminsize == 1) 163 c->logical_minimum =(int8_t)c->logical_minimum; 164 else if (s->logminsize == 2) 165 c->logical_minimum =(int16_t)c->logical_minimum; 166 }
|
120 if (s->multi < s->multimax) { 121 c->usage = s->usages[min(s->multi, s->nusage-1)]; 122 s->multi++; 123 *h = *c;
| 167 if (s->multi < s->multimax) { 168 c->usage = s->usages[min(s->multi, s->nusage-1)]; 169 s->multi++; 170 *h = *c;
|
124 125 /* 'multimax' is only non-zero if the current 126 item kind is input/output/feature */
| 171 /* 172 * 'multimax' is only non-zero if the current 173 * item kind is input/output/feature 174 */
|
127 h->pos = s->kindpos[c->kind]; 128 s->kindpos[c->kind] += c->report_size; 129 h->next = 0; 130 return (1); 131 } else { 132 c->report_count = s->multimax; 133 s->multimax = 0; 134 s->nusage = 0; 135 hid_clear_local(c); 136 } 137 } 138 for (;;) { 139 p = s->p; 140 if (p >= s->end) 141 return (0); 142 143 bSize = *p++; 144 if (bSize == 0xfe) { 145 /* long item */ 146 bSize = *p++; 147 bSize |= *p++ << 8; 148 bTag = *p++; 149 data = p; 150 p += bSize; 151 } else { 152 /* short item */ 153 bTag = bSize >> 4; 154 bType = (bSize >> 2) & 3; 155 bSize &= 3; 156 if (bSize == 3) bSize = 4; 157 data = p; 158 p += bSize; 159 } 160 s->p = p; 161 /* 162 * The spec is unclear if the data is signed or unsigned. 163 */ 164 switch(bSize) { 165 case 0: 166 dval = 0; 167 break; 168 case 1: 169 dval = (int8_t)*data++; 170 break; 171 case 2: 172 dval = *data++; 173 dval |= *data++ << 8; 174 dval = (int16_t)dval; 175 break; 176 case 4: 177 dval = *data++; 178 dval |= *data++ << 8; 179 dval |= *data++ << 16; 180 dval |= *data++ << 24; 181 break; 182 default: 183 return (-1); 184 } 185 186 switch (bType) { 187 case 0: /* Main */ 188 switch (bTag) { 189 case 8: /* Input */ 190 retkind = hid_input; 191 ret: 192 if (!(s->kindset & (1 << retkind))) { 193 /* Drop the items of this kind */ 194 s->nusage = 0; 195 continue; 196 } 197 c->kind = retkind; 198 c->flags = dval; 199 if (c->flags & HIO_VARIABLE) { 200 s->multimax = c->report_count; 201 s->multi = 0; 202 c->report_count = 1; 203 if (s->minset) { 204 for (i = c->usage_minimum; 205 i <= c->usage_maximum; 206 i++) { 207 s->usages[s->nusage] = i; 208 if (s->nusage < MAXUSAGE-1) 209 s->nusage++; 210 }
| 175 h->pos = s->kindpos[c->kind]; 176 s->kindpos[c->kind] += c->report_size; 177 h->next = 0; 178 return (1); 179 } else { 180 c->report_count = s->multimax; 181 s->multimax = 0; 182 s->nusage = 0; 183 hid_clear_local(c); 184 } 185 } 186 for (;;) { 187 p = s->p; 188 if (p >= s->end) 189 return (0); 190 191 bSize = *p++; 192 if (bSize == 0xfe) { 193 /* long item */ 194 bSize = *p++; 195 bSize |= *p++ << 8; 196 bTag = *p++; 197 data = p; 198 p += bSize; 199 } else { 200 /* short item */ 201 bTag = bSize >> 4; 202 bType = (bSize >> 2) & 3; 203 bSize &= 3; 204 if (bSize == 3) bSize = 4; 205 data = p; 206 p += bSize; 207 } 208 s->p = p; 209 /* 210 * The spec is unclear if the data is signed or unsigned. 211 */ 212 switch(bSize) { 213 case 0: 214 dval = 0; 215 break; 216 case 1: 217 dval = (int8_t)*data++; 218 break; 219 case 2: 220 dval = *data++; 221 dval |= *data++ << 8; 222 dval = (int16_t)dval; 223 break; 224 case 4: 225 dval = *data++; 226 dval |= *data++ << 8; 227 dval |= *data++ << 16; 228 dval |= *data++ << 24; 229 break; 230 default: 231 return (-1); 232 } 233 234 switch (bType) { 235 case 0: /* Main */ 236 switch (bTag) { 237 case 8: /* Input */ 238 retkind = hid_input; 239 ret: 240 if (!(s->kindset & (1 << retkind))) { 241 /* Drop the items of this kind */ 242 s->nusage = 0; 243 continue; 244 } 245 c->kind = retkind; 246 c->flags = dval; 247 if (c->flags & HIO_VARIABLE) { 248 s->multimax = c->report_count; 249 s->multi = 0; 250 c->report_count = 1; 251 if (s->minset) { 252 for (i = c->usage_minimum; 253 i <= c->usage_maximum; 254 i++) { 255 s->usages[s->nusage] = i; 256 if (s->nusage < MAXUSAGE-1) 257 s->nusage++; 258 }
|
| 259 c->usage_minimum = 0; 260 c->usage_maximum = 0;
|
211 s->minset = 0; 212 } 213 goto top; 214 } else { 215 if (s->minset) 216 c->usage = c->usage_minimum; 217 *h = *c; 218 h->next = 0; 219 h->pos = s->kindpos[c->kind];
| 261 s->minset = 0; 262 } 263 goto top; 264 } else { 265 if (s->minset) 266 c->usage = c->usage_minimum; 267 *h = *c; 268 h->next = 0; 269 h->pos = s->kindpos[c->kind];
|
220 s->kindpos[c->kind] += c->report_size * c->report_count;
| 270 s->kindpos[c->kind] += 271 c->report_size * c->report_count;
|
221 hid_clear_local(c); 222 s->minset = 0; 223 return (1); 224 } 225 case 9: /* Output */ 226 retkind = hid_output; 227 goto ret; 228 case 10: /* Collection */ 229 c->kind = hid_collection; 230 c->collection = dval; 231 c->collevel++;
| 272 hid_clear_local(c); 273 s->minset = 0; 274 return (1); 275 } 276 case 9: /* Output */ 277 retkind = hid_output; 278 goto ret; 279 case 10: /* Collection */ 280 c->kind = hid_collection; 281 c->collection = dval; 282 c->collevel++;
|
232 *h = *c;
| 283 nc = *c;
|
233 hid_clear_local(c);
| 284 hid_clear_local(c);
|
234 c->report_ID = NO_REPORT_ID;
| 285 /*c->report_ID = NO_REPORT_ID;*/
|
235 s->nusage = 0;
| 286 s->nusage = 0;
|
236 return (1);
| 287 if (s->hassavedcoll) { 288 *h = s->savedcoll; 289 h->report_ID = nc.report_ID; 290 s->savedcoll = nc; 291 return (1); 292 } else { 293 s->hassavedcoll = 1; 294 s->savedcoll = nc; 295 } 296 break;
|
237 case 11: /* Feature */ 238 retkind = hid_feature; 239 goto ret; 240 case 12: /* End collection */
| 297 case 11: /* Feature */ 298 retkind = hid_feature; 299 goto ret; 300 case 12: /* End collection */
|
| 301 REPORT_SAVED_COLL;
|
241 c->kind = hid_endcollection; 242 c->collevel--; 243 *h = *c; 244 /*hid_clear_local(c);*/ 245 s->nusage = 0; 246 return (1); 247 default: 248 return (-2); 249 }
| 302 c->kind = hid_endcollection; 303 c->collevel--; 304 *h = *c; 305 /*hid_clear_local(c);*/ 306 s->nusage = 0; 307 return (1); 308 default: 309 return (-2); 310 }
|
| 311 break;
|
250 251 case 1: /* Global */ 252 switch (bTag) { 253 case 0: 254 c->_usage_page = dval << 16; 255 break; 256 case 1: 257 c->logical_minimum = dval;
| 312 313 case 1: /* Global */ 314 switch (bTag) { 315 case 0: 316 c->_usage_page = dval << 16; 317 break; 318 case 1: 319 c->logical_minimum = dval;
|
| 320 s->logminsize = bSize;
|
258 break; 259 case 2: 260 c->logical_maximum = dval; 261 break; 262 case 3: 263 c->physical_maximum = dval; 264 break; 265 case 4: 266 c->physical_maximum = dval; 267 break; 268 case 5: 269 c->unit_exponent = dval; 270 break; 271 case 6: 272 c->unit = dval; 273 break; 274 case 7: 275 c->report_size = dval; 276 break; 277 case 8: 278 c->report_ID = dval;
| 321 break; 322 case 2: 323 c->logical_maximum = dval; 324 break; 325 case 3: 326 c->physical_maximum = dval; 327 break; 328 case 4: 329 c->physical_maximum = dval; 330 break; 331 case 5: 332 c->unit_exponent = dval; 333 break; 334 case 6: 335 c->unit = dval; 336 break; 337 case 7: 338 c->report_size = dval; 339 break; 340 case 8: 341 c->report_ID = dval;
|
| 342 s->kindpos[hid_input] = 343 s->kindpos[hid_output] = 344 s->kindpos[hid_feature] = 0;
|
279 break; 280 case 9: 281 c->report_count = dval; 282 break; 283 case 10: /* Push */ 284 hi = malloc(sizeof *hi); 285 *hi = s->cur; 286 c->next = hi; 287 break; 288 case 11: /* Pop */ 289 hi = c->next; 290 s->cur = *hi; 291 free(hi); 292 break; 293 default: 294 return (-3); 295 } 296 break; 297 case 2: /* Local */ 298 switch (bTag) { 299 case 0:
| 345 break; 346 case 9: 347 c->report_count = dval; 348 break; 349 case 10: /* Push */ 350 hi = malloc(sizeof *hi); 351 *hi = s->cur; 352 c->next = hi; 353 break; 354 case 11: /* Pop */ 355 hi = c->next; 356 s->cur = *hi; 357 free(hi); 358 break; 359 default: 360 return (-3); 361 } 362 break; 363 case 2: /* Local */ 364 switch (bTag) { 365 case 0:
|
300 if (bSize == 1) 301 dval = c->_usage_page | (dval&0xff); 302 else if (bSize == 2) 303 dval = c->_usage_page | (dval&0xffff); 304 c->usage = dval;
| 366 c->usage = c->_usage_page | dval;
|
305 if (s->nusage < MAXUSAGE)
| 367 if (s->nusage < MAXUSAGE)
|
306 s->usages[s->nusage++] = dval;
| 368 s->usages[s->nusage++] = c->usage;
|
307 /* else XXX */ 308 break; 309 case 1: 310 s->minset = 1;
| 369 /* else XXX */ 370 break; 371 case 1: 372 s->minset = 1;
|
311 if (bSize == 1) 312 dval = c->_usage_page | (dval&0xff); 313 else if (bSize == 2) 314 dval = c->_usage_page | (dval&0xffff); 315 c->usage_minimum = dval;
| 373 c->usage_minimum = c->_usage_page | dval;
|
316 break; 317 case 2:
| 374 break; 375 case 2:
|
318 if (bSize == 1) 319 dval = c->_usage_page | (dval&0xff); 320 else if (bSize == 2) 321 dval = c->_usage_page | (dval&0xffff); 322 c->usage_maximum = dval;
| 376 c->usage_maximum = c->_usage_page | dval;
|
323 break; 324 case 3: 325 c->designator_index = dval; 326 break; 327 case 4: 328 c->designator_minimum = dval; 329 break; 330 case 5: 331 c->designator_maximum = dval; 332 break; 333 case 7: 334 c->string_index = dval; 335 break; 336 case 8: 337 c->string_minimum = dval; 338 break; 339 case 9: 340 c->string_maximum = dval; 341 break; 342 case 10: 343 c->set_delimiter = dval; 344 break; 345 default: 346 return (-4); 347 } 348 break; 349 default: 350 return (-5); 351 } 352 } 353} 354 355int
| 377 break; 378 case 3: 379 c->designator_index = dval; 380 break; 381 case 4: 382 c->designator_minimum = dval; 383 break; 384 case 5: 385 c->designator_maximum = dval; 386 break; 387 case 7: 388 c->string_index = dval; 389 break; 390 case 8: 391 c->string_minimum = dval; 392 break; 393 case 9: 394 c->string_maximum = dval; 395 break; 396 case 10: 397 c->set_delimiter = dval; 398 break; 399 default: 400 return (-4); 401 } 402 break; 403 default: 404 return (-5); 405 } 406 } 407} 408 409int
|
356hid_report_size(report_desc_t r, unsigned int id, enum hid_kind k)
| 410hid_report_size(report_desc_t r, enum hid_kind k, int id)
|
357{ 358 struct hid_data *d; 359 hid_item_t h;
| 411{ 412 struct hid_data *d; 413 hid_item_t h;
|
360 unsigned int size = 0;
| 414 int size;
|
361 362 memset(&h, 0, sizeof h);
| 415 416 memset(&h, 0, sizeof h);
|
363 d = hid_start_parse(r, 1<<k); 364 while (hid_get_item(d, &h)) {
| 417 size = 0; 418 for (d = hid_start_parse(r, 1<<k, id); hid_get_item(d, &h); ) {
|
365 if (h.report_ID == id && h.kind == k) {
| 419 if (h.report_ID == id && h.kind == k) {
|
366 unsigned int newsize = h.pos + h.report_size; 367 if (newsize > size) 368 size = newsize;
| 420 size = d->kindpos[k];
|
369 } 370 } 371 hid_end_parse(d);
| 421 } 422 } 423 hid_end_parse(d);
|
372 373 if (id != NO_REPORT_ID) 374 size += 8; /* add 8 bits for the report ID */ 375 376 return ((size + 7) / 8); /* return size in bytes */
| 424 return ((size + 7) / 8);
|
377} 378 379int
| 425} 426 427int
|
380hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k, hid_item_t *h)
| 428hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k, 429 hid_item_t *h, int id)
|
381{ 382 hid_data_t d; 383
| 430{ 431 hid_data_t d; 432
|
384 for (d = hid_start_parse(desc, 1< | 433 for (d = hid_start_parse(desc, 1<<k, id); hid_get_item(d, h); ) {
|
385 if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) { 386 hid_end_parse(d); 387 return (1); 388 } 389 } 390 hid_end_parse(d); 391 h->report_size = 0; 392 return (0); 393}
| 434 if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) { 435 hid_end_parse(d); 436 return (1); 437 } 438 } 439 hid_end_parse(d); 440 h->report_size = 0; 441 return (0); 442}
|