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
34OSDefineMetaClassAndStructors(IOSimpleReporter, IOReporter);
35
36/* static */
37IOSimpleReporter*
38IOSimpleReporter::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
57finish:
58    if (!rval) {
59        if (reporter)       delete reporter;
60    }
61
62    return rval;
63}
64
65bool
66IOSimpleReporter::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
82IOReturn
83IOSimpleReporter::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
106finish:
107    unlockReporter();
108    return res;
109}
110
111
112IOReturn
113IOSimpleReporter::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
136finish:
137    unlockReporter();
138    return res;
139}
140
141int64_t
142IOSimpleReporter::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