xref: /illumos-gate/usr/src/cmd/mdb/common/modules/usba/usba.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2000-2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Routines extracted from usr/src/uts/common/io/usb/usba/usba.c.
31  */
32 
33 #include <sys/mdb_modapi.h>
34 #include <sys/usb/usba.h>
35 #include <sys/usb/usba/usba_types.h>
36 #include <sys/usb/usba/usba_impl.h>
37 #include <sys/usb/usba/hcdi_impl.h>
38 #include <sys/file.h>
39 #include <sys/sunndi.h>
40 
41 
42 /*
43  * check whether this dip is the root hub.
44  * dip_addr is address of the devinfo struct in the core image (not local space)
45  */
46 static int
47 mdb_usba_is_root_hub(struct dev_info *dip)
48 {
49 	uintptr_t	p = (uintptr_t)dip->devi_hw_prop_ptr;
50 
51 	while (p != NULL) {
52 		ddi_prop_t prop;
53 		char prop_name[128];
54 
55 		if (mdb_vread(&prop, sizeof (prop), p) == -1) {
56 			mdb_warn("failed to read property");
57 			break;
58 		}
59 		if (mdb_readstr(prop_name, sizeof (prop_name),
60 		    (uintptr_t)prop.prop_name) == -1) {
61 			mdb_warn("failed to read property name");
62 		}
63 
64 		if (strcmp(prop_name, "root-hub") == 0) {
65 
66 			return (1);
67 		}
68 
69 		p = (uintptr_t)prop.prop_next;
70 	}
71 
72 	return (0);
73 }
74 
75 
76 /*
77  * retrieve hcdi structure from the dip
78  *
79  * dip_addr is address of the devinfo struct in the core image (not local space)
80  */
81 uintptr_t
82 mdb_usba_hcdi_get_hcdi(struct dev_info *dip)
83 {
84 	return ((uintptr_t)dip->devi_driver_data);
85 }
86 
87 
88 /*
89  * get usba_device pointer in the devi
90  *
91  * dip_addr is address of the devinfo struct in the core image (not local space)
92  */
93 uintptr_t
94 mdb_usba_get_usba_device(uintptr_t dip_addr)
95 {
96 	struct dev_info	devinfo;
97 
98 	if (mdb_vread(&devinfo, sizeof (struct dev_info), dip_addr) == -1) {
99 		mdb_warn("failed to read dev_info at %p", dip_addr);
100 
101 		return (NULL);
102 	}
103 
104 	/*
105 	 * we cannot use parent_data in the usb node because its
106 	 * bus parent (eg. PCI nexus driver) uses this data
107 	 *
108 	 * we cannot use driver data in the other usb nodes since
109 	 * usb drivers may need to use this
110 	 */
111 	if (mdb_usba_is_root_hub(&devinfo)) {
112 		usba_hcdi_t hcdi_struct;
113 		uintptr_t hcdi_addr = mdb_usba_hcdi_get_hcdi(&devinfo);
114 
115 		if (!hcdi_addr) {
116 
117 			return (NULL);
118 		}
119 
120 		/* Read hcdi struct into local address space. */
121 		if (mdb_vread(&hcdi_struct, sizeof (usba_hcdi_t),
122 		    hcdi_addr) == -1) {
123 			mdb_warn("failed to read hcdi struct");
124 
125 			return (NULL);
126 		}
127 
128 		return ((uintptr_t)hcdi_struct.hcdi_usba_device);
129 
130 	} else {
131 		struct dev_info	devinfo;
132 
133 		if (mdb_vread(&devinfo, sizeof (struct dev_info),
134 		    dip_addr) == -1) {
135 			mdb_warn("failed to read dev_info at %p", dip_addr);
136 
137 			return (NULL);
138 		}
139 
140 		/* casts needed to keep lint happy */
141 		return ((uintptr_t)devinfo.devi_parent_data);
142 	}
143 }
144