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 /* 28 * Routines extracted from usr/src/uts/common/io/usb/usba/usba.c. 29 */ 30 31 #include <sys/mdb_modapi.h> 32 #include <sys/usb/usba.h> 33 #include <sys/usb/usba/usba_types.h> 34 #include <sys/usb/usba/usba_impl.h> 35 #include <sys/usb/usba/hcdi_impl.h> 36 #include <sys/file.h> 37 #include <sys/sunndi.h> 38 39 40 /* 41 * check whether this dip is the root hub. 42 * dip_addr is address of the devinfo struct in the core image (not local space) 43 */ 44 static int 45 mdb_usba_is_root_hub(struct dev_info *dip) 46 { 47 uintptr_t p = (uintptr_t)dip->devi_hw_prop_ptr; 48 49 while (p != 0) { 50 ddi_prop_t prop; 51 char prop_name[128]; 52 53 if (mdb_vread(&prop, sizeof (prop), p) == -1) { 54 mdb_warn("failed to read property"); 55 break; 56 } 57 if (mdb_readstr(prop_name, sizeof (prop_name), 58 (uintptr_t)prop.prop_name) == -1) { 59 mdb_warn("failed to read property name"); 60 } 61 62 if (strcmp(prop_name, "root-hub") == 0) { 63 64 return (1); 65 } 66 67 p = (uintptr_t)prop.prop_next; 68 } 69 70 return (0); 71 } 72 73 74 /* 75 * retrieve hcdi structure from the dip 76 * 77 * dip_addr is address of the devinfo struct in the core image (not local space) 78 */ 79 uintptr_t 80 mdb_usba_hcdi_get_hcdi(struct dev_info *dip) 81 { 82 return ((uintptr_t)dip->devi_driver_data); 83 } 84 85 86 /* 87 * get usba_device pointer in the devi 88 * 89 * dip_addr is address of the devinfo struct in the core image (not local space) 90 */ 91 uintptr_t 92 mdb_usba_get_usba_device(uintptr_t dip_addr) 93 { 94 struct dev_info devinfo; 95 96 if (mdb_vread(&devinfo, sizeof (struct dev_info), dip_addr) == -1) { 97 mdb_warn("failed to read dev_info at %p", dip_addr); 98 99 return (0); 100 } 101 102 /* 103 * we cannot use parent_data in the usb node because its 104 * bus parent (eg. PCI nexus driver) uses this data 105 * 106 * we cannot use driver data in the other usb nodes since 107 * usb drivers may need to use this 108 */ 109 if (mdb_usba_is_root_hub(&devinfo)) { 110 usba_hcdi_t hcdi_struct; 111 uintptr_t hcdi_addr = mdb_usba_hcdi_get_hcdi(&devinfo); 112 113 if (!hcdi_addr) { 114 115 return (0); 116 } 117 118 /* Read hcdi struct into local address space. */ 119 if (mdb_vread(&hcdi_struct, sizeof (usba_hcdi_t), 120 hcdi_addr) == -1) { 121 mdb_warn("failed to read hcdi struct"); 122 123 return (0); 124 } 125 126 return ((uintptr_t)hcdi_struct.hcdi_usba_device); 127 128 } else { 129 struct dev_info devinfo; 130 131 if (mdb_vread(&devinfo, sizeof (struct dev_info), 132 dip_addr) == -1) { 133 mdb_warn("failed to read dev_info at %p", dip_addr); 134 135 return (0); 136 } 137 138 /* casts needed to keep lint happy */ 139 return ((uintptr_t)devinfo.devi_parent_data); 140 } 141 } 142