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/usbai_register.c
+++ new/usr/src/uts/common/io/usb/usba/usbai_register.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 * USBA: Solaris USB Architecture support
28 30 *
29 31 * This module builds a tree of parsed USB standard descriptors and unparsed
30 32 * Class/Vendor specific (C/V) descriptors. Routines are grouped into three
31 33 * groups: those which build the tree, those which take it down, and those which
32 34 * dump it.
33 35 *
34 36 * The tree built hangs off of the dev_cfg field of the usb_client_dev_data_t
35 37 * structure returned by usb_get_dev_data(). The tree consists of different
36 38 * kinds of tree nodes (usb_xxx_data_t) each containing a standard USB
37 39 * descriptor (usb_xxx_descr_t) and pointers to arrays of other nodes.
38 40 *
39 41 * Arrays are dynamically sized, as the descriptors coming from the device may
40 42 * lie, but the number of descriptors from the device is a more reliable
41 43 * indicator of configuration. This makes the code more robust. After the raw
42 44 * descriptor data has been parsed into a non-sparse tree, the tree is ordered
43 45 * and made sparse with a bin-sort style algorithm.
44 46 *
45 47 * dev_cfg is an array of configuration tree nodes. Each contains space for one
46 48 * parsed standard USB configuration descriptor, a pointer to an array of c/v
47 49 * tree nodes and a pointer to an array of interface tree nodes.
48 50 *
49 51 * Each interface tree node represents a group of interface descriptors, called
50 52 * alternates, with the same interface number. Thus, each interface tree node
51 53 * has a pointer to an array of alternate-interface tree nodes each containing a
52 54 * standard USB interface descriptor. Alternate-interface tree nodes also
53 55 * contain a pointer to an array of c/v tree nodes and a pointer to an array of
54 56 * endpoint tree nodes.
55 57 *
56 58 * Endpoint tree nodes contain a standard endpoint descriptor, plus a pointer to
57 59 * an array of c/v tree nodes.
58 60 *
59 61 * Each array in the tree contains elements ranging from 0 to the largest key
60 62 * value of it's elements. Endpoints are a special case. The direction bit is
61 63 * right shifted over three unused bits before the index is determined, leaving
62 64 * a range of 0..31 instead of a sparsely-populated range of 0..255.
63 65 *
64 66 * The indices of tree elements coincide with their USB key values. For
65 67 * example, standard USB devices have no configuration 0; if they have one
66 68 * configuration it is #1. dev_cfg[0] is zeroed out; dev_cfg[1] is the root
67 69 * of configuration #1.
68 70 *
69 71 * The idea here is for a driver to be able to parse the tree to easily find a
70 72 * desired descriptor. For example, the interval of endpoint 2, alternate 3,
71 73 * interface 1, configuration 1 would be:
72 74 * dv->dev_cfg[1].cfg_if[1].if_alt[3].altif_ep[2].ep_descr.bInterval
73 75 *
74 76 * How the tree is built:
75 77 *
76 78 * usb_build_descr_tree() is responsible for the whole process.
77 79 *
78 80 * Next, usba_build_descr_tree() coordinates parsing this byte stream,
79 81 * descriptor by descriptor. usba_build_descr_tree() calls the appropriate
80 82 * usba_process_xx_descr() function to interpret and install each descriptor in
81 83 * the tree, based on the descriptor's type. When done with this phase, a
82 84 * non-sparse tree exists containing tree nodes with descriptors in the order
83 85 * they were found in the raw data.
84 86 *
85 87 * All levels of the tree, except alternates, remain non-sparse. Alternates are
86 88 * moved, possibly, within their array, so that descriptors are indexed by their
87 89 * alternate ID.
88 90 *
89 91 * The usba_reg_state_t structure maintains state of the tree-building process,
90 92 * helping coordinate all routines involved.
91 93 */
92 94 #define USBA_FRAMEWORK
93 95 #include <sys/usb/usba.h>
94 96 #include <sys/usb/usba/usba_impl.h>
95 97 #include <sys/usb/usba/usba_private.h>
96 98 #include <sys/usb/usba/hcdi_impl.h>
97 99 #include <sys/usb/hubd/hub.h>
98 100
99 101 #include <sys/usb/usba/usbai_register_impl.h>
100 102
101 103 /*
102 104 * Header needed for use by this module only.
103 105 * However, function may be used in V0.8 drivers so needs to be global.
104 106 */
↓ open down ↓ |
71 lines elided |
↑ open up ↑ |
105 107 int usb_log_descr_tree(usb_client_dev_data_t *, usb_log_handle_t,
106 108 uint_t, uint_t);
107 109
108 110 /* Debug stuff */
109 111 usb_log_handle_t usbai_reg_log_handle;
110 112 uint_t usbai_register_errlevel = USB_LOG_L2;
111 113 uint_t usbai_register_dump_errlevel = USB_LOG_L2;
112 114 uint_t usbai_register_errmask = (uint_t)-1;
113 115
114 116 /* Function prototypes */
115 -static int usba_build_bos(usba_device_t *, usb_client_dev_data_t *);
116 117 static int usba_build_descr_tree(dev_info_t *, usba_device_t *,
117 118 usb_client_dev_data_t *);
118 119 static void usba_process_cfg_descr(usba_reg_state_t *);
119 120 static int usba_process_if_descr(usba_reg_state_t *, boolean_t *);
120 121 static int usba_process_ep_descr(usba_reg_state_t *);
121 122 static int usba_process_cv_descr(usba_reg_state_t *);
122 -static int usba_process_ep_comp_descr(usba_reg_state_t *);
123 123 static int usba_set_parse_values(dev_info_t *dip, usba_device_t *usba_device,
124 124 usba_reg_state_t *state);
125 125 static void* usba_kmem_realloc(void *, int, int);
126 126 static void usba_augment_array(void **, uint_t, uint_t);
127 127 static void usba_make_alts_sparse(usb_alt_if_data_t **, uint_t *);
128 128
129 129 static void usba_order_tree(usba_reg_state_t *);
130 130
131 131 static void usba_free_if_array(usb_if_data_t *, uint_t);
132 132 static void usba_free_ep_array(usb_ep_data_t *, uint_t);
133 133 static void usba_free_cv_array(usb_cvs_data_t *, uint_t);
134 134
135 135 static int usba_dump_descr_tree(dev_info_t *, usb_client_dev_data_t *,
136 136 usb_log_handle_t, uint_t, uint_t);
137 137 static void usba_dump_if(usb_if_data_t *, usb_log_handle_t,
138 138 uint_t, uint_t, char *);
139 139 static void usba_dump_ep(uint_t, usb_ep_data_t *, usb_log_handle_t, uint_t,
140 140 uint_t, char *);
141 141 static void usba_dump_cv(usb_cvs_data_t *, usb_log_handle_t, uint_t, uint_t,
142 142 char *, int);
143 143 static void usba_dump_bin(uint8_t *, int, int, usb_log_handle_t,
144 144 uint_t, uint_t, char *, int);
145 145
146 146 /* Framework initialization. */
147 147 void
148 148 usba_usbai_register_initialization()
149 149 {
150 150 usbai_reg_log_handle = usb_alloc_log_hdl(NULL, "usbreg",
151 151 &usbai_register_errlevel,
152 152 &usbai_register_errmask, NULL,
153 153 0);
154 154
155 155 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
156 156 "usba_usbai_register_initialization");
157 157 }
158 158
159 159
160 160 /* Framework destruction. */
161 161 void
162 162 usba_usbai_register_destroy()
163 163 {
164 164 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
165 165 "usba_usbai_register destroy");
166 166
167 167 usb_free_log_hdl(usbai_reg_log_handle);
168 168 }
169 169
170 170
171 171 /*
172 172 * usb_client_attach:
173 173 *
174 174 * Arguments:
175 175 * dip - pointer to devinfo node of the client
176 176 * version - USBA registration version number
177 177 * flags - None used
178 178 *
179 179 * Return Values:
180 180 * USB_SUCCESS - attach succeeded
181 181 * USB_INVALID_ARGS - received null dip
182 182 * USB_INVALID_VERSION - version argument is incorrect.
183 183 * USB_FAILURE - other internal failure
184 184 */
185 185 /*ARGSUSED*/
186 186 int
187 187 usb_client_attach(dev_info_t *dip, uint_t version, usb_flags_t flags)
188 188 {
189 189 int rval;
190 190 usba_device_t *usba_device;
191 191
192 192 if (dip == NULL) {
193 193
194 194 return (USB_INVALID_ARGS);
195 195 }
196 196
197 197 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
198 198 "usb_client attach:");
199 199
200 200 usba_device = usba_get_usba_device(dip);
201 201
202 202 /*
203 203 * Allow exact match for legacy (DDK 0.8/9) drivers, or same major
204 204 * VERSion and smaller or same minor version for non-legacy drivers.
205 205 */
206 206 if ((version !=
207 207 USBA_MAKE_VER(USBA_LEG_MAJOR_VER, USBA_LEG_MINOR_VER)) &&
208 208 ((USBA_GET_MAJOR(version) != USBA_MAJOR_VER) ||
209 209 (USBA_GET_MINOR(version) > USBA_MINOR_VER))) {
210 210 USB_DPRINTF_L1(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
211 211 "Incorrect USB driver version for %s%d: found: %d.%d, "
212 212 "expecting %d.%d",
213 213 ddi_driver_name(dip), ddi_get_instance(dip),
214 214 USBA_GET_MAJOR(version), USBA_GET_MINOR(version),
215 215 USBA_MAJOR_VER, USBA_MINOR_VER);
216 216
217 217 return (USB_INVALID_VERSION);
218 218 }
219 219
220 220 if (version == USBA_MAKE_VER(USBA_LEG_MAJOR_VER, USBA_LEG_MINOR_VER)) {
221 221 USB_DPRINTF_L2(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
222 222 "Accepting legacy USB driver version %d.%d for %s%d",
223 223 USBA_LEG_MAJOR_VER, USBA_LEG_MINOR_VER,
224 224 ddi_driver_name(dip), ddi_get_instance(dip));
225 225 }
226 226
227 227 rval = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "driver-major",
228 228 USBA_GET_MAJOR(version));
229 229 if (rval != DDI_PROP_SUCCESS) {
230 230
231 231 return (USB_FAILURE);
232 232 }
233 233 rval = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "driver-minor",
234 234 USBA_GET_MINOR(version));
235 235 if (rval != DDI_PROP_SUCCESS) {
236 236
237 237 return (USB_FAILURE);
238 238 }
239 239
240 240 mutex_enter(&usba_device->usb_mutex);
241 241 if (strcmp(ddi_driver_name(dip), "usb_mid") != 0) {
242 242 usba_device->usb_client_flags[usba_get_ifno(dip)] |=
243 243 USBA_CLIENT_FLAG_ATTACH;
244 244 usba_device->usb_client_attach_list->dip = dip;
245 245 }
246 246 mutex_exit(&usba_device->usb_mutex);
247 247
248 248 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
249 249 "usb_client attach: done");
250 250
251 251 return (USB_SUCCESS);
252 252 }
253 253
254 254
255 255 /*
256 256 * usb_client_detach:
257 257 * free dev_data is reg != NULL, not much else to do
258 258 *
259 259 * Arguments:
260 260 * dip - pointer to devinfo node of the client
261 261 * reg - return registration data at this address
262 262 */
263 263 void
264 264 usb_client_detach(dev_info_t *dip, usb_client_dev_data_t *reg)
265 265 {
266 266 usba_device_t *usba_device = usba_get_usba_device(dip);
267 267
268 268 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
269 269 "usb_client_detach:");
270 270
271 271 if (dip) {
272 272 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
273 273 "Unregistering usb client %s%d: reg=0x%p",
274 274 ddi_driver_name(dip), ddi_get_instance(dip), (void *)reg);
275 275
276 276 usb_free_dev_data(dip, reg);
277 277
278 278 mutex_enter(&usba_device->usb_mutex);
279 279 if (strcmp(ddi_driver_name(dip), "usb_mid") != 0) {
280 280 usba_device->usb_client_flags[usba_get_ifno(dip)] &=
281 281 ~USBA_CLIENT_FLAG_ATTACH;
282 282 }
283 283 mutex_exit(&usba_device->usb_mutex);
284 284 }
285 285
286 286 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
287 287 "usb_client_detach done");
288 288 }
289 289
290 290
291 291 /*
292 292 * usb_register_client (deprecated):
293 293 * The client registers with USBA during attach.
294 294 */
295 295 /*ARGSUSED*/
296 296 int
297 297 usb_register_client(dev_info_t *dip, uint_t version,
298 298 usb_client_dev_data_t **reg, usb_reg_parse_lvl_t parse_level,
299 299 usb_flags_t flags)
300 300 {
301 301 int rval = usb_client_attach(dip, version, flags);
302 302
303 303 if (rval == USB_SUCCESS) {
304 304 rval = usb_get_dev_data(dip, reg, parse_level, flags);
305 305
306 306 if (rval != USB_SUCCESS) {
307 307 usb_client_detach(dip, NULL);
308 308 }
309 309 }
310 310
311 311 return (rval);
312 312 }
313 313
314 314
315 315 /*
316 316 * usb_unregister_client (deprecated):
317 317 * Undo the makings of usb_get_dev_data(). Free memory if allocated.
318 318 *
319 319 * Arguments:
320 320 * dip - pointer to devinfo node of the client
321 321 * reg - pointer to registration data to be freed
322 322 */
323 323 void
324 324 usb_unregister_client(dev_info_t *dip, usb_client_dev_data_t *reg)
325 325 {
326 326 usb_client_detach(dip, reg);
327 327 }
328 328
329 329
330 330 /*
331 331 * usb_get_dev_data:
332 332 * On completion, the registration data has been initialized.
333 333 * Most data items are straightforward.
334 334 * Among the items returned in the data is the tree of
335 335 * parsed descriptors, in dev_cfg; the number of configurations parsed,
336 336 * in dev_n_cfg; a pointer to the current configuration in the tree,
337 337 * in dev_curr_cfg; the index of the first valid interface in the
338 338 * tree, in dev_curr_if, and a parse level that accurately reflects what
339 339 * is in the tree, in dev_parse_level.
340 340 *
341 341 * This routine sets up directly-initialized fields, and calls
342 342 * usb_build_descr_tree() to parse the raw descriptors and initialize the
343 343 * tree.
344 344 *
345 345 * Parse_level determines the extent to which the tree is built. It has
346 346 * the following values:
347 347 *
348 348 * USB_PARSE_LVL_NONE - Build no tree. dev_n_cfg will return 0, dev_cfg
349 349 * and dev_curr_cfg will return NULL.
350 350 * USB_PARSE_LVL_IF - Parse configured interface only, if configuration#
351 351 * and interface properties are set (as when different
352 352 * interfaces are viewed by the OS as different device
353 353 * instances). If an OS device instance is set up to
354 354 * represent an entire physical device, this works
355 355 * like USB_PARSE_LVL_ALL.
356 356 * USB_PARSE_LVL_CFG - Parse entire configuration of configured interface
357 357 * only. This is like USB_PARSE_LVL_IF except entire
358 358 * configuration is returned.
359 359 * USB_PARSE_LVL_ALL - Parse entire device (all configurations), even
360 360 * when driver is bound to a single interface of a
361 361 * single configuration.
362 362 *
363 363 * No tree is built for root hubs, regardless of parse_level.
364 364 *
365 365 * Arguments:
366 366 * dip - pointer to devinfo node of the client
367 367 * version - USBA registration version number
368 368 * reg - return registration data at this address
369 369 * parse_level - See above
370 370 * flags - None used
371 371 *
372 372 * Return Values:
373 373 * USB_SUCCESS - usb_get_dev_data succeeded
374 374 * USB_INVALID_ARGS - received null dip or reg argument
375 375 * USB_INVALID_CONTEXT - called from callback context
376 376 * USB_FAILURE - bad descriptor info or other internal failure
377 377 *
378 378 * Note: The non-standard USB descriptors are returned in RAW format.
379 379 * returns initialized registration data. Most data items are clear.
380 380 * Among the items returned is the tree of parsed descriptors in dev_cfg;
381 381 * and the number of configurations parsed in dev_n_cfg.
382 382 *
383 383 * The registration data is not shared. each client receives its own
384 384 * copy.
385 385 */
386 386 /*ARGSUSED*/
387 387 int
388 388 usb_get_dev_data(dev_info_t *dip,
389 389 usb_client_dev_data_t **reg, usb_reg_parse_lvl_t parse_level,
390 390 usb_flags_t flags)
391 391 {
392 392 usb_client_dev_data_t *usb_reg = NULL;
393 393 char *tmpbuf = NULL;
394 394 usba_device_t *usba_device;
395 395 int rval = USB_SUCCESS;
396 396
397 397 if ((dip == NULL) || (reg == NULL)) {
398 398
399 399 return (USB_INVALID_ARGS);
400 400 }
401 401
402 402 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
403 403 "usb_get_dev_data: %s%d",
404 404 ddi_driver_name(dip), ddi_get_instance(dip));
405 405
406 406 *reg = NULL;
407 407
408 408 /* did the client attach first? */
409 409 if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
410 410 "driver-major", -1) == -1) {
411 411
412 412 return (USB_INVALID_VERSION);
413 413 }
414 414 if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
415 415 "driver-minor", -1) == -1) {
416 416
417 417 return (USB_INVALID_VERSION);
418 418 }
419 419
↓ open down ↓ |
287 lines elided |
↑ open up ↑ |
420 420 usb_reg = kmem_zalloc(sizeof (usb_client_dev_data_t), KM_SLEEP);
421 421 usba_device = usba_get_usba_device(dip);
422 422 usb_reg->dev_descr = usba_device->usb_dev_descr;
423 423 usb_reg->dev_default_ph = usba_get_dflt_pipe_handle(dip);
424 424 if (usb_reg->dev_default_ph == NULL) {
425 425 kmem_free(usb_reg, sizeof (usb_client_dev_data_t));
426 426
427 427 return (USB_FAILURE);
428 428 }
429 429
430 - /* get parsed bos for wusb device */
431 - if (usba_device->usb_is_wireless) {
432 - if ((rval = usba_build_bos(usba_device, usb_reg)) !=
433 - USB_SUCCESS) {
434 - kmem_free(usb_reg, sizeof (usb_client_dev_data_t));
435 -
436 - return (rval);
437 - }
438 - }
439 -
440 430 usb_reg->dev_iblock_cookie = usba_hcdi_get_hcdi(
441 431 usba_device->usb_root_hub_dip)->hcdi_soft_iblock_cookie;
442 432
443 433 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
444 434 "cookie = 0x%p", (void *)usb_reg->dev_iblock_cookie);
445 435
446 436 tmpbuf = (char *)kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP);
447 437
448 438 if (usba_device->usb_mfg_str != NULL) {
449 439 usb_reg->dev_mfg = kmem_zalloc(
450 440 strlen(usba_device->usb_mfg_str) + 1, KM_SLEEP);
451 441 (void) strcpy(usb_reg->dev_mfg, usba_device->usb_mfg_str);
452 442 }
453 443
454 444 if (usba_device->usb_product_str != NULL) {
455 445 usb_reg->dev_product = kmem_zalloc(
456 446 strlen(usba_device->usb_product_str) + 1,
457 447 KM_SLEEP);
458 448 (void) strcpy(usb_reg->dev_product,
459 449 usba_device->usb_product_str);
460 450 }
461 451
462 452 if (usba_device->usb_serialno_str != NULL) {
463 453 usb_reg->dev_serial = kmem_zalloc(
464 454 strlen(usba_device->usb_serialno_str) + 1,
465 455 KM_SLEEP);
466 456 (void) strcpy(usb_reg->dev_serial,
467 457 usba_device->usb_serialno_str);
468 458 }
469 459
470 460 if ((usb_reg->dev_parse_level = parse_level) == USB_PARSE_LVL_NONE) {
471 461 rval = USB_SUCCESS;
472 462
473 463 } else if ((rval = usba_build_descr_tree(dip, usba_device, usb_reg)) !=
474 464 USB_SUCCESS) {
475 465 usb_unregister_client(dip, usb_reg);
476 466 usb_reg = NULL;
477 467 } else {
478 468
479 469 /* Current tree cfg is always zero if only one cfg in tree. */
480 470 if (usb_reg->dev_n_cfg == 1) {
481 471 usb_reg->dev_curr_cfg = &usb_reg->dev_cfg[0];
482 472 } else {
483 473 mutex_enter(&usba_device->usb_mutex);
484 474 usb_reg->dev_curr_cfg =
485 475 &usb_reg->dev_cfg[usba_device->usb_active_cfg_ndx];
486 476 mutex_exit(&usba_device->usb_mutex);
487 477 ASSERT(usb_reg->dev_curr_cfg != NULL);
488 478 ASSERT(usb_reg->dev_curr_cfg->cfg_descr.bLength ==
489 479 USB_CFG_DESCR_SIZE);
490 480 }
491 481
492 482 /*
493 483 * Keep dev_curr_if at device's single interface only if that
494 484 * particular interface has been explicitly defined by the
495 485 * device.
496 486 */
497 487 usb_reg->dev_curr_if = usba_get_ifno(dip);
498 488 #ifdef DEBUG
499 489 (void) usb_log_descr_tree(usb_reg, usbai_reg_log_handle,
500 490 usbai_register_dump_errlevel, (uint_t)-1);
501 491 #endif
502 492 /*
503 493 * Fail if interface and configuration of dev_curr_if and
504 494 * dev_curr_cfg don't exist or are invalid. (Shouldn't happen.)
505 495 * These indices must be reliable for tree traversal.
506 496 */
507 497 if ((usb_reg->dev_curr_cfg->cfg_n_if <= usb_reg->dev_curr_if) ||
508 498 (usb_reg->dev_curr_cfg->cfg_descr.bLength == 0) ||
509 499 (usb_reg->dev_curr_cfg->cfg_if[usb_reg->dev_curr_if].
510 500 if_n_alt == 0)) {
511 501 USB_DPRINTF_L2(DPRINT_MASK_ALL, usbai_reg_log_handle,
512 502 "usb_get_dev_data: dev_curr_cfg or "
513 503 "dev_curr_if have no descriptors");
514 504 usb_unregister_client(dip, usb_reg);
515 505 usb_reg = NULL;
516 506 rval = USB_FAILURE;
517 507 }
518 508 }
519 509
520 510 *reg = usb_reg;
521 511 kmem_free(tmpbuf, USB_MAXSTRINGLEN);
522 512
523 513 if (rval == USB_SUCCESS) {
524 514 usb_client_dev_data_list_t *entry = kmem_zalloc(
525 515 sizeof (*entry), KM_SLEEP);
526 516 mutex_enter(&usba_device->usb_mutex);
527 517
528 518 usba_device->usb_client_flags[usba_get_ifno(dip)] |=
529 519 USBA_CLIENT_FLAG_DEV_DATA;
530 520
531 521 entry->cddl_dip = dip;
532 522 entry->cddl_dev_data = usb_reg;
533 523 entry->cddl_ifno = usba_get_ifno(dip);
534 524
535 525 entry->cddl_next =
536 526 usba_device->usb_client_dev_data_list.cddl_next;
537 527 if (entry->cddl_next) {
538 528 entry->cddl_next->cddl_prev = entry;
539 529 }
540 530 entry->cddl_prev = &usba_device->usb_client_dev_data_list;
541 531 usba_device->usb_client_dev_data_list.cddl_next = entry;
542 532
543 533 mutex_exit(&usba_device->usb_mutex);
544 534 }
545 535
546 536 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
547 537 "usb_get_dev_data rval=%d", rval);
548 538
549 539 return (rval);
550 540 }
551 541
552 542
553 543 /*
554 544 * usb_free_dev_data
555 545 * undoes what usb_get_dev_data does
556 546 *
557 547 * Arguments:
558 548 * dip - pointer to devinfo node of the client
559 549 * reg - return registration data at this address
560 550 */
561 551 void
562 552 usb_free_dev_data(dev_info_t *dip, usb_client_dev_data_t *reg)
563 553 {
564 554 if (dip == NULL) {
565 555
566 556 return;
567 557 }
568 558
569 559 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
570 560 "usb_free_dev_data %s%d: reg=0x%p",
571 561 ddi_driver_name(dip), ddi_get_instance(dip), (void *)reg);
572 562
573 563 if (reg != NULL) {
574 564 usba_device_t *usba_device = usba_get_usba_device(dip);
575 565 usb_client_dev_data_list_t *next, *prev, *entry;
576 566 int matches = 0;
577 567
578 568 if (reg->dev_serial != NULL) {
579 569 kmem_free((char *)reg->dev_serial,
580 570 strlen((char *)reg->dev_serial) + 1);
581 571 }
582 572
583 573 if (reg->dev_product != NULL) {
584 574 kmem_free((char *)reg->dev_product,
585 575 strlen((char *)reg->dev_product) + 1);
586 576 }
587 577
↓ open down ↓ |
138 lines elided |
↑ open up ↑ |
588 578 if (reg->dev_mfg != NULL) {
589 579 kmem_free((char *)reg->dev_mfg,
590 580 strlen((char *)reg->dev_mfg) + 1);
591 581 }
592 582
593 583 /* Free config tree under reg->dev_cfg. */
594 584 if (reg->dev_cfg != NULL) {
595 585 usb_free_descr_tree(dip, reg);
596 586 }
597 587
598 - if (reg->dev_bos != NULL) {
599 - kmem_free(reg->dev_bos, sizeof (usb_bos_data_t));
600 - }
601 -
602 588 mutex_enter(&usba_device->usb_mutex);
603 589 prev = &usba_device->usb_client_dev_data_list;
604 590 entry = usba_device->usb_client_dev_data_list.cddl_next;
605 591
606 592 /* free the entries in usb_client_data_list */
607 593 while (entry) {
608 594 next = entry->cddl_next;
609 595 if ((dip == entry->cddl_dip) &&
610 596 (reg == entry->cddl_dev_data)) {
611 597 prev->cddl_next = entry->cddl_next;
612 598 if (entry->cddl_next) {
613 599 entry->cddl_next->cddl_prev = prev;
614 600 }
615 601 kmem_free(entry, sizeof (*entry));
616 602 } else {
617 603 /*
618 604 * any other entries for this interface?
619 605 */
620 606 if (usba_get_ifno(dip) == entry->cddl_ifno) {
621 607 matches++;
622 608 }
623 609 prev = entry;
624 610 }
625 611 entry = next;
626 612 }
627 613
628 614 USB_DPRINTF_L3(DPRINT_MASK_REGISTER,
629 615 usbai_reg_log_handle,
630 616 "usb_free_dev_data: next=0x%p flags[%d]=0x%x",
631 617 (void *)usba_device->usb_client_dev_data_list.cddl_next,
632 618 usba_get_ifno(dip),
633 619 usba_device->usb_client_flags[usba_get_ifno(dip)]);
634 620
635 621 if (matches == 0) {
636 622 usba_device->
637 623 usb_client_flags[usba_get_ifno(dip)] &=
638 624 ~USBA_CLIENT_FLAG_DEV_DATA;
639 625 }
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
640 626 mutex_exit(&usba_device->usb_mutex);
641 627
642 628 kmem_free(reg, sizeof (usb_client_dev_data_t));
643 629 }
644 630
645 631 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
646 632 "usb_free_dev_data done");
647 633 }
648 634
649 635 /*
650 - * This builds the BOS descriptors for WUSB device
651 - */
652 -static int
653 -usba_build_bos(usba_device_t *usba_device, usb_client_dev_data_t *usb_reg)
654 -{
655 - uint8_t *buf;
656 - size_t size, buflen;
657 -
658 - buf = usba_device->usb_wireless_data->wusb_bos;
659 - buflen = usba_device->usb_wireless_data->wusb_bos_length;
660 -
661 - usb_reg->dev_bos = kmem_zalloc(sizeof (usb_bos_data_t),
662 - KM_SLEEP);
663 - size = usb_parse_bos_descr(buf, buflen, &usb_reg->dev_bos->bos_descr,
664 - sizeof (usb_bos_descr_t));
665 - if (size != USB_BOS_DESCR_SIZE) {
666 - kmem_free(usb_reg->dev_bos, sizeof (usb_bos_data_t));
667 -
668 - return (USB_FAILURE);
669 - }
670 -
671 - size = usb_parse_uwb_bos_descr(buf, buflen,
672 - &usb_reg->dev_bos->bos_uwb_cap, sizeof (usb_uwb_cap_descr_t));
673 - if (size != USB_UWB_CAP_DESCR_SIZE) {
674 - kmem_free(usb_reg->dev_bos, sizeof (usb_bos_data_t));
675 -
676 - return (USB_FAILURE);
677 - }
678 -
679 - return (USB_SUCCESS);
680 -}
681 -
682 -
683 -/*
684 636 * usba_build_descr_tree:
685 637 * This builds the descriptor tree. See module header comment for tree
686 638 * description.
687 639 *
688 640 * Arguments:
689 641 * dip - devinfo pointer - cannot be NULL.
690 642 * usba_device - pointer to usba_device structure.
691 643 * usb_reg - pointer to area returned to client describing device.
692 644 * number of configuration (dev_n_cfg) and array of
693 645 * configurations (dev_cfg) are initialized here -
694 646 * dev_parse_level used and may be modified to fit
695 647 * current configuration.
696 648 * Return values:
697 649 * USB_SUCCESS - Tree build succeeded
698 650 * USB_INVALID_ARGS - dev_parse_level in usb_reg is invalid.
699 651 * USB_FAILURE - Bad descriptor info or other internal failure
700 652 */
701 653 static int
702 654 usba_build_descr_tree(dev_info_t *dip, usba_device_t *usba_device,
703 655 usb_client_dev_data_t *usb_reg)
704 656 {
705 657 usba_reg_state_t state; /* State of tree construction */
706 658 int cfg_len_so_far = 0; /* Bytes found, this config. */
707 659 uint8_t *last_byte; /* Ptr to the end of the cfg cloud. */
708 660 uint_t this_cfg_ndx; /* Configuration counter. */
709 661 uint_t high_cfg_bound; /* High config index + 1. */
710 662 uint_t low_cfg_bound; /* Low config index. */
711 663 boolean_t process_this_if_tree = B_FALSE; /* Save alts, eps, */
712 664 /* of this interface. */
713 665
714 666 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
715 667 "usba_build_descr_tree starting");
716 668
717 669 bzero(&state, sizeof (usba_reg_state_t));
718 670 state.dip = dip;
719 671
720 672 /*
721 673 * Set config(s) and interface(s) to parse based on parse level.
722 674 * Adjust parse_level according to which configs and interfaces are
723 675 * made available by the device.
724 676 */
725 677 state.st_dev_parse_level = usb_reg->dev_parse_level;
726 678 if (usba_set_parse_values(dip, usba_device, &state) != USB_SUCCESS) {
727 679
728 680 return (USB_INVALID_ARGS);
729 681 }
730 682 usb_reg->dev_parse_level = state.st_dev_parse_level;
731 683
732 684 /* Preallocate configurations based on parse level. */
733 685 if (usb_reg->dev_parse_level == USB_PARSE_LVL_ALL) {
734 686 usb_reg->dev_n_cfg = usba_device->usb_n_cfgs;
735 687 low_cfg_bound = 0;
736 688 high_cfg_bound = usba_device->usb_n_cfgs;
737 689 } else {
738 690 usb_reg->dev_n_cfg = 1;
739 691 mutex_enter(&usba_device->usb_mutex);
740 692 low_cfg_bound = usba_device->usb_active_cfg_ndx;
741 693 high_cfg_bound = usba_device->usb_active_cfg_ndx + 1;
742 694 mutex_exit(&usba_device->usb_mutex);
743 695 }
744 696 usb_reg->dev_cfg = state.st_dev_cfg = kmem_zalloc(
745 697 (usb_reg->dev_n_cfg * sizeof (usb_cfg_data_t)),
746 698 KM_SLEEP);
747 699 /*
748 700 * this_cfg_ndx loops through all configurations presented;
749 701 * state.st_dev_n_cfg limits the cfgs checked to the number desired.
750 702 */
751 703 state.st_dev_n_cfg = 0;
752 704 for (this_cfg_ndx = low_cfg_bound; this_cfg_ndx < high_cfg_bound;
753 705 this_cfg_ndx++) {
754 706
755 707 state.st_curr_raw_descr =
756 708 usba_device->usb_cfg_array[this_cfg_ndx];
757 709 ASSERT(state.st_curr_raw_descr != NULL);
758 710
759 711 /* Clear the following for config cloud sanity checking. */
760 712 last_byte = NULL;
761 713 state.st_curr_cfg = NULL;
762 714 state.st_curr_if = NULL;
763 715 state.st_curr_alt = NULL;
764 716 state.st_curr_ep = NULL;
765 717
766 718 do {
767 719 /* All descr have length and type at offset 0 and 1 */
768 720 state.st_curr_raw_descr_len =
769 721 state.st_curr_raw_descr[0];
770 722 state.st_curr_raw_descr_type =
771 723 state.st_curr_raw_descr[1];
772 724
773 725 /* First descr in cloud must be a config descr. */
774 726 if ((last_byte == NULL) &&
775 727 (state.st_curr_raw_descr_type !=
776 728 USB_DESCR_TYPE_CFG)) {
777 729
778 730 return (USB_FAILURE);
779 731 }
780 732
781 733 /*
782 734 * Bomb if we don't find a new cfg descr when expected.
783 735 * cfg_len_so_far = total_cfg_length = 0 1st time thru.
784 736 */
785 737 if (cfg_len_so_far > state.st_total_cfg_length) {
786 738 USB_DPRINTF_L2(DPRINT_MASK_ALL,
787 739 usbai_reg_log_handle,
788 740 "usba_build_descr_tree: Configuration (%d) "
789 741 "larger than wTotalLength (%d).",
790 742 cfg_len_so_far, state.st_total_cfg_length);
791 743
792 744 return (USB_FAILURE);
793 745 }
794 746
795 747 USB_DPRINTF_L3(DPRINT_MASK_REGISTER,
796 748 usbai_reg_log_handle,
797 749 "usba_build_descr_tree: Process type %d descr "
798 750 "(addr=0x%p)", state.st_curr_raw_descr_type,
799 751 (void *)state.st_curr_raw_descr);
800 752
801 753 switch (state.st_curr_raw_descr_type) {
802 754 case USB_DESCR_TYPE_CFG:
803 755 cfg_len_so_far = 0;
804 756 process_this_if_tree = B_FALSE;
805 757
806 758 state.st_curr_cfg_str = usba_device->
807 759 usb_cfg_str_descr[this_cfg_ndx];
808 760 usba_process_cfg_descr(&state);
809 761 state.st_last_processed_descr_type =
810 762 USB_DESCR_TYPE_CFG;
811 763 last_byte = state.st_curr_raw_descr +
812 764 (state.st_total_cfg_length *
813 765 sizeof (uchar_t));
814 766
815 767 break;
816 768
817 769 case USB_DESCR_TYPE_IF:
818 770 /*
819 771 * process_this_if_tree == TRUE means this
820 772 * interface, plus all eps and c/vs in it are
821 773 * to be processed.
822 774 */
823 775 if (usba_process_if_descr(&state,
824 776 &process_this_if_tree) != USB_SUCCESS) {
825 777
826 778 return (USB_FAILURE);
827 779 }
828 780 state.st_last_processed_descr_type =
829 781 USB_DESCR_TYPE_IF;
830 782
831 783 break;
832 784
833 785 case USB_DESCR_TYPE_EP:
834 786 /*
835 787 * Skip if endpoints of a specific interface are
836 788 * desired and this endpoint is associated with
837 789 * a different interface.
838 790 */
839 791 if (process_this_if_tree) {
↓ open down ↓ |
146 lines elided |
↑ open up ↑ |
840 792 if (usba_process_ep_descr(&state) !=
841 793 USB_SUCCESS) {
842 794
843 795 return (USB_FAILURE);
844 796 }
845 797 state.st_last_processed_descr_type =
846 798 USB_DESCR_TYPE_EP;
847 799 }
848 800
849 801 break;
850 - case USB_DESCR_TYPE_WIRELESS_EP_COMP:
851 - /* for WUSB devices */
852 - if (process_this_if_tree &&
853 - state.st_build_ep_comp) {
854 - if (usba_process_ep_comp_descr(
855 - &state) != USB_SUCCESS) {
856 -
857 - return (USB_FAILURE);
858 - }
859 - }
860 -
861 - break;
862 802 case USB_DESCR_TYPE_STRING:
863 803 USB_DPRINTF_L2(DPRINT_MASK_ALL,
864 804 usbai_reg_log_handle,
865 805 "usb_get_dev_data: "
866 806 "Found unexpected str descr at addr 0x%p",
867 807 (void *)state.st_curr_raw_descr);
868 808
869 809 break; /* Shouldn't be any here. Skip. */
870 810
871 811 default:
872 812 /*
873 813 * Treat all other descr as class/vendor
874 814 * specific. Skip if c/vs of a specific
875 815 * interface are desired and this c/v is
876 816 * associated with a different one.
877 817 * Device level c/vs should always be
878 818 * processed, e.g., the security descrs
879 819 * for the Host Wire Adapter.
880 820 */
881 821 if ((state.st_last_processed_descr_type ==
882 822 USB_DESCR_TYPE_CFG) ||
883 823 (process_this_if_tree == B_TRUE)) {
884 824 if (usba_process_cv_descr(&state) !=
885 825 USB_SUCCESS) {
886 826
887 827 return (USB_FAILURE);
888 828 }
889 829 }
890 830 }
891 831
892 832 state.st_curr_raw_descr += state.st_curr_raw_descr_len;
893 833 cfg_len_so_far += state.st_curr_raw_descr_len;
894 834
895 835 } while (state.st_curr_raw_descr < last_byte);
896 836 }
897 837
898 838 /* Make tree sparse, and put elements in order. */
899 839 usba_order_tree(&state);
900 840
901 841 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
902 842 "usba_build_descr_tree done");
903 843
904 844 return (USB_SUCCESS);
905 845 }
906 846
907 847
908 848 /*
909 849 * usba_process_cfg_descr:
910 850 * Set up a configuration tree node based on a raw config descriptor.
911 851 *
912 852 * Arguments:
913 853 * state - Pointer to this module's state structure.
914 854 *
915 855 * Returns:
916 856 * B_TRUE: the descr processed corresponds to a requested configuration.
917 857 * B_FALSE: the descr processed does not correspond to a requested config.
918 858 */
919 859 static void
920 860 usba_process_cfg_descr(usba_reg_state_t *state)
921 861 {
922 862 usb_cfg_data_t *curr_cfg;
923 863
924 864 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
925 865 "usba_process_cfg_descr starting");
926 866
927 867 curr_cfg = state->st_curr_cfg =
928 868 &state->st_dev_cfg[state->st_dev_n_cfg++];
929 869
930 870 /* Parse and store config descriptor proper in the tree. */
931 871 (void) usb_parse_data("2cs5c",
932 872 state->st_curr_raw_descr, state->st_curr_raw_descr_len,
933 873 &curr_cfg->cfg_descr,
934 874 sizeof (usb_cfg_descr_t));
935 875
936 876 state->st_total_cfg_length = curr_cfg->cfg_descr.wTotalLength;
937 877
938 878 if (state->st_curr_cfg_str != NULL) {
939 879 curr_cfg->cfg_strsize = strlen(state->st_curr_cfg_str) + 1;
940 880 curr_cfg->cfg_str = kmem_zalloc(curr_cfg->cfg_strsize,
941 881 KM_SLEEP);
942 882 (void) strcpy(curr_cfg->cfg_str, state->st_curr_cfg_str);
943 883 }
944 884
945 885 curr_cfg->cfg_n_if = curr_cfg->cfg_descr.bNumInterfaces;
946 886 curr_cfg->cfg_if = kmem_zalloc((curr_cfg->cfg_n_if *
947 887 sizeof (usb_if_data_t)), KM_SLEEP);
948 888
949 889 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
950 890 "usba_process_cfg_descr done");
951 891 }
952 892
953 893
954 894 /*
955 895 * usba_process_if_descr:
956 896 * This processes a raw interface descriptor, and sets up an analogous
957 897 * interface node and child "alternate" nodes (each containing an
958 898 * interface descriptor) in the descriptor tree.
959 899 *
960 900 * It groups all descriptors with the same bInterfaceNumber (alternates)
961 901 * into an array. It makes entries in an interface array, each of which
962 902 * points to an array of alternates.
963 903 *
964 904 * Arguments:
965 905 * state - Pointer to this module's state structure.
966 906 * requested_if - Address into which the following is returned:
967 907 * B_TRUE - the processed descr is of a requested interface.
968 908 * B_FALSE - the processed descr if of a non-requested interface.
969 909 *
970 910 * Returns:
971 911 * USB_SUCCESS: Descriptor is successfully parsed.
972 912 * USB_FAILURE: Descriptor is inappropriately placed in config cloud.
973 913 */
974 914 static int
975 915 usba_process_if_descr(usba_reg_state_t *state, boolean_t *requested_if)
976 916 {
977 917 char *string;
978 918 usb_if_descr_t *new_if_descr;
979 919 usba_device_t *usba_device = usba_get_usba_device(state->dip);
980 920 int is_root_hub = (usba_device->usb_addr == ROOT_HUB_ADDR);
981 921
982 922 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
983 923 "usba_process_if_descr starting");
984 924
985 925 /* No config preceeds this interface. */
986 926 if (state->st_curr_cfg == NULL) {
987 927 USB_DPRINTF_L2(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
988 928 "usba_process_if_descr found interface after no config.");
989 929
990 930 return (USB_FAILURE);
991 931 }
992 932
993 933 new_if_descr = kmem_zalloc(sizeof (usb_if_descr_t), KM_SLEEP);
994 934
995 935 /* Strictly speaking, unpacking is not necessary. Could use bcopy. */
996 936 (void) usb_parse_data("9c", state->st_curr_raw_descr,
997 937 state->st_curr_raw_descr_len,
998 938 new_if_descr, sizeof (usb_if_descr_t));
999 939
1000 940 /* Check the interface number in case of a malfunction device */
1001 941 if (new_if_descr->bInterfaceNumber >= state->st_curr_cfg->cfg_n_if) {
1002 942 USB_DPRINTF_L2(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1003 943 "usba_process_if_descr: bInterfaceNumber=%d is not "
1004 944 "a valid one", new_if_descr->bInterfaceNumber);
1005 945 kmem_free(new_if_descr, sizeof (usb_if_descr_t));
1006 946
1007 947 *requested_if = B_FALSE;
1008 948
1009 949 return (USB_SUCCESS);
1010 950 }
1011 951 *requested_if = B_TRUE;
1012 952
1013 953 /* Not a requested interface. */
1014 954 if ((state->st_if_to_build != new_if_descr->bInterfaceNumber) &&
1015 955 (state->st_if_to_build != USBA_ALL)) {
1016 956 *requested_if = B_FALSE;
1017 957
1018 958 } else {
1019 959 usb_alt_if_data_t *alt_array;
1020 960 uint_t alt_index;
1021 961
1022 962 /* Point to proper interface node, based on num in descr. */
1023 963 state->st_curr_if =
1024 964 &state->st_curr_cfg->cfg_if[new_if_descr->bInterfaceNumber];
1025 965
1026 966 /* Make room for new alternate. */
1027 967 alt_index = state->st_curr_if->if_n_alt;
1028 968 alt_array = state->st_curr_if->if_alt;
1029 969 usba_augment_array((void **)(&alt_array), alt_index,
1030 970 sizeof (usb_alt_if_data_t));
1031 971
1032 972 /* Ptr to the current alt, may be used to attach a c/v to it. */
1033 973 state->st_curr_alt = &alt_array[alt_index];
1034 974
1035 975 bcopy(new_if_descr, &(alt_array[alt_index++].altif_descr),
1036 976 sizeof (usb_if_descr_t));
1037 977 state->st_curr_if->if_alt = alt_array;
1038 978 state->st_curr_if->if_n_alt = alt_index;
1039 979
1040 980 string = kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP);
1041 981 if (!is_root_hub) {
1042 982 (void) usb_get_string_descr(state->dip, USB_LANG_ID,
1043 983 state->st_curr_alt->altif_descr.iInterface,
1044 984 string, USB_MAXSTRINGLEN);
1045 985 }
1046 986 if (string[0] == '\0') {
1047 987 (void) strcpy(string, "<none>");
1048 988 }
1049 989 state->st_curr_alt->altif_strsize = strlen(string) + 1;
1050 990 state->st_curr_alt->altif_str = kmem_zalloc(
1051 991 state->st_curr_alt->altif_strsize, KM_SLEEP);
1052 992 (void) strcpy(state->st_curr_alt->altif_str, string);
1053 993 kmem_free(string, USB_MAXSTRINGLEN);
1054 994 }
1055 995
1056 996 kmem_free(new_if_descr, sizeof (usb_if_descr_t));
1057 997
1058 998 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1059 999 "usba_process_if_descr done");
1060 1000
1061 1001 return (USB_SUCCESS);
1062 1002 }
1063 1003
1064 1004
1065 1005 /*
1066 1006 * usba_process_ep_descr:
1067 1007 * This processes a raw endpoint descriptor, and sets up an analogous
1068 1008 * endpoint descriptor node in the descriptor tree.
1069 1009 *
1070 1010 * Arguments:
1071 1011 * state - Pointer to this module's state structure.
1072 1012 *
1073 1013 * Returns:
1074 1014 * USB_SUCCESS: Descriptor is successfully parsed.
1075 1015 * USB_FAILURE: Descriptor is inappropriately placed in config cloud.
1076 1016 */
1077 1017 static int
1078 1018 usba_process_ep_descr(usba_reg_state_t *state)
1079 1019 {
1080 1020 usb_alt_if_data_t *curr_alt = state->st_curr_alt;
1081 1021
1082 1022 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1083 1023 "usba_process_ep_descr starting");
1084 1024
1085 1025 /* No interface preceeds this endpoint. */
1086 1026 if (state->st_curr_alt == NULL) {
1087 1027 USB_DPRINTF_L2(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1088 1028 "usba_process_ep_descr: no requested alt before endpt.");
1089 1029
1090 1030 return (USB_FAILURE);
1091 1031 }
1092 1032
1093 1033 usba_augment_array((void **)(&curr_alt->altif_ep),
1094 1034 curr_alt->altif_n_ep, sizeof (usb_ep_data_t));
1095 1035
1096 1036 /* Ptr to the current endpt, may be used to attach a c/v to it. */
1097 1037 state->st_curr_ep = &curr_alt->altif_ep[curr_alt->altif_n_ep++];
1098 1038
1099 1039 (void) usb_parse_data("4csc", state->st_curr_raw_descr,
↓ open down ↓ |
228 lines elided |
↑ open up ↑ |
1100 1040 state->st_curr_raw_descr_len,
1101 1041 &state->st_curr_ep->ep_descr, sizeof (usb_ep_descr_t));
1102 1042
1103 1043 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1104 1044 "usba_process_ep_descr done");
1105 1045
1106 1046 return (USB_SUCCESS);
1107 1047 }
1108 1048
1109 1049
1110 -static int
1111 -usba_process_ep_comp_descr(usba_reg_state_t *state)
1112 -{
1113 - USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1114 - "usba_process_ep_comp_descr starting");
1115 -
1116 - /* No endpoint descr preceeds this descr */
1117 - if (state->st_curr_ep == NULL) {
1118 - USB_DPRINTF_L2(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1119 - "usba_process_ep_comp_descr: no endpt before the descr");
1120 -
1121 - return (USB_FAILURE);
1122 - }
1123 -
1124 - (void) usb_parse_data("ccccsscc", state->st_curr_raw_descr,
1125 - state->st_curr_raw_descr_len,
1126 - &state->st_curr_ep->ep_comp_descr,
1127 - sizeof (usb_ep_comp_descr_t));
1128 - USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1129 - "usba_process_ep_comp_descr done");
1130 -
1131 - return (USB_SUCCESS);
1132 -}
1133 -
1134 1050 /*
1135 1051 * usba_process_cv_descr:
1136 1052 * This processes a raw endpoint descriptor, and sets up an analogous
1137 1053 * endpoint descriptor in the descriptor tree. C/Vs are associated with
1138 1054 * other descriptors they follow in the raw data.
1139 1055 * last_processed_descr_type indicates the type of descr this c/v follows.
1140 1056 *
1141 1057 * Arguments:
1142 1058 * state - Pointer to this module's state structure.
1143 1059 *
1144 1060 * Returns:
1145 1061 * USB_SUCCESS: Descriptor is successfully parsed.
1146 1062 * USB_FAILURE: Descriptor is inappropriately placed in config cloud.
1147 1063 */
1148 1064 static int
1149 1065 usba_process_cv_descr(usba_reg_state_t *state)
1150 1066 {
1151 1067 usb_cvs_data_t *curr_cv_descr;
1152 1068 usb_cvs_data_t **cvs_ptr = NULL;
1153 1069 uint_t *n_cvs_ptr;
1154 1070
1155 1071 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1156 1072 "usba_process_cv_descr starting. Processing c/v for descr type %d",
1157 1073 state->st_last_processed_descr_type);
1158 1074
1159 1075 /*
1160 1076 * Attach the c/v to a node based on the last descr type processed.
1161 1077 * Save handles to appropriate c/v node array and count to update.
1162 1078 */
1163 1079 switch (state->st_last_processed_descr_type) {
1164 1080 case USB_DESCR_TYPE_CFG:
1165 1081 n_cvs_ptr = &state->st_curr_cfg->cfg_n_cvs;
1166 1082 cvs_ptr = &state->st_curr_cfg->cfg_cvs;
1167 1083 break;
1168 1084
1169 1085 case USB_DESCR_TYPE_IF:
1170 1086 n_cvs_ptr = &state->st_curr_alt->altif_n_cvs;
1171 1087 cvs_ptr = &state->st_curr_alt->altif_cvs;
1172 1088 break;
1173 1089
1174 1090 case USB_DESCR_TYPE_EP:
1175 1091 n_cvs_ptr = &state->st_curr_ep->ep_n_cvs;
1176 1092 cvs_ptr = &state->st_curr_ep->ep_cvs;
1177 1093 break;
1178 1094
1179 1095 default:
1180 1096 USB_DPRINTF_L2(DPRINT_MASK_ALL, usbai_reg_log_handle,
1181 1097 "usba_process_cv_descr: Type of last descriptor unknown. ");
1182 1098
1183 1099 return (USB_FAILURE);
1184 1100 }
1185 1101
1186 1102 usba_augment_array((void **)cvs_ptr, *n_cvs_ptr,
1187 1103 sizeof (usb_cvs_data_t));
1188 1104 curr_cv_descr = &(*cvs_ptr)[(*n_cvs_ptr)++];
1189 1105
1190 1106 curr_cv_descr->cvs_buf =
1191 1107 kmem_zalloc(state->st_curr_raw_descr_len, KM_SLEEP);
1192 1108 curr_cv_descr->cvs_buf_len = state->st_curr_raw_descr_len;
1193 1109 bcopy(state->st_curr_raw_descr, curr_cv_descr->cvs_buf,
1194 1110 state->st_curr_raw_descr_len);
1195 1111
1196 1112 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1197 1113 "usba_process_cv_descr done");
1198 1114
1199 1115 return (USB_SUCCESS);
1200 1116 }
1201 1117
1202 1118
1203 1119 /*
1204 1120 * usba_set_parse_values:
1205 1121 * Based on parse level, set the configuration(s) and interface(s) to build
1206 1122 *
1207 1123 * Returned configuration value can be USBA_ALL indicating to build all
1208 1124 * configurations. Likewise for the returned interface value.
1209 1125 *
1210 1126 * Arguments:
1211 1127 * dip - pointer to devinfo of the device
1212 1128 * usba_device - pointer to usba_device structure of the device
1213 1129 * state - Pointer to this module's state structure.
1214 1130 * if no specific config specified, default to all config
1215 1131 * if no specific interface specified, default to all.
1216 1132 * if_to_build and config_to_build are modified.
1217 1133 * dev_parse_level may be modified.
1218 1134 *
1219 1135 * Returns:
↓ open down ↓ |
76 lines elided |
↑ open up ↑ |
1220 1136 * USB_SUCCESS - success
1221 1137 * USB_INVALID_ARGS - state->st_dev_parse_level is invalid.
1222 1138 */
1223 1139 static int
1224 1140 usba_set_parse_values(dev_info_t *dip, usba_device_t *usba_device,
1225 1141 usba_reg_state_t *state)
1226 1142 {
1227 1143 /* Default to *all* in case configuration# prop not set. */
1228 1144 mutex_enter(&usba_device->usb_mutex);
1229 1145 state->st_cfg_to_build = usba_device->usb_active_cfg_ndx;
1230 - state->st_build_ep_comp = usba_device->usb_is_wireless;
1231 1146 mutex_exit(&usba_device->usb_mutex);
1232 1147 if (state->st_cfg_to_build == USBA_DEV_CONFIG_INDEX_UNDEFINED) {
1233 1148 state->st_cfg_to_build = USBA_ALL;
1234 1149 }
1235 1150 state->st_if_to_build = usb_get_if_number(dip);
1236 1151
1237 1152 switch (state->st_dev_parse_level) {
1238 1153 case USB_PARSE_LVL_ALL: /* Parse all configurations */
1239 1154 state->st_cfg_to_build = USBA_ALL;
1240 1155 state->st_if_to_build = USBA_ALL;
1241 1156 break;
1242 1157
1243 1158 case USB_PARSE_LVL_CFG: /* Parse all interfaces of a */
1244 1159 /* specific configuration. */
1245 1160 state->st_if_to_build = USBA_ALL;
1246 1161 break;
1247 1162
1248 1163 case USB_PARSE_LVL_IF: /* Parse configured interface only */
1249 1164 if (state->st_if_to_build < 0) {
1250 1165 state->st_if_to_build = USBA_ALL;
1251 1166 }
1252 1167 break;
1253 1168
1254 1169 default:
1255 1170
1256 1171 return (USB_INVALID_ARGS);
1257 1172 }
1258 1173
1259 1174 /*
1260 1175 * Set parse level to identify this tree properly, regardless of what
1261 1176 * the caller thought the tree would have.
1262 1177 */
1263 1178 if ((state->st_if_to_build == USBA_ALL) &&
1264 1179 (state->st_dev_parse_level == USB_PARSE_LVL_IF)) {
1265 1180 state->st_dev_parse_level = USB_PARSE_LVL_CFG;
1266 1181 }
1267 1182 if ((state->st_cfg_to_build == USBA_ALL) &&
1268 1183 (state->st_dev_parse_level == USB_PARSE_LVL_CFG)) {
1269 1184 state->st_dev_parse_level = USB_PARSE_LVL_ALL;
1270 1185 }
1271 1186
1272 1187 return (USB_SUCCESS);
1273 1188 }
1274 1189
1275 1190
1276 1191 /*
1277 1192 * usba_kmem_realloc:
1278 1193 * Resize dynamic memory. Copy contents of old area to
1279 1194 * beginning of new area.
1280 1195 *
1281 1196 * Arguments:
1282 1197 * old_mem - pointer to old memory area.
1283 1198 * old_size - size of old memory area. 0 is OK.
1284 1199 * new_size - size desired.
1285 1200 *
1286 1201 * Returns:
1287 1202 * pointer to new memory area.
1288 1203 */
1289 1204 static void*
1290 1205 usba_kmem_realloc(void* old_mem, int old_size, int new_size)
1291 1206 {
1292 1207 void *new_mem = NULL;
1293 1208
1294 1209 if (new_size > 0) {
1295 1210 new_mem = kmem_zalloc(new_size, KM_SLEEP);
1296 1211 if (old_size > 0) {
1297 1212 bcopy(old_mem, new_mem,
1298 1213 min(old_size, new_size));
1299 1214 }
1300 1215 }
1301 1216
1302 1217 if (old_size > 0) {
1303 1218 kmem_free(old_mem, old_size);
1304 1219 }
1305 1220
1306 1221 return (new_mem);
1307 1222 }
1308 1223
1309 1224
1310 1225 /*
1311 1226 * usba_augment_array:
1312 1227 * Add a new element on the end of an array.
1313 1228 *
1314 1229 * Arguments:
1315 1230 * addr - ptr to the array address. Array addr will change.
1316 1231 * n_elements - array element count.
1317 1232 * element_size - size of an array element
1318 1233 */
1319 1234 static void
1320 1235 usba_augment_array(void **addr, uint_t n_elements, uint_t element_size)
1321 1236 {
1322 1237 *addr = usba_kmem_realloc(*addr, (n_elements * element_size),
1323 1238 ((n_elements + 1) * element_size));
1324 1239 }
1325 1240
1326 1241
1327 1242 /*
1328 1243 * usba_make_alts_sparse:
1329 1244 * Disburse alternate array elements such that they are at the proper array
1330 1245 * indices for which alt they represent. It is assumed that all key values
1331 1246 * used for ordering the elements are positive. Original array space may
1332 1247 * be freed and new space allocated.
1333 1248 *
1334 1249 * Arguments:
1335 1250 * array - pointer to alternates array; may be modified
1336 1251 * n_elements - number of elements in the array; may be modified
1337 1252 */
1338 1253 static void
1339 1254 usba_make_alts_sparse(usb_alt_if_data_t **array, uint_t *n_elements)
1340 1255 {
1341 1256 uint_t n_orig_elements = *n_elements;
1342 1257 uint8_t smallest_value;
1343 1258 uint8_t largest_value;
1344 1259 uint8_t curr_value;
1345 1260 uint_t in_order = 0;
1346 1261 usb_alt_if_data_t *orig_addr = *array; /* Non-sparse array base ptr */
1347 1262 usb_alt_if_data_t *repl_array; /* Base ptr to sparse array */
1348 1263 uint_t n_repl_elements; /* Number elements in the new array */
1349 1264 uint_t i;
1350 1265
1351 1266 /* Check for a null array. */
1352 1267 if ((array == NULL) || (n_orig_elements == 0)) {
1353 1268
1354 1269 return;
1355 1270 }
1356 1271
1357 1272 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1358 1273 "make_sparse: array=0x%p, n_orig_elements=%d",
1359 1274 (void *)array, n_orig_elements);
1360 1275
1361 1276 curr_value = orig_addr[0].altif_descr.bAlternateSetting;
1362 1277 smallest_value = largest_value = curr_value;
1363 1278
1364 1279 /* Figure the low-high range of the array. */
1365 1280 for (i = 1; i < n_orig_elements; i++) {
1366 1281 curr_value = orig_addr[i].altif_descr.bAlternateSetting;
1367 1282 if (curr_value < smallest_value) {
1368 1283 smallest_value = curr_value;
1369 1284 } else if (curr_value > largest_value) {
1370 1285 in_order++;
1371 1286 largest_value = curr_value;
1372 1287 }
1373 1288 }
1374 1289 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1375 1290 "make_sparse: largest=%d, smallest=%d, "
1376 1291 "order=%d",
1377 1292 largest_value, smallest_value, in_order);
1378 1293
1379 1294 n_repl_elements = largest_value + 1;
1380 1295
1381 1296 /*
1382 1297 * No holes to leave, array starts at zero, and everything is already
1383 1298 * in order. Just return original array.
1384 1299 */
1385 1300 if ((n_repl_elements == n_orig_elements) &&
1386 1301 ((in_order + 1) == n_orig_elements)) {
1387 1302 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1388 1303 "No holes");
1389 1304
1390 1305 return;
1391 1306 }
1392 1307
1393 1308 /* Allocate zeroed space for the array. */
1394 1309 repl_array = kmem_zalloc(
1395 1310 (n_repl_elements * sizeof (usb_alt_if_data_t)), KM_SLEEP);
1396 1311
1397 1312 /* Now fill in the array. */
1398 1313 for (i = 0; i < n_orig_elements; i++) {
1399 1314 curr_value = orig_addr[i].altif_descr.bAlternateSetting;
1400 1315
1401 1316 /* Place in sparse array based on key. */
1402 1317 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1403 1318 "move %lu bytes (key %d) from 0x%p to 0x%p",
1404 1319 (unsigned long)sizeof (usb_alt_if_data_t), curr_value,
1405 1320 (void *)&orig_addr[i], (void *)&repl_array[curr_value]);
1406 1321
1407 1322 bcopy((char *)&orig_addr[i], (char *)&repl_array[curr_value],
1408 1323 sizeof (usb_alt_if_data_t));
1409 1324 }
1410 1325
1411 1326 kmem_free(*array, sizeof (usb_alt_if_data_t) * n_orig_elements);
1412 1327 *array = repl_array;
1413 1328 *n_elements = n_repl_elements;
1414 1329 }
1415 1330
1416 1331
1417 1332 /*
1418 1333 * usba_order_tree:
1419 1334 * Take a tree as built by usba_build_descr_tree and make sure the key
1420 1335 * values of all elements match their indeces. Proper order is implied.
1421 1336 *
1422 1337 * Arguments:
1423 1338 * state - Pointer to this module's state structure.
1424 1339 */
1425 1340 static void
1426 1341 usba_order_tree(usba_reg_state_t *state)
1427 1342 {
1428 1343 usb_cfg_data_t *this_cfg;
1429 1344 usb_if_data_t *this_if;
1430 1345 uint_t n_cfgs = state->st_dev_n_cfg;
1431 1346 uint_t cfg;
1432 1347 uint_t which_if;
1433 1348
1434 1349 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1435 1350 "usba_order_tree:");
1436 1351
1437 1352 for (cfg = 0; cfg < n_cfgs; cfg++) {
1438 1353 this_cfg = &state->st_dev_cfg[cfg];
1439 1354
1440 1355 for (which_if = 0; which_if < this_cfg->cfg_n_if; which_if++) {
1441 1356 this_if = this_cfg->cfg_if;
1442 1357 usba_make_alts_sparse(&this_if->if_alt,
1443 1358 &this_if->if_n_alt);
1444 1359 }
1445 1360 }
1446 1361 }
1447 1362
1448 1363
1449 1364 /*
1450 1365 * usb_free_descr_tree:
1451 1366 * Take down the configuration tree. Called internally and can be called
1452 1367 * from a driver standalone to take the tree down while leaving the rest
1453 1368 * of the registration intact.
1454 1369 *
1455 1370 * Arguments:
1456 1371 * dip - pointer to devinfo of the device
1457 1372 * dev_data - pointer to registration data containing the tree.
1458 1373 */
1459 1374 void
1460 1375 usb_free_descr_tree(dev_info_t *dip, usb_client_dev_data_t *dev_data)
1461 1376 {
1462 1377 usb_cfg_data_t *cfg_array;
1463 1378 int n_cfgs;
1464 1379 int cfg;
1465 1380
1466 1381 if ((dip == NULL) || (dev_data == NULL)) {
1467 1382
1468 1383 return;
1469 1384 }
1470 1385 cfg_array = dev_data->dev_cfg;
1471 1386 n_cfgs = dev_data->dev_n_cfg;
1472 1387
1473 1388 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1474 1389 "usb_free_descr_tree starting for %s%d",
1475 1390 ddi_driver_name(dip), ddi_get_instance(dip));
1476 1391
1477 1392 for (cfg = 0; cfg < n_cfgs; cfg++) {
1478 1393 if (cfg_array[cfg].cfg_if) {
1479 1394 usba_free_if_array(cfg_array[cfg].cfg_if,
1480 1395 cfg_array[cfg].cfg_n_if);
1481 1396 }
1482 1397 if (cfg_array[cfg].cfg_cvs) {
1483 1398 usba_free_cv_array(cfg_array[cfg].cfg_cvs,
1484 1399 cfg_array[cfg].cfg_n_cvs);
1485 1400 }
1486 1401 if (cfg_array[cfg].cfg_str) {
1487 1402 kmem_free(cfg_array[cfg].cfg_str,
1488 1403 cfg_array[cfg].cfg_strsize);
1489 1404 }
1490 1405 }
1491 1406
1492 1407 if (cfg_array) {
1493 1408 kmem_free(cfg_array, (sizeof (usb_cfg_data_t) * n_cfgs));
1494 1409 }
1495 1410
1496 1411 dev_data->dev_parse_level = USB_PARSE_LVL_NONE;
1497 1412 dev_data->dev_n_cfg = 0;
1498 1413 dev_data->dev_cfg = NULL;
1499 1414 dev_data->dev_curr_cfg = NULL;
1500 1415
1501 1416 USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle,
1502 1417 "usb_free_descr_tree done");
1503 1418 }
1504 1419
1505 1420
1506 1421 /*
1507 1422 * usba_free_if_array:
1508 1423 * Free a configuration's array of interface nodes and their subtrees of
1509 1424 * interface alternate, endpoint and c/v descriptors.
1510 1425 *
1511 1426 * Arguments:
1512 1427 * if_array - pointer to array of interfaces to remove.
1513 1428 * n_ifs - number of elements in the array to remove.
1514 1429 */
1515 1430 static void
1516 1431 usba_free_if_array(usb_if_data_t *if_array, uint_t n_ifs)
1517 1432 {
1518 1433 uint_t which_if;
1519 1434 uint_t which_alt;
1520 1435 uint_t n_alts;
1521 1436 usb_alt_if_data_t *altif;
1522 1437
1523 1438 for (which_if = 0; which_if < n_ifs; which_if++) {
1524 1439 n_alts = if_array[which_if].if_n_alt;
1525 1440
1526 1441 /* Every interface has at least one alternate. */
1527 1442 for (which_alt = 0; which_alt < n_alts; which_alt++) {
1528 1443 altif = &if_array[which_if].if_alt[which_alt];
1529 1444 usba_free_ep_array(altif->altif_ep, altif->altif_n_ep);
1530 1445 usba_free_cv_array(altif->altif_cvs,
1531 1446 altif->altif_n_cvs);
1532 1447 kmem_free(altif->altif_str, altif->altif_strsize);
1533 1448 }
1534 1449
1535 1450 kmem_free(if_array[which_if].if_alt,
1536 1451 (sizeof (usb_alt_if_data_t) * n_alts));
1537 1452 }
1538 1453
1539 1454 /* Free the interface array itself. */
1540 1455 kmem_free(if_array, (sizeof (usb_if_data_t) * n_ifs));
1541 1456 }
1542 1457
1543 1458
1544 1459 /*
1545 1460 * usba_free_ep_array:
1546 1461 * Free an array of endpoint nodes and their subtrees of c/v descriptors.
1547 1462 *
1548 1463 * Arguments:
1549 1464 * ep_array - pointer to array of endpoints to remove.
1550 1465 * n_eps - number of elements in the array to remove.
1551 1466 */
1552 1467 static void
1553 1468 usba_free_ep_array(usb_ep_data_t *ep_array, uint_t n_eps)
1554 1469 {
1555 1470 uint_t ep;
1556 1471
1557 1472 for (ep = 0; ep < n_eps; ep++) {
1558 1473 usba_free_cv_array(ep_array[ep].ep_cvs, ep_array[ep].ep_n_cvs);
1559 1474 }
1560 1475
1561 1476 kmem_free(ep_array, (sizeof (usb_ep_data_t) * n_eps));
1562 1477 }
1563 1478
1564 1479
1565 1480 /*
1566 1481 * usba_free_cv_array:
1567 1482 * Free an array of class/vendor (c/v) descriptor nodes.
1568 1483 *
1569 1484 * Arguments:
1570 1485 * cv_array - pointer to array of c/v nodes to remove.
1571 1486 * n_cvs - number of elements in the array to remove.
1572 1487 */
1573 1488 static void
1574 1489 usba_free_cv_array(usb_cvs_data_t *cv_array, uint_t n_cvs)
1575 1490 {
1576 1491 uint_t cv_node;
1577 1492
1578 1493 /* Free data areas hanging off of each c/v descriptor. */
1579 1494 for (cv_node = 0; cv_node < n_cvs; cv_node++) {
1580 1495 kmem_free(cv_array[cv_node].cvs_buf,
1581 1496 cv_array[cv_node].cvs_buf_len);
1582 1497 }
1583 1498
1584 1499 /* Free the array of cv descriptors. */
1585 1500 kmem_free(cv_array, (sizeof (usb_cvs_data_t) * n_cvs));
1586 1501 }
1587 1502
1588 1503
1589 1504 /*
1590 1505 * usb_log_descr_tree:
1591 1506 * Log to the usba_debug_buf a descriptor tree as returned by
1592 1507 * usbai_register_client.
1593 1508 *
1594 1509 * Arguments:
1595 1510 * dev_data - pointer to registration area containing the tree
1596 1511 * log_handle - pointer to log handle to use for dumping.
1597 1512 * level - print level, one of USB_LOG_L0 ... USB_LOG_L4
1598 1513 * Please see usb_log(9F) for details.
1599 1514 * mask - print mask. Please see usb_log(9F) for details.
1600 1515 *
1601 1516 * Returns:
1602 1517 * USB_SUCCESS - tree successfully dumped
1603 1518 * USB_INVALID_CONTEXT - called from callback context
1604 1519 * USB_INVALID_ARGS - bad arguments given
1605 1520 */
1606 1521 int
1607 1522 usb_log_descr_tree(usb_client_dev_data_t *dev_data,
1608 1523 usb_log_handle_t log_handle, uint_t level, uint_t mask)
1609 1524 {
1610 1525 return (usba_dump_descr_tree(NULL, dev_data, log_handle, level, mask));
1611 1526 }
1612 1527
1613 1528
1614 1529 /*
1615 1530 * usb_print_descr_tree:
1616 1531 * Print to the screen a descriptor tree as returned by
1617 1532 * usbai_register_client.
1618 1533 *
1619 1534 * Arguments:
1620 1535 * dip - pointer to devinfo of the client
1621 1536 * dev_data - pointer to registration area containing the tree
1622 1537 *
1623 1538 * Returns:
1624 1539 * USB_SUCCESS - tree successfully dumped
1625 1540 * USB_INVALID_CONTEXT - called from callback context
1626 1541 * USB_INVALID_ARGS - bad arguments given
1627 1542 */
1628 1543 int
1629 1544 usb_print_descr_tree(dev_info_t *dip, usb_client_dev_data_t *dev_data)
1630 1545 {
1631 1546 return (usba_dump_descr_tree(dip, dev_data, NULL, 0, 0));
1632 1547 }
1633 1548
1634 1549
1635 1550 /*
1636 1551 * usba_dump_descr_tree:
1637 1552 * Dump a descriptor tree.
1638 1553 *
1639 1554 * Arguments:
1640 1555 * dip - pointer to devinfo of the client. Used when no
1641 1556 * log_handle argument given.
1642 1557 * usb_reg - pointer to registration area containing the tree
1643 1558 * log_handle - pointer to log handle to use for dumping. If NULL,
1644 1559 * use internal log handle, which dumps to screen.
1645 1560 * level - print level, one of USB_LOG_L0 ... USB_LOG_L4
1646 1561 * Used only when log_handle provided.
1647 1562 * mask - print mask, used when log_handle argument provided.
1648 1563 *
1649 1564 * Returns:
1650 1565 * USB_SUCCESS - tree successfully dumped
1651 1566 * USB_INVALID_CONTEXT - called from callback context
1652 1567 * USB_INVALID_ARGS - bad arguments given
1653 1568 */
1654 1569 static int
1655 1570 usba_dump_descr_tree(dev_info_t *dip, usb_client_dev_data_t *usb_reg,
1656 1571 usb_log_handle_t log_handle, uint_t level, uint_t mask)
1657 1572 {
1658 1573 usb_log_handle_t dump_handle;
1659 1574 uint_t dump_level;
1660 1575 uint_t dump_mask;
1661 1576 int which_config; /* Counters. */
1662 1577 int which_if;
1663 1578 int which_cv;
1664 1579 usb_cfg_data_t *config; /* ptr to current configuration tree node */
1665 1580 usb_cfg_descr_t *config_descr; /* and its USB descriptor. */
1666 1581 char *string;
1667 1582 char *name_string = NULL;
1668 1583 int name_string_size;
1669 1584
1670 1585 if ((usb_reg == NULL) || ((log_handle == NULL) && (dip == NULL))) {
1671 1586
1672 1587 return (USB_INVALID_ARGS);
1673 1588 }
1674 1589
1675 1590 /*
1676 1591 * To keep calling this simple, kmem_zalloc with the sleep flag always.
1677 1592 * This means no interrupt context is allowed.
1678 1593 */
1679 1594 if (servicing_interrupt()) {
1680 1595
1681 1596 return (USB_INVALID_CONTEXT);
1682 1597 }
1683 1598
1684 1599 string = kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP);
1685 1600
1686 1601 if (log_handle != NULL) {
1687 1602 dump_level = level;
1688 1603 dump_mask = mask;
1689 1604 dump_handle = log_handle;
1690 1605 } else {
1691 1606 dump_level = USB_LOG_L1;
1692 1607 dump_mask = DPRINT_MASK_ALL;
1693 1608
1694 1609 /* Build device name string. */
1695 1610 (void) snprintf(string, USB_MAXSTRINGLEN,
1696 1611 "Port%d", usb_get_addr(dip));
1697 1612 name_string_size = strlen(string) + 1;
1698 1613 name_string = kmem_zalloc(name_string_size, KM_SLEEP);
1699 1614 (void) strcpy(name_string, string);
1700 1615
1701 1616 /* Allocate a log handle specifying the name string. */
1702 1617 dump_handle = usb_alloc_log_hdl(NULL, name_string,
1703 1618 &dump_level, &dump_mask, NULL,
1704 1619 USB_FLAGS_SLEEP);
1705 1620 }
1706 1621
1707 1622 (void) usb_log(dump_handle, dump_level, dump_mask,
1708 1623 "USB descriptor tree for %s %s",
1709 1624 (usb_reg->dev_mfg != NULL ? usb_reg->dev_mfg : ""),
1710 1625 (usb_reg->dev_product != NULL ? usb_reg->dev_product : ""));
1711 1626 if (usb_reg->dev_n_cfg == 0) {
1712 1627 (void) usb_log(dump_handle, dump_level, dump_mask,
1713 1628 "No descriptor tree present");
1714 1629 } else {
1715 1630 (void) usb_log(dump_handle, dump_level, dump_mask,
1716 1631 "highest configuration found=%d", usb_reg->dev_n_cfg - 1);
1717 1632 }
1718 1633
1719 1634 for (which_config = 0; which_config < usb_reg->dev_n_cfg;
1720 1635 which_config++) {
1721 1636 config = &usb_reg->dev_cfg[which_config];
1722 1637 config_descr = &config->cfg_descr;
1723 1638 if (config_descr->bLength == 0) {
1724 1639
1725 1640 continue;
1726 1641 }
1727 1642 if (dump_level == USB_LOG_L0) {
1728 1643 (void) usb_log(dump_handle, dump_level, dump_mask, " ");
1729 1644 }
1730 1645 (void) usb_log(dump_handle, dump_level, dump_mask,
1731 1646 "Configuration #%d (Addr= 0x%p)", which_config,
1732 1647 (void *)config);
1733 1648 (void) usb_log(dump_handle, dump_level, dump_mask,
1734 1649 "String descr=%s", config->cfg_str);
1735 1650 (void) usb_log(dump_handle, dump_level, dump_mask,
1736 1651 "config descr: len=%d tp=%d totLen=%d numIf=%d "
1737 1652 "cfgVal=%d att=0x%x pwr=%d",
1738 1653 config_descr->bLength, config_descr->bDescriptorType,
1739 1654 config_descr->wTotalLength, config_descr->bNumInterfaces,
1740 1655 config_descr->bConfigurationValue,
1741 1656 config_descr->bmAttributes, config_descr->bMaxPower);
1742 1657 if ((config->cfg_n_if > 0) || (config->cfg_n_cvs > 0)) {
1743 1658 (void) usb_log(dump_handle, dump_level, dump_mask,
1744 1659 "usb_cfg_data_t shows max if=%d "
1745 1660 "and %d cv descr(s).",
1746 1661 config->cfg_n_if - 1, config->cfg_n_cvs);
1747 1662 }
1748 1663
1749 1664 for (which_if = 0; which_if < config->cfg_n_if;
1750 1665 which_if++) {
1751 1666
1752 1667 if (dump_level == USB_LOG_L0) {
1753 1668 (void) usb_log(dump_handle, dump_level,
1754 1669 dump_mask, " ");
1755 1670 }
1756 1671 (void) usb_log(dump_handle, dump_level, dump_mask,
1757 1672 " interface #%d (0x%p)",
1758 1673 which_if, (void *)&config->cfg_if[which_if]);
1759 1674 usba_dump_if(&config->cfg_if[which_if],
1760 1675 dump_handle, dump_level, dump_mask, string);
1761 1676 }
1762 1677
1763 1678 for (which_cv = 0; which_cv < config->cfg_n_cvs; which_cv++) {
1764 1679 (void) usb_log(dump_handle, dump_level, dump_mask,
1765 1680 " config cv descriptor %d (Address=0x%p)",
1766 1681 which_cv, (void *)&config->cfg_cvs[which_cv]);
1767 1682 usba_dump_cv(&config->cfg_cvs[which_cv],
1768 1683 dump_handle, dump_level, dump_mask, string, 4);
1769 1684 }
1770 1685 }
1771 1686
1772 1687 (void) usb_log(dump_handle, dump_level, dump_mask,
1773 1688 "Returning dev_curr_cfg:0x%p, dev_curr_if:%d",
1774 1689 (void *)usb_reg->dev_curr_cfg, usb_reg->dev_curr_if);
1775 1690
1776 1691 if (log_handle == NULL) {
1777 1692 usb_free_log_hdl(dump_handle);
1778 1693 }
1779 1694 if (name_string != NULL) {
1780 1695 kmem_free(name_string, name_string_size);
1781 1696 }
1782 1697 kmem_free(string, USB_MAXSTRINGLEN);
1783 1698
1784 1699 return (USB_SUCCESS);
1785 1700 }
1786 1701
1787 1702
1788 1703 /*
1789 1704 * usba_dump_if:
1790 1705 * Dump an interface node and its branches.
1791 1706 *
1792 1707 * Arguments:
1793 1708 * which_if - interface node to dump
1794 1709 * dump_handle - write data through this log handle
1795 1710 * dump_level - level passed to usb_log
1796 1711 * dump_mask - mask passed to usb_log
1797 1712 * string - temporary area used for processing
1798 1713 *
1799 1714 */
1800 1715 static void
1801 1716 usba_dump_if(usb_if_data_t *which_if, usb_log_handle_t dump_handle,
1802 1717 uint_t dump_level, uint_t dump_mask, char *string)
1803 1718 {
1804 1719 int which_alt; /* Number of alt being dumped */
1805 1720 usb_alt_if_data_t *alt; /* Pointer to it. */
1806 1721 usb_if_descr_t *if_descr; /* Pointer to its USB descr. */
1807 1722 int which_ep; /* Endpoint counter. */
1808 1723 int which_cv; /* C/V descr counter. */
1809 1724
1810 1725 for (which_alt = 0; which_alt < which_if->if_n_alt; which_alt++) {
1811 1726 alt = &which_if->if_alt[which_alt];
1812 1727 if_descr = &alt->altif_descr;
1813 1728
1814 1729 if (if_descr->bLength == 0) {
1815 1730
1816 1731 continue;
1817 1732 }
1818 1733 if (dump_level == USB_LOG_L0) {
1819 1734 (void) usb_log(dump_handle, dump_level, dump_mask, " ");
1820 1735 }
1821 1736 (void) usb_log(dump_handle, dump_level, dump_mask,
1822 1737 "\tAlt #%d (0x%p)", which_alt, (void *)alt);
1823 1738 (void) usb_log(dump_handle, dump_level, dump_mask,
1824 1739 "\tString descr=%s", alt->altif_str);
1825 1740 (void) usb_log(dump_handle, dump_level, dump_mask,
1826 1741 "\tif descr: len=%d type=%d if=%d alt=%d n_ept=%d "
1827 1742 "cls=%d sub=%d proto=%d",
1828 1743 if_descr->bLength,
1829 1744 if_descr->bDescriptorType, if_descr->bInterfaceNumber,
1830 1745 if_descr->bAlternateSetting, if_descr->bNumEndpoints,
1831 1746 if_descr->bInterfaceClass, if_descr->bInterfaceSubClass,
1832 1747 if_descr->bInterfaceProtocol);
1833 1748
1834 1749 if ((alt->altif_n_ep > 0) || (alt->altif_n_cvs > 0)) {
1835 1750 (void) usb_log(dump_handle, dump_level, dump_mask,
1836 1751 "\tusb_alt_if_data_t shows max ep=%d "
1837 1752 "and %d cv descr(s).",
1838 1753 alt->altif_n_ep - 1, alt->altif_n_cvs);
1839 1754 }
1840 1755
1841 1756 for (which_ep = 0; which_ep < alt->altif_n_ep;
1842 1757 which_ep++) {
1843 1758 if (alt->altif_ep[which_ep].ep_descr.bLength == 0) {
1844 1759
1845 1760 continue;
1846 1761 }
1847 1762 if (dump_level == USB_LOG_L0) {
1848 1763 (void) usb_log(dump_handle, dump_level,
1849 1764 dump_mask, " ");
1850 1765 }
1851 1766 usba_dump_ep(which_ep, &alt->altif_ep[which_ep],
1852 1767 dump_handle, dump_level, dump_mask, string);
1853 1768 }
1854 1769
1855 1770 for (which_cv = 0; which_cv < alt->altif_n_cvs; which_cv++) {
1856 1771 if (dump_level == USB_LOG_L0) {
1857 1772 (void) usb_log(dump_handle, dump_level,
1858 1773 dump_mask, " ");
1859 1774 }
1860 1775 (void) usb_log(dump_handle, dump_level, dump_mask,
1861 1776 "\talt cv descriptor #%d (0x%p), size=%d",
1862 1777 which_cv, (void *)&alt->altif_cvs[which_cv],
1863 1778 alt->altif_cvs[which_cv].cvs_buf_len);
1864 1779 usba_dump_cv(&alt->altif_cvs[which_cv],
1865 1780 dump_handle, dump_level, dump_mask, string, 2);
1866 1781 }
1867 1782 }
1868 1783 }
1869 1784
1870 1785
1871 1786 /*
1872 1787 * usba_dump_ep:
1873 1788 * Dump an endpoint node and its branches.
1874 1789 *
1875 1790 * Arguments:
1876 1791 * which_ep - index to display
1877 1792 * ep - endpoint node to dump
1878 1793 * dump_handle - write data through this log handle
1879 1794 * dump_level - level passed to usb_log
1880 1795 * dump_mask - mask passed to usb_log
1881 1796 * string - temporary area used for processing
1882 1797 *
1883 1798 */
1884 1799 static void
1885 1800 usba_dump_ep(uint_t which_ep, usb_ep_data_t *ep, usb_log_handle_t dump_handle,
1886 1801 uint_t dump_level, uint_t dump_mask, char *string)
1887 1802 {
1888 1803 int which_cv;
1889 1804 usb_ep_descr_t *ep_descr = &ep->ep_descr;
1890 1805
1891 1806 (void) usb_log(dump_handle, dump_level, dump_mask,
1892 1807 "\t endpoint[%d], epaddr=0x%x (0x%p)", which_ep,
1893 1808 ep_descr->bEndpointAddress, (void *)ep);
1894 1809 (void) usb_log(dump_handle, dump_level, dump_mask,
1895 1810 "\t len=%d type=%d attr=0x%x pktsize=%d interval=%d",
1896 1811 ep_descr->bLength, ep_descr->bDescriptorType,
1897 1812 ep_descr->bmAttributes, ep_descr->wMaxPacketSize,
1898 1813 ep_descr->bInterval);
1899 1814 if (ep->ep_n_cvs > 0) {
1900 1815 (void) usb_log(dump_handle, dump_level, dump_mask,
1901 1816 "\t usb_ep_data_t shows %d cv descr(s)", ep->ep_n_cvs);
1902 1817 }
1903 1818
1904 1819 for (which_cv = 0; which_cv < ep->ep_n_cvs; which_cv++) {
1905 1820 if (dump_level == USB_LOG_L0) {
1906 1821 (void) usb_log(dump_handle, dump_level,
1907 1822 dump_mask, " ");
1908 1823 }
1909 1824 (void) usb_log(dump_handle, dump_level, dump_mask,
1910 1825 "\t endpoint cv descriptor %d (0x%p), size=%d",
1911 1826 which_cv, (void *)&ep->ep_cvs[which_cv],
1912 1827 ep->ep_cvs[which_cv].cvs_buf_len);
1913 1828 usba_dump_cv(&ep->ep_cvs[which_cv],
1914 1829 dump_handle, dump_level, dump_mask, string, 3);
1915 1830 }
1916 1831 }
1917 1832
1918 1833
1919 1834 /*
1920 1835 * usba_dump_cv:
1921 1836 * Dump a raw class or vendor specific descriptor.
1922 1837 *
1923 1838 * Arguments:
1924 1839 * cv_node - pointer to the descriptor to dump
1925 1840 * dump_handle - write data through this log handle
1926 1841 * dump_level - level passed to usb_log
1927 1842 * dump_mask - mask passed to usb_log
1928 1843 * string - temporary area used for processing
1929 1844 * indent - number of tabs to indent output
1930 1845 *
1931 1846 */
1932 1847 static void
1933 1848 usba_dump_cv(usb_cvs_data_t *cv_node, usb_log_handle_t dump_handle,
1934 1849 uint_t dump_level, uint_t dump_mask, char *string, int indent)
1935 1850 {
1936 1851 if (cv_node) {
1937 1852 usba_dump_bin(cv_node->cvs_buf, cv_node->cvs_buf_len, indent,
1938 1853 dump_handle, dump_level, dump_mask, string,
1939 1854 USB_MAXSTRINGLEN);
1940 1855 }
1941 1856 }
1942 1857
1943 1858
1944 1859 /*
1945 1860 * usba_dump_bin:
1946 1861 * Generic byte dump function.
1947 1862 *
1948 1863 * Arguments:
1949 1864 * data - pointer to the data to dump
1950 1865 * max_bytes - amount of data to dump
1951 1866 * indent - number of indentation levels
1952 1867 * dump_handle - write data through this log handle
1953 1868 * dump_level - level passed to usb_log
1954 1869 * dump_mask - mask passed to usb_log
1955 1870 * buffer - temporary area used for processing
1956 1871 * bufferlen - size of the temporary string area
1957 1872 *
1958 1873 */
1959 1874 static void
1960 1875 usba_dump_bin(uint8_t *data, int max_bytes, int indent,
1961 1876 usb_log_handle_t dump_handle, uint_t dump_level, uint_t dump_mask,
1962 1877 char *buffer, int bufferlen)
1963 1878 {
1964 1879 int i;
1965 1880 int bufoffset = 0;
1966 1881 int nexthere;
1967 1882
1968 1883 if ((indent * SPACES_PER_INDENT) >
1969 1884 (bufferlen - (BINDUMP_BYTES_PER_LINE * 3))) {
1970 1885 (void) usb_log(dump_handle, dump_level, dump_mask,
1971 1886 "Offset to usb_dump_bin must be %d or less. "
1972 1887 "Setting to 0.\n",
1973 1888 (bufferlen - (BINDUMP_BYTES_PER_LINE * 3)));
1974 1889 indent = 0;
1975 1890 }
1976 1891
1977 1892 /* Assume a tab is 2 four-space units. */
1978 1893 for (i = 0; i < indent/2; i++) {
1979 1894 buffer[bufoffset] = '\t';
1980 1895 bufoffset++;
1981 1896 }
1982 1897
1983 1898 if (indent % 2) {
1984 1899 (void) strcpy(&buffer[bufoffset], INDENT_SPACE_STR);
1985 1900 bufoffset += SPACES_PER_INDENT;
1986 1901 }
1987 1902
1988 1903 i = 0; /* Num dumped bytes put on this line. */
1989 1904 nexthere = bufoffset;
1990 1905 while (i < max_bytes) {
1991 1906 (void) sprintf(&buffer[nexthere], "%2x ", *data++);
1992 1907 nexthere += 3;
1993 1908 i++;
1994 1909 if (!(i % BINDUMP_BYTES_PER_LINE)) {
1995 1910 buffer[nexthere] = '\0';
1996 1911 (void) usb_log(dump_handle, dump_level, dump_mask,
1997 1912 buffer);
1998 1913 nexthere = bufoffset;
1999 1914 }
2000 1915 }
2001 1916
2002 1917 if (nexthere > bufoffset) {
2003 1918 buffer[nexthere] = '\0';
2004 1919 (void) usb_log(dump_handle, dump_level, dump_mask, buffer);
2005 1920 }
2006 1921 }
↓ open down ↓ |
766 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX