1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 #include <sys/kstat.h> 9 #include <sys/ddi.h> 10 #include <sys/sunddi.h> 11 #include <sys/sunldi.h> 12 #include <sys/agpgart.h> 13 #include <sys/agp/agpdefs.h> 14 #include <sys/agp/agpgart_impl.h> 15 16 /* 17 * The values of type agp_arc_type_t are used as indices into arc_name 18 * So if agp_arc_type_t's values are changed in the future, the content 19 * of arc_name must be changed accordingly. 20 */ 21 static const char *arc_name[] = { 22 "IGD_810", 23 "IGD_830", 24 "INTEL_AGP", 25 "AMD64_AGP", 26 "AMD64_NONAGP", 27 "UNKNOWN" 28 }; 29 30 static char *agpkstat_name[] = { 31 "&arc_type", 32 "master_dev_id", 33 "master_dev_version", 34 "master_dev_status", 35 "$prealloc_size", 36 "target_dev_id", 37 "target_dev_version", 38 "target_dev_status", 39 "$aper_base", 40 "$aper_size", 41 "&agp_enabled", 42 "agp_mode_set", 43 "$aper_used", 44 NULL 45 }; 46 47 static void 48 agp_set_char_kstat(kstat_named_t *knp, const char *s) 49 { 50 (void) strlcpy(knp->value.c, s, sizeof (knp->value.c)); 51 } 52 53 static int 54 agp_kstat_update(kstat_t *ksp, int flag) 55 { 56 agpgart_softstate_t *sc; 57 kstat_named_t *knp; 58 int tmp; 59 60 if (flag != KSTAT_READ) 61 return (EACCES); 62 63 sc = ksp->ks_private; 64 knp = ksp->ks_data; 65 66 agp_set_char_kstat(knp++, arc_name[sc->asoft_devreg.agprd_arctype]); 67 (knp++)->value.ui32 = sc->asoft_info.agpki_mdevid; 68 (knp++)->value.ui32 = (sc->asoft_info.agpki_mver.agpv_major<<16) | 69 sc->asoft_info.agpki_mver.agpv_minor; 70 (knp++)->value.ui32 = sc->asoft_info.agpki_mstatus; 71 (knp++)->value.ui64 = (sc->asoft_info.agpki_presize << 10) & UI32_MASK; 72 (knp++)->value.ui32 = sc->asoft_info.agpki_tdevid; 73 (knp++)->value.ui32 = (sc->asoft_info.agpki_tver.agpv_major<<16) | 74 sc->asoft_info.agpki_tver.agpv_minor; 75 (knp++)->value.ui32 = sc->asoft_info.agpki_tstatus; 76 (knp++)->value.ui64 = sc->asoft_info.agpki_aperbase; 77 (knp++)->value.ui64 = 78 (sc->asoft_info.agpki_apersize << 20) & UI32_MASK; 79 80 tmp = sc->asoft_agpen; 81 agp_set_char_kstat(knp++, (tmp > 0) ? "yes" : "no"); 82 83 (knp++)->value.ui32 = sc->asoft_mode; 84 (knp++)->value.ui64 = (sc->asoft_pgused << 12) & UI32_MASK; 85 86 return (0); 87 } 88 89 int 90 agp_init_kstats(agpgart_softstate_t *sc) 91 { 92 int instance; 93 kstat_t *ksp; 94 kstat_named_t *knp; 95 char *np; 96 int type; 97 char **aknp; 98 99 instance = ddi_get_instance(sc->asoft_dip); 100 aknp = agpkstat_name; 101 ksp = kstat_create(AGPGART_DEVNODE, instance, "agpinfo", "agp", 102 KSTAT_TYPE_NAMED, sizeof (agpkstat_name)/sizeof (char *) - 1, 103 KSTAT_FLAG_PERSISTENT); 104 if (ksp == NULL) 105 return (NULL); 106 107 ksp->ks_private = sc; 108 ksp->ks_update = agp_kstat_update; 109 for (knp = ksp->ks_data; (np = (*aknp)) != NULL; knp++, aknp++) { 110 switch (*np) { 111 case '$': 112 np += 1; 113 type = KSTAT_DATA_UINT64; 114 break; 115 case '&': 116 np += 1; 117 type = KSTAT_DATA_CHAR; 118 break; 119 default: 120 type = KSTAT_DATA_UINT32; 121 break; 122 123 } 124 kstat_named_init(knp, np, type); 125 } 126 kstat_install(ksp); 127 128 sc->asoft_ksp = ksp; 129 130 return (0); 131 } 132 133 void 134 agp_fini_kstats(agpgart_softstate_t *sc) 135 { 136 ASSERT(sc->asoft_ksp); 137 kstat_delete(sc->asoft_ksp); 138 } 139