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