Print this page
5832 EOF wireless usb (aka UWB)
Reviewed by: TBD
Reviewed by: TBD
Approved by: TBD
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/usb/usba/parser.c
+++ new/usr/src/uts/common/io/usb/usba/parser.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2014 Garrett D'Amore <garrett@damore.org>
24 26 */
25 27
26 28
27 29 /*
28 30 * Descriptor parsing functions
29 31 */
30 32 #define USBA_FRAMEWORK
31 33 #include <sys/usb/usba/usba_impl.h>
32 34 #include <sys/strsun.h>
33 35
34 36 #define INCREMENT_BUF(buf) \
35 37 if ((buf)[0] == 0) { \
36 38 break; \
37 39 } else { \
38 40 (buf) += (buf)[0]; \
39 41 }
40 42 #define isdigit(ch) ((ch >= '0') && (ch <= '9'))
41 43
42 44 extern usba_cfg_pwr_descr_t default_cfg_power;
43 45 extern usba_if_pwr_descr_t default_if_power;
44 46
45 47 size_t
46 48 usb_parse_data(char *format,
47 49 uchar_t *data,
48 50 size_t datalen,
49 51 void *structure,
50 52 size_t structlen)
51 53 {
52 54 int fmt;
53 55 int counter = 1;
54 56 int multiplier = 0;
55 57 uchar_t *dataend = data + datalen;
56 58 char *structstart = (char *)structure;
57 59 void *structend = (void *)((intptr_t)structstart + structlen);
58 60
59 61 if ((format == NULL) || (data == NULL) || (structure == NULL)) {
60 62
61 63 return (USB_PARSE_ERROR);
62 64 }
63 65
64 66 while ((fmt = *format) != '\0') {
65 67
66 68 /*
67 69 * Could some one pass a "format" that is greater than
68 70 * the structlen? Conversely, one could pass a ret_buf_len
69 71 * that is less than the "format" length.
70 72 * If so, we need to protect against writing over memory.
71 73 */
72 74 if (counter++ > structlen) {
73 75 break;
74 76 }
75 77
76 78 if (fmt == 'c') {
77 79 uint8_t *cp = (uint8_t *)structure;
78 80
79 81 cp = (uint8_t *)(((uintptr_t)cp + _CHAR_ALIGNMENT - 1) &
80 82 ~(_CHAR_ALIGNMENT - 1));
81 83 if (((data + 1) > dataend) ||
82 84 ((cp + 1) > (uint8_t *)structend))
83 85 break;
84 86
85 87 *cp++ = *data++;
86 88 structure = (void *)cp;
87 89 if (multiplier) {
88 90 multiplier--;
89 91 }
90 92 if (multiplier == 0) {
91 93 format++;
92 94 }
93 95 } else if (fmt == 's') {
94 96 uint16_t *sp = (uint16_t *)structure;
95 97
96 98 sp = (uint16_t *)
97 99 (((uintptr_t)sp + _SHORT_ALIGNMENT - 1) &
98 100 ~(_SHORT_ALIGNMENT - 1));
99 101 if (((data + 2) > dataend) ||
100 102 ((sp + 1) > (uint16_t *)structend))
101 103 break;
102 104
103 105 *sp++ = (data[1] << 8) + data[0];
104 106 data += 2;
105 107 structure = (void *)sp;
106 108 if (multiplier) {
107 109 multiplier--;
108 110 }
109 111 if (multiplier == 0) {
110 112 format++;
111 113 }
112 114 } else if (fmt == 'l') {
113 115 uint32_t *lp = (uint32_t *)structure;
114 116
115 117 lp = (uint32_t *)
116 118 (((uintptr_t)lp + _INT_ALIGNMENT - 1) &
117 119 ~(_INT_ALIGNMENT - 1));
118 120 if (((data + 4) > dataend) ||
119 121 ((lp + 1) > (uint32_t *)structend))
120 122 break;
121 123
122 124 *lp++ = (((((
123 125 (uint32_t)data[3] << 8) | data[2]) << 8) |
124 126 data[1]) << 8) | data[0];
125 127 data += 4;
126 128 structure = (void *)lp;
127 129 if (multiplier) {
128 130 multiplier--;
129 131 }
130 132 if (multiplier == 0) {
131 133 format++;
132 134 }
133 135 } else if (fmt == 'L') {
134 136 uint64_t *llp = (uint64_t *)structure;
135 137
136 138 llp = (uint64_t *)
137 139 (((uintptr_t)llp + _LONG_LONG_ALIGNMENT - 1) &
138 140 ~(_LONG_LONG_ALIGNMENT - 1));
139 141 if (((data + 8) > dataend) ||
140 142 ((llp + 1) >= (uint64_t *)structend))
141 143 break;
142 144
143 145 *llp++ = (((((((((((((data[7] << 8) |
144 146 data[6]) << 8) | data[5]) << 8) |
145 147 data[4]) << 8) | data[3]) << 8) |
146 148 data[2]) << 8) | data[1]) << 8) |
147 149 data[0];
148 150 data += 8;
149 151 structure = (void *)llp;
150 152 if (multiplier) {
151 153 multiplier--;
152 154 }
153 155 if (multiplier == 0) {
154 156 format++;
155 157 }
156 158 } else if (isdigit(fmt)) {
157 159 multiplier = (multiplier * 10) + (fmt - '0');
158 160 format++;
159 161 counter--;
160 162 } else {
161 163 multiplier = 0;
162 164 break;
163 165 }
164 166 }
165 167
166 168 return ((intptr_t)structure - (intptr_t)structstart);
167 169 }
168 170
169 171
170 172 size_t
171 173 usb_parse_CV_descr(char *format,
172 174 uchar_t *data,
173 175 size_t datalen,
174 176 void *structure,
175 177 size_t structlen)
176 178 {
177 179 return (usb_parse_data(format, data, datalen, structure,
178 180 structlen));
179 181 }
180 182
181 183
182 184 /*
183 185 * Helper function: returns pointer to n-th descriptor of
184 186 * type descr_type, unless the end of the buffer or a descriptor
185 187 * of type stop_descr_type1 or stop_descr_type2 is encountered first.
186 188 */
187 189 static uchar_t *
188 190 usb_nth_descr(uchar_t *buf,
189 191 size_t buflen,
190 192 int descr_type,
191 193 uint_t n,
192 194 int stop_descr_type1,
193 195 int stop_descr_type2)
194 196 {
195 197 uchar_t *bufstart = buf;
196 198 uchar_t *bufend = buf + buflen;
197 199
198 200 if (buf == NULL) {
199 201
200 202 return (NULL);
201 203 }
202 204
203 205 while (buf + 2 <= bufend) {
204 206 if ((buf != bufstart) && ((buf[1] == stop_descr_type1) ||
205 207 (buf[1] == stop_descr_type2))) {
206 208
207 209 return (NULL);
208 210 }
209 211
210 212 if ((descr_type == USB_DESCR_TYPE_ANY) ||
211 213 (buf[1] == descr_type)) {
212 214 if (n-- == 0) {
213 215
214 216 return (buf);
215 217 }
216 218 }
217 219
218 220 /*
219 221 * Check for a bad buffer.
220 222 * If buf[0] is 0, then this will be an infite loop
221 223 */
222 224 INCREMENT_BUF(buf);
223 225 }
224 226
225 227 return (NULL);
226 228 }
227 229
228 230
229 231 size_t
230 232 usb_parse_dev_descr(uchar_t *buf, /* from GET_DESCRIPTOR(DEVICE) */
231 233 size_t buflen,
232 234 usb_dev_descr_t *ret_descr,
233 235 size_t ret_buf_len)
234 236 {
235 237 if ((buf == NULL) || (ret_descr == NULL) ||
236 238 (buflen < 2) || (buf[1] != USB_DESCR_TYPE_DEV)) {
237 239
238 240 return (USB_PARSE_ERROR);
239 241 }
240 242
241 243 return (usb_parse_data("ccsccccssscccc",
242 244 buf, buflen, ret_descr, ret_buf_len));
243 245 }
244 246
245 247
246 248 size_t
247 249 usb_parse_cfg_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
248 250 size_t buflen,
249 251 usb_cfg_descr_t *ret_descr,
250 252 size_t ret_buf_len)
251 253 {
252 254 if ((buf == NULL) || (ret_descr == NULL) ||
253 255 (buflen < 2) || (buf[1] != USB_DESCR_TYPE_CFG)) {
254 256
255 257 return (USB_PARSE_ERROR);
256 258 }
257 259
258 260 return (usb_parse_data("ccsccccc",
259 261 buf, buflen, ret_descr, ret_buf_len));
260 262 }
261 263
262 264
263 265 size_t
264 266 usba_parse_cfg_pwr_descr(
265 267 uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
266 268 size_t buflen,
267 269 usba_cfg_pwr_descr_t *ret_descr,
268 270 size_t ret_buf_len)
269 271 {
270 272 uchar_t *bufend = buf + buflen;
271 273
272 274 if ((buf == NULL) || (ret_descr == NULL)) {
273 275
274 276 return (USB_PARSE_ERROR);
275 277 }
276 278 while (buf + 2 <= bufend) {
277 279
278 280 if (buf[1] == USBA_DESCR_TYPE_CFG_PWR_1_1) {
279 281 return (usb_parse_data("ccsccccccccsss",
280 282 buf, buflen, ret_descr, ret_buf_len));
281 283 }
282 284
283 285 /*
284 286 * Check for a bad buffer.
285 287 * If buf[0] is 0, then this will be an infinite loop
286 288 */
287 289 INCREMENT_BUF(buf);
288 290 }
289 291
290 292 /* return the default configuration power descriptor */
291 293 bcopy(&default_cfg_power, ret_descr, USBA_CFG_PWR_DESCR_SIZE);
292 294
293 295 return (ret_descr->bLength);
294 296
295 297 }
296 298
297 299
298 300 size_t
299 301 usb_parse_ia_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
300 302 size_t buflen,
301 303 size_t first_if,
302 304 usb_ia_descr_t *ret_descr,
303 305 size_t ret_buf_len)
304 306 {
305 307 uchar_t *bufend = buf + buflen;
306 308
307 309 if ((buf == NULL) || (ret_descr == NULL)) {
308 310
309 311 return (USB_PARSE_ERROR);
310 312 }
311 313
312 314 while (buf + USB_IA_DESCR_SIZE <= bufend) {
313 315 if ((buf[1] == USB_DESCR_TYPE_IA) &&
314 316 (buf[2] == first_if)) {
315 317
316 318 return (usb_parse_data("cccccccc",
317 319 buf, _PTRDIFF(bufend, buf),
318 320 ret_descr, ret_buf_len));
319 321 }
320 322
321 323 /*
322 324 * Check for a bad buffer.
323 325 * If buf[0] is 0, then this will be an infinite loop
324 326 */
325 327 INCREMENT_BUF(buf);
326 328 }
327 329
328 330 return (USB_PARSE_ERROR);
329 331 }
330 332
331 333
332 334 size_t
333 335 usb_parse_if_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
334 336 size_t buflen,
335 337 uint_t if_number,
336 338 uint_t alt_if_setting,
337 339 usb_if_descr_t *ret_descr,
338 340 size_t ret_buf_len)
339 341 {
340 342 uchar_t *bufend = buf + buflen;
341 343
342 344 if ((buf == NULL) || (ret_descr == NULL)) {
343 345
344 346 return (USB_PARSE_ERROR);
345 347 }
346 348
347 349 while (buf + 4 <= bufend) {
348 350 if ((buf[1] == USB_DESCR_TYPE_IF) &&
349 351 (buf[2] == if_number) &&
350 352 (buf[3] == alt_if_setting)) {
351 353
352 354 return (usb_parse_data("ccccccccc",
353 355 buf, _PTRDIFF(bufend, buf),
354 356 ret_descr, ret_buf_len));
355 357 }
356 358
357 359 /*
358 360 * Check for a bad buffer.
359 361 * If buf[0] is 0, then this will be an infinite loop
360 362 */
361 363 INCREMENT_BUF(buf);
362 364 }
363 365
364 366 return (USB_PARSE_ERROR);
365 367 }
366 368
367 369 size_t
368 370 usba_parse_if_pwr_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
369 371 size_t buflen,
370 372 uint_t if_number,
371 373 uint_t alt_if_setting,
372 374 usba_if_pwr_descr_t *ret_descr,
373 375 size_t ret_buf_len)
374 376 {
375 377 uchar_t *bufend = buf + buflen;
376 378
377 379 if ((buf == NULL) || (ret_descr == NULL)) {
378 380
379 381 return (USB_PARSE_ERROR);
380 382 }
381 383
382 384 while (buf + 4 <= bufend) {
383 385 if ((buf[1] == USB_DESCR_TYPE_IF) &&
384 386 (buf[2] == if_number) &&
385 387 (buf[3] == alt_if_setting)) {
386 388
387 389 buf += buf[0];
388 390
389 391 if (buf + 2 <= bufend) {
390 392 if (buf[1] == USBA_DESCR_TYPE_IF_PWR_1_1) {
391 393
392 394 return (
393 395 usb_parse_data("cccccccccsss", buf,
394 396 _PTRDIFF(bufend, buf), ret_descr,
395 397 ret_buf_len));
396 398 } else {
397 399 break;
398 400 }
399 401 } else {
400 402 break;
401 403 }
402 404 }
403 405
404 406 /*
405 407 * Check for a bad buffer.
406 408 * If buf[0] is 0, then this will be an infinite loop
407 409 */
408 410 INCREMENT_BUF(buf);
409 411 }
410 412
411 413 /* return the default interface power descriptor */
412 414 bcopy(&default_if_power, ret_descr, USBA_IF_PWR_DESCR_SIZE);
413 415
414 416 return (ret_descr->bLength);
415 417 }
416 418
417 419
418 420 /*
419 421 * the endpoint index is relative to the interface. index 0 is
420 422 * the first endpoint
421 423 */
422 424 size_t
423 425 usb_parse_ep_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
424 426 size_t buflen,
425 427 uint_t if_number,
426 428 uint_t alt_if_setting,
427 429 uint_t ep_index,
428 430 usb_ep_descr_t *ret_descr,
429 431 size_t ret_buf_len)
430 432 {
431 433 uchar_t *bufend = buf + buflen;
432 434
433 435 if ((buf == NULL) || (ret_descr == NULL)) {
434 436
435 437 return (USB_PARSE_ERROR);
436 438 }
437 439
438 440 while ((buf + 4) <= bufend) {
439 441 if (buf[1] == USB_DESCR_TYPE_IF &&
440 442 buf[2] == if_number &&
441 443 buf[3] == alt_if_setting) {
442 444 if ((buf = usb_nth_descr(buf,
443 445 _PTRDIFF(bufend, buf),
444 446 USB_DESCR_TYPE_EP, ep_index,
445 447 USB_DESCR_TYPE_IF, -1)) == NULL) {
446 448
447 449 break;
448 450 }
449 451
450 452 return (usb_parse_data("ccccsc",
451 453 buf, _PTRDIFF(bufend, buf),
452 454 ret_descr, ret_buf_len));
453 455 }
454 456
455 457 /*
456 458 * Check for a bad buffer.
457 459 * If buf[0] is 0, then this will be an infinite loop
458 460 */
459 461 INCREMENT_BUF(buf);
460 462 }
461 463
462 464 return (USB_PARSE_ERROR);
463 465 }
464 466
465 467
466 468 /*
467 469 * Returns (at ret_descr) a null-terminated string. Null termination is
468 470 * guaranteed, even if the string is longer than the buffer. Thus, a
469 471 * maximum of (ret_buf_len - 1) characters are returned.
470 472 * Stops silently on first character not in UNICODE format.
471 473 */
472 474 /*ARGSUSED*/
473 475 size_t
474 476 usba_ascii_string_descr(uchar_t *buf, /* from GET_DESCRIPTOR(STRING) */
475 477 size_t buflen,
476 478 char *ret_descr,
477 479 size_t ret_buf_len)
478 480 {
479 481 int i = 1;
480 482 char *retstart = ret_descr;
481 483 uchar_t *bufend = buf + buflen;
482 484
483 485 if ((buf == NULL) || (ret_descr == NULL) ||
484 486 (ret_buf_len == 0) || (buflen < 2) ||
485 487 (buf[0] < 2) || (buf[1] != USB_DESCR_TYPE_STRING)) {
486 488
487 489 return (USB_PARSE_ERROR);
488 490 }
489 491
490 492 for (buf = buf + 2; buf+1 < bufend && ret_buf_len > 1 &&
491 493 buf[0] != 0 && buf[1] == 0 && (i < ret_buf_len); buf += 2, i++) {
492 494 *ret_descr++ = buf[0];
493 495 }
494 496
495 497 *ret_descr++ = 0;
496 498
497 499 return (_PTRDIFF(ret_descr, retstart));
498 500 }
499 501
500 502
501 503 size_t
502 504 usb_parse_CV_cfg_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
503 505 size_t buflen,
504 506 char *fmt,
505 507 uint_t descr_type,
506 508 uint_t descr_index,
507 509 void *ret_descr,
508 510 size_t ret_buf_len)
509 511 {
510 512 uchar_t *bufend = buf + buflen;
511 513
512 514 if ((buf == NULL) || (ret_descr == NULL) || (fmt == NULL) ||
513 515 (buflen < 2) || ((buf = usb_nth_descr(buf, buflen, descr_type,
514 516 descr_index, -1, -1)) == NULL)) {
515 517
516 518 return (USB_PARSE_ERROR);
517 519 }
518 520
519 521 return (usb_parse_data(fmt, buf,
520 522 _PTRDIFF(bufend, buf), ret_descr,
521 523 ret_buf_len));
522 524 }
523 525
524 526
525 527 size_t
526 528 usb_parse_CV_if_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
527 529 size_t buflen,
528 530 char *fmt,
529 531 uint_t if_number,
530 532 uint_t alt_if_setting,
531 533 uint_t descr_type,
532 534 uint_t descr_index,
533 535 void *ret_descr,
534 536 size_t ret_buf_len)
535 537 {
536 538 uchar_t *bufend = buf + buflen;
537 539
538 540 if ((buf == NULL) || (ret_descr == NULL) || (fmt == NULL)) {
539 541
540 542 return (USB_PARSE_ERROR);
541 543 }
542 544
543 545 while (buf + 4 <= bufend) {
544 546 if ((buf[1] == USB_DESCR_TYPE_IF) &&
545 547 (buf[2] == if_number) &&
546 548 (buf[3] == alt_if_setting)) {
547 549 if ((buf = usb_nth_descr(buf,
548 550 _PTRDIFF(bufend, buf), descr_type,
549 551 descr_index, USB_DESCR_TYPE_IF, -1)) ==
550 552 NULL) {
551 553 break;
552 554 }
553 555
554 556 return (usb_parse_data(fmt, buf,
555 557 _PTRDIFF(bufend, buf),
556 558 ret_descr, ret_buf_len));
557 559 }
558 560
559 561 /*
560 562 * Check for a bad buffer.
561 563 * If buf[0] is 0, then this will be an infinite loop
562 564 */
563 565 INCREMENT_BUF(buf);
564 566 }
565 567
566 568 return (USB_PARSE_ERROR);
567 569 }
568 570
569 571
570 572 size_t
571 573 usb_parse_CV_ep_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
572 574 size_t buflen,
573 575 char *fmt,
574 576 uint_t if_number,
575 577 uint_t alt_if_setting,
576 578 uint_t ep_index,
577 579 uint_t descr_type,
578 580 uint_t descr_index,
579 581 void *ret_descr,
580 582 size_t ret_buf_len)
581 583 {
582 584 uchar_t *bufend = buf + buflen;
583 585
584 586 if ((buf == NULL) || (ret_descr == NULL) || (fmt == NULL)) {
585 587
586 588 return (USB_PARSE_ERROR);
587 589 }
588 590
589 591 while (buf + 4 <= bufend) {
590 592 if ((buf[1] == USB_DESCR_TYPE_IF) &&
591 593 (buf[2] == if_number) &&
592 594 (buf[3] == alt_if_setting)) {
593 595 if ((buf = usb_nth_descr(buf,
594 596 _PTRDIFF(bufend, buf),
595 597 USB_DESCR_TYPE_EP, ep_index,
596 598 USB_DESCR_TYPE_IF, -1)) == NULL) {
597 599
598 600 break;
599 601 }
600 602
601 603 if ((buf = usb_nth_descr(buf,
602 604 _PTRDIFF(bufend, buf),
603 605 descr_type, descr_index,
604 606 USB_DESCR_TYPE_EP,
605 607 USB_DESCR_TYPE_IF)) == NULL) {
606 608
607 609 break;
608 610 }
609 611
610 612 return (usb_parse_data(fmt, buf,
611 613 _PTRDIFF(bufend, buf),
612 614 ret_descr, ret_buf_len));
↓ open down ↓ |
579 lines elided |
↑ open up ↑ |
613 615 }
614 616
615 617 /*
616 618 * Check for a bad buffer.
617 619 * If buf[0] is 0, then this will be an infite loop
618 620 */
619 621 INCREMENT_BUF(buf);
620 622 }
621 623
622 624 return (USB_PARSE_ERROR);
623 -}
624 -
625 -size_t
626 -usb_parse_bos_descr(uchar_t *buf, /* from GET_DESCRIPTOR(BOS) */
627 - size_t buflen,
628 - usb_bos_descr_t *ret_descr,
629 - size_t ret_buf_len)
630 -{
631 - if ((buf == NULL) || (ret_descr == NULL) ||
632 - (buflen < 2) || (buf[1] != USB_DESCR_TYPE_BOS)) {
633 -
634 - return (USB_PARSE_ERROR);
635 - }
636 -
637 - return (usb_parse_data("ccsc",
638 - buf, buflen, ret_descr, ret_buf_len));
639 -}
640 -
641 -size_t
642 -usb_parse_uwb_bos_descr(uchar_t *buf, /* from GET_DESCRIPTOR(BOS) */
643 - size_t buflen,
644 - usb_uwb_cap_descr_t *ret_descr,
645 - size_t ret_buf_len)
646 -{
647 - uchar_t *bufend = buf + buflen;
648 -
649 - if ((buf == NULL) || (ret_descr == NULL)) {
650 -
651 - return (USB_PARSE_ERROR);
652 - }
653 -
654 - while (buf + 3 <= bufend) {
655 - if ((buf[1] == USB_DESCR_TYPE_DEV_CAPABILITY) &&
656 - (buf[2] == USB_CAP_TYPE_WUSB)) {
657 -
658 - return (usb_parse_data("ccccsccsc",
659 - buf, _PTRDIFF(bufend, buf), ret_descr,
660 - ret_buf_len));
661 - }
662 -
663 - INCREMENT_BUF(buf);
664 - }
665 -
666 - return (USB_PARSE_ERROR);
667 -}
668 -
669 -size_t
670 -usb_parse_comp_ep_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */
671 - size_t buflen,
672 - uint_t if_number,
673 - uint_t alt_if_setting,
674 - uint_t ep_index,
675 - usb_ep_comp_descr_t *ret_descr,
676 - size_t ret_buf_len)
677 -{
678 - return (usb_parse_CV_ep_descr(buf, buflen, "ccccsscc",
679 - if_number, alt_if_setting, ep_index,
680 - USB_DESCR_TYPE_WIRELESS_EP_COMP, 0,
681 - ret_descr, ret_buf_len));
682 625 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX