]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOReportLegend.cpp
xnu-6153.61.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOReportLegend.cpp
CommitLineData
fe8ab488
A
1/*
2 * Copyright (c) 2012-2013 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
fe8ab488
A
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.
0a7de745 14 *
fe8ab488
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
fe8ab488
A
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.
0a7de745 25 *
fe8ab488
A
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
3e170ce0
A
36 #define IORLEGENDLOG(fmt, args...) \
37 do { \
0a7de745
A
38 IOLog("IOReportLegend | "); \
39 IOLog(fmt, ##args); \
40 IOLog("\n"); \
3e170ce0 41 } while(0)
fe8ab488 42#else
3e170ce0 43 #define IORLEGENDLOG(fmt, args...)
fe8ab488
A
44#endif
45
46
47#define super OSObject
48OSDefineMetaClassAndStructors(IOReportLegend, OSObject);
49
50IOReportLegend*
51IOReportLegend::with(OSArray *legend)
52{
0a7de745
A
53 IOReportLegend *iorLegend = new IOReportLegend;
54
55 if (iorLegend) {
56 if (legend != NULL) {
57 if (iorLegend->initWith(legend) != kIOReturnSuccess) {
58 OSSafeReleaseNULL(iorLegend);
59 return NULL;
60 }
61 }
62
63 return iorLegend;
64 } else {
65 return NULL;
66 }
fe8ab488
A
67}
68
69/* must clean up everything if it fails */
70IOReturn
71IOReportLegend::initWith(OSArray *legend)
72{
0a7de745
A
73 if (legend) {
74 _reportLegend = OSArray::withArray(legend);
75 }
76
77 if (_reportLegend == NULL) {
78 return kIOReturnError;
79 } else {
80 return kIOReturnSuccess;
81 }
fe8ab488
A
82}
83
84
85void
86IOReportLegend::free(void)
87{
0a7de745
A
88 if (_reportLegend) {
89 _reportLegend->release();
90 }
91 super::free();
fe8ab488
A
92}
93
94
95OSArray*
96IOReportLegend::getLegend(void)
97{
0a7de745 98 return _reportLegend;
fe8ab488
A
99}
100
101IOReturn
102IOReportLegend::addReporterLegend(IOService *reportingService,
0a7de745
A
103 IOReporter *reporter,
104 const char *groupName,
105 const char *subGroupName)
fe8ab488 106{
0a7de745
A
107 IOReturn res = kIOReturnError;
108 IOReportLegend *legend = NULL;
109 OSObject *curLegend = NULL;
110
111 // No need to check groupName and subGroupName because optional params
112 if (!reportingService || !reporter) {
113 goto finish;
114 }
115
116 // It's fine if the legend doesn't exist (IOReportLegend::with(NULL)
117 // is how you make an empty legend). If it's not an array, then
118 // we're just going to replace it.
119 curLegend = reportingService->copyProperty(kIOReportLegendKey);
120 legend = IOReportLegend::with(OSDynamicCast(OSArray, curLegend));
121 if (!legend) {
122 goto finish;
123 }
124
125 // Add the reporter's entries and update the service property.
126 // The overwrite triggers a release of the old legend array.
127 legend->addReporterLegend(reporter, groupName, subGroupName);
128 reportingService->setProperty(kIOReportLegendKey, legend->getLegend());
129 reportingService->setProperty(kIOReportLegendPublicKey, true);
130
131 res = kIOReturnSuccess;
3e170ce0 132
0a7de745
A
133finish:
134 if (legend) {
135 legend->release();
136 }
137 if (curLegend) {
138 curLegend->release();
139 }
140
141 return res;
fe8ab488
A
142}
143
144
145IOReturn
146IOReportLegend::addLegendEntry(IOReportLegendEntry *legendEntry,
0a7de745
A
147 const char *groupName,
148 const char *subGroupName)
fe8ab488 149{
0a7de745
A
150 kern_return_t res = kIOReturnError;
151 const OSSymbol *tmpGroupName = NULL;
152 const OSSymbol *tmpSubGroupName = NULL;
153
154 if (!legendEntry) {
155 goto finish;
156 }
157
158 if (groupName) {
159 tmpGroupName = OSSymbol::withCString(groupName);
160 }
161
162 if (subGroupName) {
163 tmpSubGroupName = OSSymbol::withCString(subGroupName);
164 }
165
166 // It is ok to call appendLegendWith() if tmpGroups are NULL
167 if (legendEntry) {
168 res = organizeLegend(legendEntry, tmpGroupName, tmpSubGroupName);
169
170 if (tmpGroupName) {
171 tmpGroupName->release();
172 }
173 if (tmpSubGroupName) {
174 tmpSubGroupName->release();
175 }
176 }
fe8ab488
A
177
178finish:
0a7de745 179 return res;
fe8ab488
A
180}
181
182
183IOReturn
184IOReportLegend::addReporterLegend(IOReporter *reporter,
0a7de745
A
185 const char *groupName,
186 const char *subGroupName)
fe8ab488 187{
0a7de745
A
188 IOReturn res = kIOReturnError;
189 IOReportLegendEntry *legendEntry = NULL;
190
191 if (reporter) {
192 legendEntry = reporter->createLegend();
193
194 if (legendEntry) {
195 res = addLegendEntry(legendEntry, groupName, subGroupName);
196 legendEntry->release();
197 }
198 }
199
200 return res;
fe8ab488
A
201}
202
203
204IOReturn
205IOReportLegend::organizeLegend(IOReportLegendEntry *legendEntry,
0a7de745
A
206 const OSSymbol *groupName,
207 const OSSymbol *subGroupName)
fe8ab488 208{
0a7de745 209 IOReturn res = kIOReturnError;
fe8ab488 210
0a7de745
A
211 if (!legendEntry) {
212 return res = kIOReturnBadArgument;
213 }
214
215 if (!groupName && subGroupName) {
216 return res = kIOReturnBadArgument;
217 }
218
219 IORLEGENDLOG("IOReportLegend::organizeLegend");
220 // Legend is empty, enter first node
221 if (_reportLegend == NULL) {
222 IORLEGENDLOG("IOReportLegend::new legend creation");
223 _reportLegend = OSArray::withCapacity(1);
224
225 if (!_reportLegend) {
226 return kIOReturnNoMemory;
227 }
228 }
229
230 if (groupName) {
231 legendEntry->setObject(kIOReportLegendGroupNameKey, groupName);
232 }
233
234 if (subGroupName) {
235 legendEntry->setObject(kIOReportLegendSubGroupNameKey, subGroupName);
236 }
237
238 _reportLegend->setObject(legendEntry);
239
240 // callers can now safely release legendEntry (it is part of _reportLegend)
241
242 return res = kIOReturnSuccess;
243}