81 * walk
82 * - local_dip is a pointer to a copy of the struct dev_info in local memory
83 * - cb_data is the addr of the callback arg the walker was invoked with
84 * (passed through transparently from walk invoker).
85 *
86 * Returns:
87 * - WALK_NEXT on success (match not found yet)
88 * - WALK_ERR on errors.
89 * - WALK_DONE is returned, cb_data.found is set to TRUE, and
90 * *cb_data.u2d_dip_addr is set to the matched dip addr if a dip corresponding
91 * to the desired usba_device_t* is found.
92 */
93 /*ARGSUSED*/
94 static int
95 find_dip(uintptr_t dip_addr, const void *local_dip, void *cb_arg)
96 {
97 uintptr_t cur_usb_dev;
98 usba_device2devinfo_cbdata_t *cb_data =
99 (usba_device2devinfo_cbdata_t *)cb_arg;
100
101 if ((cur_usb_dev = mdb_usba_get_usba_device(dip_addr)) == NULL) {
102 /*
103 * If there's no corresponding usba_device_t, this dip isn't
104 * a usb node. Might be an sd node. Ignore it.
105 */
106
107 return (WALK_NEXT);
108 }
109
110 if (cur_usb_dev == cb_data->u2d_target_usb_dev_p) {
111 *cb_data->u2d_dip_addr = dip_addr;
112 cb_data->u2d_found = TRUE;
113
114 return (WALK_DONE);
115 }
116
117 return (WALK_NEXT);
118 }
119
120
121 /*
165 return (-1);
166 }
167
168 if (cb_data.u2d_found == TRUE) {
169
170 return (1);
171 }
172
173 return (0);
174 }
175
176
177 /*
178 * Generic walker usba_list_entry_t walker.
179 * Works for any usba_list_entry_t list.
180 */
181 int
182 usba_list_walk_init(mdb_walk_state_t *wsp)
183 {
184 /* Must have a start addr. */
185 if (wsp->walk_addr == NULL) {
186 mdb_warn("not a global walk. Starting address required\n");
187
188 return (WALK_ERR);
189 }
190
191 return (WALK_NEXT);
192 }
193
194
195 /*
196 * Generic list walker step routine.
197 * NOTE: multiple walkers share this routine.
198 */
199 int
200 usba_list_walk_step(mdb_walk_state_t *wsp)
201 {
202 int status;
203 usba_list_entry_t list_entry;
204
205 if (mdb_vread(&list_entry, sizeof (usba_list_entry_t),
206 (uintptr_t)wsp->walk_addr) == -1) {
207 mdb_warn("failed to read usba_list_entry_t at %p",
208 wsp->walk_addr);
209
210 return (WALK_ERR);
211 }
212
213 status = wsp->walk_callback(wsp->walk_addr, &list_entry,
214 wsp->walk_cbdata);
215 wsp->walk_addr = (uintptr_t)list_entry.next;
216
217 /* Check if we're at the last element */
218 if (wsp->walk_addr == NULL) {
219
220 return (WALK_DONE);
221 }
222
223 return (status);
224 }
225
226
227 /*
228 * usb_pipe_handle walker
229 * Given a pointer to a usba_device_t, walk the array of endpoint
230 * pipe_handle lists.
231 * For each list, traverse the list, invoking the callback on each element.
232 *
233 * Note this function takes the address of a usba_device struct (which is
234 * easily obtainable), but actually traverses a sub-portion of the struct
235 * (which address is not so easily obtainable).
236 */
237 int
238 usb_pipe_handle_walk_init(mdb_walk_state_t *wsp)
239 {
240 if (wsp->walk_addr == NULL) {
241 mdb_warn("not a global walk; usba_device_t required\n");
242
243 return (WALK_ERR);
244 }
245
246 wsp->walk_data = mdb_alloc((sizeof (usba_ph_impl_t)) * USBA_N_ENDPOINTS,
247 UM_SLEEP | UM_GC);
248
249 /*
250 * Read the usb_ph_list array into local memory.
251 * Set start address to first element/endpoint in usb_pipehandle_list
252 */
253 if (mdb_vread(wsp->walk_data,
254 (sizeof (usba_ph_impl_t)) * USBA_N_ENDPOINTS,
255 (uintptr_t)((size_t)(wsp->walk_addr) +
256 offsetof(usba_device_t, usb_ph_list))) == -1) {
257 mdb_warn("failed to read usb_pipehandle_list at %p",
258 wsp->walk_addr);
259
260 return (WALK_ERR);
386 ept_descr.bEndpointAddress & USB_EP_NUM_MASK, type, dir, state,
387 addr, addr + offsetof(usba_pipe_handle_data_t, p_policy),
388 addr + offsetof(usba_pipe_handle_data_t, p_ep));
389
390 return (DCMD_OK);
391 }
392
393
394 /*
395 * usba_device walker:
396 *
397 * walks the chain of usba_device structs headed by usba_device_list in usba.c
398 * NOTE: It uses the generic list walk step routine usba_list_walk_step.
399 * No walk_fini routine is needed.
400 */
401 int
402 usba_device_walk_init(mdb_walk_state_t *wsp)
403 {
404 usba_list_entry_t list_entry;
405
406 if (wsp->walk_addr != NULL) {
407 mdb_warn(
408 "global walk only. Must be invoked without an address\n");
409
410 return (WALK_ERR);
411 }
412
413 if (mdb_readvar(&list_entry, "usba_device_list") == -1) {
414 mdb_warn("failed to read usba_device_list");
415
416 return (WALK_ERR);
417 }
418
419 /* List head is not part of usba_device_t, get first usba_device_t */
420 wsp->walk_addr = (uintptr_t)list_entry.next;
421
422 return (WALK_NEXT);
423 }
424
425
426 /*
427 * usba_device dcmd
428 * Given the address of a usba_device struct, dump summary info
429 * -v: Print more (verbose) info
430 * -p: Walk/dump all open pipes for this usba_device
431 */
432 /*ARGSUSED*/
433 int
434 usba_device(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
435 {
436 int status;
437 char pathname[MAXNAMELEN];
438 char dname[MODMAXNAMELEN + 1] = "<unatt>"; /* Driver name */
439 char drv_statep[MODMAXNAMELEN+ 10];
440 uint_t usb_flag = NULL;
441 boolean_t no_driver_attached = FALSE;
442 uintptr_t dip_addr;
443 struct dev_info devinfo;
444
445 if (!(flags & DCMD_ADDRSPEC)) {
446 /* Global walk */
447 if (mdb_walk_dcmd("usba_device", "usba_device", argc,
448 argv) == -1) {
449 mdb_warn("failed to walk usba_device");
450
451 return (DCMD_ERR);
452 }
453
454 return (DCMD_OK);
455 }
456
457 if (mdb_getopts(argc, argv,
458 'p', MDB_OPT_SETBITS, USB_DUMP_ACTIVE_PIPES, &usb_flag,
459 'v', MDB_OPT_SETBITS, USB_DUMP_VERBOSE, &usb_flag, NULL) != argc) {
460
492 /* Figure out what driver (name) is attached to this node. */
493 (void) mdb_devinfo2driver(dip_addr, (char *)dname, sizeof (dname));
494
495 if (mdb_vread(&devinfo, sizeof (struct dev_info),
496 dip_addr) == -1) {
497 mdb_warn("failed to read devinfo");
498
499 return (DCMD_ERR);
500 }
501
502 if (!(DDI_CF2(&devinfo))) {
503 no_driver_attached = TRUE;
504 }
505
506 (void) mdb_ddi_pathname(dip_addr, pathname, sizeof (pathname));
507 mdb_printf("%-15s %2d %-?p %s\n", dname, devinfo.devi_instance,
508 dip_addr, pathname);
509
510 if (usb_flag & USB_DUMP_VERBOSE) {
511 int i;
512 uintptr_t statep = NULL;
513 char *string_descr;
514 char **config_cloud, **conf_str_descr;
515 usb_dev_descr_t usb_dev_descr;
516 usba_device_t usba_device_struct;
517
518 if (mdb_vread(&usba_device_struct,
519 sizeof (usba_device_t), addr) == -1) {
520 mdb_warn("failed to read usba_device struct");
521
522 return (DCMD_ERR);
523 }
524
525 mdb_printf(" usba_device: %-16p\n\n", (usba_device_t *)addr);
526
527 if (mdb_vread(&usb_dev_descr, sizeof (usb_dev_descr),
528 (uintptr_t)usba_device_struct.usb_dev_descr) == -1) {
529 mdb_warn("failed to read usb_dev_descr_t struct");
530
531 return (DCMD_ERR);
532 }
700
701
702 if (mdb_readvar(&debug_buf_size, "usba_debug_buf_size") == -1) {
703 mdb_warn("failed to read usba_debug_buf_size");
704
705 return (DCMD_ERR);
706 }
707
708 debug_buf_size += USB_DEBUG_SIZE_EXTRA_ALLOC;
709 local_debug_buf = (char *)mdb_alloc(debug_buf_size, UM_SLEEP | UM_GC);
710
711 if ((mdb_vread(local_debug_buf, debug_buf_size,
712 (uintptr_t)debug_buf_addr)) == -1) {
713 mdb_warn("failed to read usba_debug_buf at %p",
714 local_debug_buf);
715
716 return (DCMD_ERR);
717 }
718 local_debug_buf[debug_buf_size - 1] = '\0';
719
720 if (strlen(local_debug_buf) == NULL) {
721
722 return (DCMD_OK);
723 }
724
725 if ((term_p = strstr(local_debug_buf, ">>>>")) == NULL) {
726 mdb_warn("failed to find terminator \">>>>\"\n");
727
728 return (DCMD_ERR);
729 }
730
731 /*
732 * Print the chunk of buffer from the terminator to the end.
733 * This will print a null string if no wrap has occurred yet.
734 */
735 mdb_printf("%s", term_p+5); /* after >>>>\0 to end of buf */
736 mdb_printf("%s\n", local_debug_buf); /* beg of buf to >>>>\0 */
737
738 return (DCMD_OK);
739 }
740
|
81 * walk
82 * - local_dip is a pointer to a copy of the struct dev_info in local memory
83 * - cb_data is the addr of the callback arg the walker was invoked with
84 * (passed through transparently from walk invoker).
85 *
86 * Returns:
87 * - WALK_NEXT on success (match not found yet)
88 * - WALK_ERR on errors.
89 * - WALK_DONE is returned, cb_data.found is set to TRUE, and
90 * *cb_data.u2d_dip_addr is set to the matched dip addr if a dip corresponding
91 * to the desired usba_device_t* is found.
92 */
93 /*ARGSUSED*/
94 static int
95 find_dip(uintptr_t dip_addr, const void *local_dip, void *cb_arg)
96 {
97 uintptr_t cur_usb_dev;
98 usba_device2devinfo_cbdata_t *cb_data =
99 (usba_device2devinfo_cbdata_t *)cb_arg;
100
101 if ((cur_usb_dev = mdb_usba_get_usba_device(dip_addr)) == (uintptr_t)NULL) {
102 /*
103 * If there's no corresponding usba_device_t, this dip isn't
104 * a usb node. Might be an sd node. Ignore it.
105 */
106
107 return (WALK_NEXT);
108 }
109
110 if (cur_usb_dev == cb_data->u2d_target_usb_dev_p) {
111 *cb_data->u2d_dip_addr = dip_addr;
112 cb_data->u2d_found = TRUE;
113
114 return (WALK_DONE);
115 }
116
117 return (WALK_NEXT);
118 }
119
120
121 /*
165 return (-1);
166 }
167
168 if (cb_data.u2d_found == TRUE) {
169
170 return (1);
171 }
172
173 return (0);
174 }
175
176
177 /*
178 * Generic walker usba_list_entry_t walker.
179 * Works for any usba_list_entry_t list.
180 */
181 int
182 usba_list_walk_init(mdb_walk_state_t *wsp)
183 {
184 /* Must have a start addr. */
185 if (wsp->walk_addr == (uintptr_t)NULL) {
186 mdb_warn("not a global walk. Starting address required\n");
187
188 return (WALK_ERR);
189 }
190
191 return (WALK_NEXT);
192 }
193
194
195 /*
196 * Generic list walker step routine.
197 * NOTE: multiple walkers share this routine.
198 */
199 int
200 usba_list_walk_step(mdb_walk_state_t *wsp)
201 {
202 int status;
203 usba_list_entry_t list_entry;
204
205 if (mdb_vread(&list_entry, sizeof (usba_list_entry_t),
206 (uintptr_t)wsp->walk_addr) == -1) {
207 mdb_warn("failed to read usba_list_entry_t at %p",
208 wsp->walk_addr);
209
210 return (WALK_ERR);
211 }
212
213 status = wsp->walk_callback(wsp->walk_addr, &list_entry,
214 wsp->walk_cbdata);
215 wsp->walk_addr = (uintptr_t)list_entry.next;
216
217 /* Check if we're at the last element */
218 if (wsp->walk_addr == (uintptr_t)NULL) {
219
220 return (WALK_DONE);
221 }
222
223 return (status);
224 }
225
226
227 /*
228 * usb_pipe_handle walker
229 * Given a pointer to a usba_device_t, walk the array of endpoint
230 * pipe_handle lists.
231 * For each list, traverse the list, invoking the callback on each element.
232 *
233 * Note this function takes the address of a usba_device struct (which is
234 * easily obtainable), but actually traverses a sub-portion of the struct
235 * (which address is not so easily obtainable).
236 */
237 int
238 usb_pipe_handle_walk_init(mdb_walk_state_t *wsp)
239 {
240 if (wsp->walk_addr == (uintptr_t)NULL) {
241 mdb_warn("not a global walk; usba_device_t required\n");
242
243 return (WALK_ERR);
244 }
245
246 wsp->walk_data = mdb_alloc((sizeof (usba_ph_impl_t)) * USBA_N_ENDPOINTS,
247 UM_SLEEP | UM_GC);
248
249 /*
250 * Read the usb_ph_list array into local memory.
251 * Set start address to first element/endpoint in usb_pipehandle_list
252 */
253 if (mdb_vread(wsp->walk_data,
254 (sizeof (usba_ph_impl_t)) * USBA_N_ENDPOINTS,
255 (uintptr_t)((size_t)(wsp->walk_addr) +
256 offsetof(usba_device_t, usb_ph_list))) == -1) {
257 mdb_warn("failed to read usb_pipehandle_list at %p",
258 wsp->walk_addr);
259
260 return (WALK_ERR);
386 ept_descr.bEndpointAddress & USB_EP_NUM_MASK, type, dir, state,
387 addr, addr + offsetof(usba_pipe_handle_data_t, p_policy),
388 addr + offsetof(usba_pipe_handle_data_t, p_ep));
389
390 return (DCMD_OK);
391 }
392
393
394 /*
395 * usba_device walker:
396 *
397 * walks the chain of usba_device structs headed by usba_device_list in usba.c
398 * NOTE: It uses the generic list walk step routine usba_list_walk_step.
399 * No walk_fini routine is needed.
400 */
401 int
402 usba_device_walk_init(mdb_walk_state_t *wsp)
403 {
404 usba_list_entry_t list_entry;
405
406 if (wsp->walk_addr != (uintptr_t)NULL) {
407 mdb_warn(
408 "global walk only. Must be invoked without an address\n");
409
410 return (WALK_ERR);
411 }
412
413 if (mdb_readvar(&list_entry, "usba_device_list") == -1) {
414 mdb_warn("failed to read usba_device_list");
415
416 return (WALK_ERR);
417 }
418
419 /* List head is not part of usba_device_t, get first usba_device_t */
420 wsp->walk_addr = (uintptr_t)list_entry.next;
421
422 return (WALK_NEXT);
423 }
424
425
426 /*
427 * usba_device dcmd
428 * Given the address of a usba_device struct, dump summary info
429 * -v: Print more (verbose) info
430 * -p: Walk/dump all open pipes for this usba_device
431 */
432 /*ARGSUSED*/
433 int
434 usba_device(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
435 {
436 int status;
437 char pathname[MAXNAMELEN];
438 char dname[MODMAXNAMELEN + 1] = "<unatt>"; /* Driver name */
439 char drv_statep[MODMAXNAMELEN+ 10];
440 uint_t usb_flag = 0;
441 boolean_t no_driver_attached = FALSE;
442 uintptr_t dip_addr;
443 struct dev_info devinfo;
444
445 if (!(flags & DCMD_ADDRSPEC)) {
446 /* Global walk */
447 if (mdb_walk_dcmd("usba_device", "usba_device", argc,
448 argv) == -1) {
449 mdb_warn("failed to walk usba_device");
450
451 return (DCMD_ERR);
452 }
453
454 return (DCMD_OK);
455 }
456
457 if (mdb_getopts(argc, argv,
458 'p', MDB_OPT_SETBITS, USB_DUMP_ACTIVE_PIPES, &usb_flag,
459 'v', MDB_OPT_SETBITS, USB_DUMP_VERBOSE, &usb_flag, NULL) != argc) {
460
492 /* Figure out what driver (name) is attached to this node. */
493 (void) mdb_devinfo2driver(dip_addr, (char *)dname, sizeof (dname));
494
495 if (mdb_vread(&devinfo, sizeof (struct dev_info),
496 dip_addr) == -1) {
497 mdb_warn("failed to read devinfo");
498
499 return (DCMD_ERR);
500 }
501
502 if (!(DDI_CF2(&devinfo))) {
503 no_driver_attached = TRUE;
504 }
505
506 (void) mdb_ddi_pathname(dip_addr, pathname, sizeof (pathname));
507 mdb_printf("%-15s %2d %-?p %s\n", dname, devinfo.devi_instance,
508 dip_addr, pathname);
509
510 if (usb_flag & USB_DUMP_VERBOSE) {
511 int i;
512 uintptr_t statep = (uintptr_t)NULL;
513 char *string_descr;
514 char **config_cloud, **conf_str_descr;
515 usb_dev_descr_t usb_dev_descr;
516 usba_device_t usba_device_struct;
517
518 if (mdb_vread(&usba_device_struct,
519 sizeof (usba_device_t), addr) == -1) {
520 mdb_warn("failed to read usba_device struct");
521
522 return (DCMD_ERR);
523 }
524
525 mdb_printf(" usba_device: %-16p\n\n", (usba_device_t *)addr);
526
527 if (mdb_vread(&usb_dev_descr, sizeof (usb_dev_descr),
528 (uintptr_t)usba_device_struct.usb_dev_descr) == -1) {
529 mdb_warn("failed to read usb_dev_descr_t struct");
530
531 return (DCMD_ERR);
532 }
700
701
702 if (mdb_readvar(&debug_buf_size, "usba_debug_buf_size") == -1) {
703 mdb_warn("failed to read usba_debug_buf_size");
704
705 return (DCMD_ERR);
706 }
707
708 debug_buf_size += USB_DEBUG_SIZE_EXTRA_ALLOC;
709 local_debug_buf = (char *)mdb_alloc(debug_buf_size, UM_SLEEP | UM_GC);
710
711 if ((mdb_vread(local_debug_buf, debug_buf_size,
712 (uintptr_t)debug_buf_addr)) == -1) {
713 mdb_warn("failed to read usba_debug_buf at %p",
714 local_debug_buf);
715
716 return (DCMD_ERR);
717 }
718 local_debug_buf[debug_buf_size - 1] = '\0';
719
720 if (strlen(local_debug_buf) == 0) {
721
722 return (DCMD_OK);
723 }
724
725 if ((term_p = strstr(local_debug_buf, ">>>>")) == NULL) {
726 mdb_warn("failed to find terminator \">>>>\"\n");
727
728 return (DCMD_ERR);
729 }
730
731 /*
732 * Print the chunk of buffer from the terminator to the end.
733 * This will print a null string if no wrap has occurred yet.
734 */
735 mdb_printf("%s", term_p+5); /* after >>>>\0 to end of buf */
736 mdb_printf("%s\n", local_debug_buf); /* beg of buf to >>>>\0 */
737
738 return (DCMD_OK);
739 }
740
|