1/* 2 * Copyright (c) 2012-2013 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <IOKit/IOKernelReportStructs.h> 30#include <IOKit/IOKernelReporters.h> 31 32 33//#define IORDEBUG_LEGEND 1 34 35#ifdef IORDEBUG_LEGEND 36#define IORLEGENDLOG(fmt, args...) \ 37do { \ 38IOLog("IOReportLegend | "); \ 39IOLog(fmt, ##args); \ 40IOLog("\n"); \ 41} while(0) 42#else 43#define IORLEGENDLOG(fmt, args...) 44#endif 45 46 47#define super OSObject 48OSDefineMetaClassAndStructors(IOReportLegend, OSObject); 49 50IOReportLegend* 51IOReportLegend::with(OSArray *legend) 52{ 53 IOReportLegend *iorLegend = new IOReportLegend; 54 55 if (iorLegend) { 56 57 if (legend != NULL) { 58 if (iorLegend->initWith(legend) != kIOReturnSuccess) { 59 delete iorLegend; 60 return NULL; 61 } 62 } 63 64 return iorLegend; 65 } 66 67 else return NULL; 68} 69 70/* must clean up everything if it fails */ 71IOReturn 72IOReportLegend::initWith(OSArray *legend) 73{ 74 if (legend) _reportLegend = OSArray::withArray(legend); 75 76 if (_reportLegend == NULL) 77 return kIOReturnError; 78 79 else return kIOReturnSuccess; 80} 81 82 83void 84IOReportLegend::free(void) 85{ 86 if (_reportLegend) _reportLegend->release(); 87 super::free(); 88} 89 90 91OSArray* 92IOReportLegend::getLegend(void) 93{ 94 return _reportLegend; 95} 96 97IOReturn 98IOReportLegend::addReporterLegend(IOService *reportingService, 99 IOReporter *reporter, 100 const char *groupName, 101 const char *subGroupName) 102{ 103 IOReturn res = kIOReturnError; 104 IOReportLegend *legend; 105 106 // No need to check groupName and subGroupName because optional params 107 if (!reportingService || !reporter) { 108 goto finish; 109 } 110 111 legend = IOReportLegend::with(OSDynamicCast(OSArray, reportingService->getProperty(kIOReportLegendKey))); 112 113 if (legend) 114 { 115 legend->addReporterLegend(reporter, groupName, subGroupName); 116 reportingService->setProperty(kIOReportLegendKey, legend->getLegend()); 117 reportingService->setProperty(kIOReportLegendPublicKey, true); 118 legend->free(); 119 res = kIOReturnSuccess; 120 } 121 122finish: 123 return res; 124} 125 126 127IOReturn 128IOReportLegend::addLegendEntry(IOReportLegendEntry *legendEntry, 129 const char *groupName, 130 const char *subGroupName) 131{ 132 kern_return_t res = kIOReturnError; 133 const OSSymbol *tmpGroupName = NULL; 134 const OSSymbol *tmpSubGroupName = NULL; 135 136 if (!legendEntry) goto finish; 137 138 if (groupName) { 139 tmpGroupName = OSSymbol::withCString(groupName); 140 } 141 142 if (subGroupName) { 143 tmpSubGroupName = OSSymbol::withCString(subGroupName); 144 } 145 146 // It is ok to call appendLegendWith() if tmpGroups are NULL 147 if (legendEntry) { 148 res = organizeLegend(legendEntry, tmpGroupName, tmpSubGroupName); 149 150 if (tmpGroupName) tmpGroupName->release(); 151 if (tmpSubGroupName) tmpSubGroupName->release(); 152 } 153 154finish: 155 return res; 156} 157 158 159IOReturn 160IOReportLegend::addReporterLegend(IOReporter *reporter, 161 const char *groupName, 162 const char *subGroupName) 163{ 164 IOReturn res = kIOReturnError; 165 IOReportLegendEntry *legendEntry = NULL; 166 167 if (reporter) { 168 169 legendEntry = reporter->createLegend(); 170 171 if (legendEntry) { 172 173 res = addLegendEntry(legendEntry, groupName, subGroupName); 174 legendEntry->release(); 175 } 176 } 177 178 return res; 179} 180 181 182IOReturn 183IOReportLegend::organizeLegend(IOReportLegendEntry *legendEntry, 184 const OSSymbol *groupName, 185 const OSSymbol *subGroupName) 186{ 187 IOReturn res = kIOReturnError; 188 189 if (!legendEntry) 190 return res = kIOReturnBadArgument; 191 192 if (!groupName && subGroupName) 193 return res = kIOReturnBadArgument; 194 195 IORLEGENDLOG("IOReportLegend::organizeLegend"); 196 // Legend is empty, enter first node 197 if (_reportLegend == NULL) { 198 IORLEGENDLOG("IOReportLegend::new legend creation"); 199 _reportLegend = OSArray::withCapacity(1); 200 201 if (!_reportLegend) 202 return kIOReturnNoMemory; 203 } 204 205 if (groupName) 206 legendEntry->setObject(kIOReportLegendGroupNameKey, groupName); 207 208 if (subGroupName) 209 legendEntry->setObject(kIOReportLegendSubGroupNameKey, subGroupName); 210 211 _reportLegend->setObject(legendEntry); 212 213 // callers can now safely release legendEntry (it is part of _reportLegend) 214 215 return res = kIOReturnSuccess; 216} 217 218