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 #include "IOReporterDefs.h"
32 
33 #define super IOReporter
34 OSDefineMetaClassAndStructors(IOSimpleReporter, IOReporter);
35 
36 /* static */
37 IOSimpleReporter*
38 IOSimpleReporter::with(IOService *reportingService,
39                        IOReportCategories categories,
40                        IOReportUnits unit)
41 {
42     IOSimpleReporter *reporter, *rval = NULL;
43 
44     // kprintf("%s\n", __func__);      // can't IORLOG() from static
45 
46     reporter = new IOSimpleReporter;
47     if (!reporter)      goto finish;
48 
49 
50     if (!reporter->initWith(reportingService, categories, unit)) {
51         goto finish;
52     }
53 
54     // success
55     rval = reporter;
56 
57 finish:
58     if (!rval) {
59         if (reporter)       delete reporter;
60     }
61 
62     return rval;
63 }
64 
65 bool
66 IOSimpleReporter::initWith(IOService *reportingService,
67                            IOReportCategories categories,
68                            IOReportUnits unit)
69 {
70     // fully specify the channel type for the superclass
71     IOReportChannelType channelType = {
72         .categories = categories,
73         .report_format = kIOReportFormatSimple,
74         .nelements = 1,
75         .element_idx = 0
76     };
77 
78     return super::init(reportingService, channelType, unit);
79 }
80 
81 
82 IOReturn
83 IOSimpleReporter::setValue(uint64_t channel_id,
84                            int64_t value)
85 {
86     IOReturn res = kIOReturnError;
87     IOSimpleReportValues simple_values;
88     int element_index = 0;
89 
90     lockReporter();
91 
92     if (getFirstElementIndex(channel_id, &element_index) != kIOReturnSuccess) {
93         res = kIOReturnBadArgument;
94         goto finish;
95     }
96 
97 
98     if (copyElementValues(element_index, (IOReportElementValues *)&simple_values) != kIOReturnSuccess) {
99         res = kIOReturnBadArgument;
100         goto finish;
101     }
102 
103     simple_values.simple_value = value;
104     res = setElementValues(element_index, (IOReportElementValues *)&simple_values);
105 
106 finish:
107     unlockReporter();
108     return res;
109 }
110 
111 
112 IOReturn
113 IOSimpleReporter::incrementValue(uint64_t channel_id,
114                                  int64_t increment)
115 {
116     IOReturn res = kIOReturnError;
117     IOSimpleReportValues simple_values;
118     int element_index = 0;
119 
120     lockReporter();
121 
122     if (getFirstElementIndex(channel_id, &element_index) != kIOReturnSuccess) {
123         res = kIOReturnBadArgument;
124         goto finish;
125     }
126 
127     if (copyElementValues(element_index, (IOReportElementValues *)&simple_values) != kIOReturnSuccess){
128         res = kIOReturnBadArgument;
129         goto finish;
130     }
131 
132     simple_values.simple_value += increment;
133 
134     res = setElementValues(element_index, (IOReportElementValues *)&simple_values);
135 
136 finish:
137     unlockReporter();
138     return res;
139 }
140 
141 int64_t
142 IOSimpleReporter::getValue(uint64_t channel_id)
143 {
144     IOSimpleReportValues *values = NULL;
145     int64_t simple_value = (int64_t)kIOReportInvalidValue;
146     int index = 0;
147 
148     lockReporter();
149 
150     if (getFirstElementIndex(channel_id, &index) == kIOReturnSuccess) {
151 
152         values = (IOSimpleReportValues *)getElementValues(index);
153 
154         if (values != NULL)
155             simple_value = values->simple_value;
156     }
157 
158     unlockReporter();
159     return simple_value;
160 }
161 
162