]>
git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/IOReportMacros.h
2 * Copyright (c) 2012-2014 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _IOREPORT_MACROS_H_
30 #define _IOREPORT_MACROS_H_
32 #include "IOReportTypes.h"
39 #ifndef IOREPORT_ABORT
40 #define IOREPORT_ABORT panic
46 These macros allow non-I/O Kit software to generate IOReporting
47 reports. Clients must prevent concurrent access to any given
48 report buffer from multiple threads.
50 While these macros allow non-I/O Kit software to participate
51 in IOReporting, an IOService instance must lend its driver ID,
52 respond to the appropriate IOService overrides, and shuttle
53 data back and forth. In some cases, it may be useful to have
54 the I/O Kit driver initialize the report buffer with the
59 /* ----- Reporting Single Integers (SimpleReport) ----- */
62 * The buffer size required for a SimpleReport.
65 #define SIMPLEREPORT_BUFSIZE (sizeof(IOReportElement))
69 * Initialize a buffer to hold a SimpleReport.
71 * void* buffer - ptr to SIMPLEREPORT_BUFSIZE bytes
72 * size_t bufSize - sanity check of buffer's size
73 * uint64_t providerID - registry Entry ID of the reporting service
74 * uint64_t channelID - the report's channel ID
75 * IOReportCategories categories - categories of this channel
77 * If the buffer is not of sufficient size, the macro calls IOREPORT_ABORT().
78 * If that returns, the buffer is left full of '&'.
81 #define SIMPLEREPORT_INIT(buf, bufSize, providerID, channelID, cats) \
83 memset((buf), '&', (bufSize)); \
84 IOReportElement *__elem = (IOReportElement *)(buf); \
85 IOSimpleReportValues *__vals; \
86 if ((bufSize) >= SIMPLEREPORT_BUFSIZE) { \
87 __elem->provider_id = (providerID); \
88 __elem->channel_id = (channelID); \
89 __elem->channel_type.report_format = kIOReportFormatSimple; \
90 __elem->channel_type.reserved = 0; \
91 __elem->channel_type.categories = (cats); \
92 __elem->channel_type.nelements = 1; \
93 __elem->channel_type.element_idx = 0; \
94 __elem->timestamp = 0; \
95 __vals = (IOSimpleReportValues*)&__elem->values; \
96 __vals->simple_value = kIOReportInvalidIntValue; \
99 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
105 * Set a SimpleReport to a new value.
107 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
108 * int64_t new_value - new value for the report
111 #define SIMPLEREPORT_SETVALUE(simp_buf, new_value) \
113 IOReportElement *__elem = (IOReportElement *)(simp_buf); \
114 IOSimpleReportValues *__vals; \
115 __vals = (IOSimpleReportValues*)&__elem->values; \
116 __vals->simple_value = (new_value); \
121 * Increment the value of a SimpleReport.
123 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
124 * int64_t increment - amount by which to increment the value
126 #define SIMPLEREPORT_INCREMENTVALUE(simp_buf, new_value) \
128 IOReportElement *__elem = (IOReportElement *)(simp_buf); \
129 IOSimpleReportValues *__vals; \
130 __vals = (IOSimpleReportValues*)&__elem->values; \
131 __vals->simple_value += (new_value); \
136 * Prepare a SimpleReport for
137 * IOService::updateReport(kIOReportCopyChannelData...)
139 * void* simp_buf - Ptr to memory updated by SIMPLEREPORT_SETVALUE()
140 * void* ptr2cpy - On return, 'ptr2cpy' points to the memory that needs to be
141 * copied for kIOReportCopyChannelData.
142 * size_t size2cpy - On return, 'size2cpy' is set to the size of the report
143 * data that needs to be copied for kIOReportCopyChannelData.
146 #define SIMPLEREPORT_UPDATEPREP(simp_buf, ptr2cpy, size2cpy) \
148 (ptr2cpy) = (simp_buf); \
149 (size2cpy) = sizeof(IOReportElement); \
154 * Update the result field received as a parameter for
155 * kIOReportGetDimensions & kIOReportCopyChannelData actions.
157 * IOReportConfigureAction action - configure/updateReport() 'action' param
158 * void* result - configure/updateReport() 'result' param
161 #define SIMPLEREPORT_UPDATERES(action, result) \
163 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
164 int *__nElements = (int *)(result); \
171 * Get the 64-bit channel ID of a SimpleReport.
173 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
176 #define SIMPLEREPORT_GETCHID(simp_buf) \
177 (((IOReportElement *)(simp_buf))->channel_id)
180 * Get the IOReportChannelType of a SimpleReport.
182 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
185 #define SIMPLEREPORT_GETCHTYPE(simp_buf) \
186 (*(uint64_t*)&(((IOReportElement *)(simp_buf))->channel_type))
190 * Get the integer value of a SimpleReport.
192 * void* simp_buf - memory initialized by SIMPLEREPORT_INIT()
195 #define SIMPLEREPORT_GETVALUE(simp_buf) \
196 (((IOSimpleReportValues*)&(((IOReportElement*)(simp_buf))->values)) \
200 /* ----- State Machine Reporting (StateReport) ----- */
202 // Internal struct for StateReport
206 IOReportElement elem
[]; // Array of elements
210 * Determine the size required for a StateReport buffer.
212 * int nstates - number of states to be reported
214 #define STATEREPORT_BUFSIZE(nstates) \
215 (sizeof(IOStateReportInfo) + (nstates) * sizeof(IOReportElement))
219 * Initialize a StateReport buffer.
221 * int nstates - number of states to be reported
222 * void* buffer - ptr to STATEREPORT_BUFSIZE(nstates) bytes
223 * size_t bufSize - sanity check of buffer's size
224 * uint64_t providerID - registry Entry ID of the reporting service
225 * uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
226 * IOReportCategories categories - categories of this channel
228 * If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT.
229 * If that returns, the buffer is left full of '&'.
231 #define STATEREPORT_INIT(nstates, buf, bufSize, providerID, channelID, cats) \
233 memset((buf), '&', (bufSize)); \
234 IOStateReportInfo *__info = (IOStateReportInfo *)(buf); \
235 IOStateReportValues *__rep; \
236 IOReportElement *__elem; \
237 if ((bufSize) >= STATEREPORT_BUFSIZE(nstates)) { \
238 for (unsigned __no = 0; __no < (nstates); __no++) { \
239 __elem = &(__info->elem[__no]); \
240 __rep = (IOStateReportValues *) &(__elem->values); \
241 __elem->provider_id = (providerID); \
242 __elem->channel_id = (channelID); \
243 __elem->channel_type.report_format = kIOReportFormatState; \
244 __elem->channel_type.reserved = 0; \
245 __elem->channel_type.categories = (cats); \
246 __elem->channel_type.nelements = (nstates); \
247 __elem->channel_type.element_idx = __no; \
248 __elem->timestamp = 0; \
249 __rep->state_id = __no; \
250 __rep->intransitions = 0; \
251 __rep->upticks = 0; \
252 __rep->last_intransition = 0; \
254 __info->curr_state = 0; \
255 __info->update_ts = 0; \
258 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
263 * Initialize the state id field of a state with the specified value. By
264 * default, STATEREPORT_INIT() initializes the state IDs with the index of
265 * that state. This macro can be used to provide a more descriptive state id.
267 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
268 * unsigned stateIdx - index of the state, out of bounds -> no-op
269 * uint64_t stateID - new state id, see IOREPORT_MAKEID()
271 #define STATEREPORT_SETSTATEID(state_buf, stateIdx, stateID) \
273 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
274 IOStateReportValues *__rep; \
275 if ((stateIdx) < __info->elem[0].channel_type.nelements) { \
276 __rep = (IOStateReportValues*) &(__info->elem[(stateIdx)].values); \
277 __rep->state_id = (stateID); \
283 * Set the state of a StateReport.
285 * void* state_buf - pointer to memory initialized by STATEREPORT_INIT()
286 * unsigned newStateIdx - index of new state, out of bounds -> no-op
287 * uint64_t changeTime - time at which the transition occurred
289 #define STATEREPORT_SETSTATE(state_buf, newStateIdx, changeTime) \
291 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
292 IOStateReportValues *__rep; \
293 if ((newStateIdx) < __info->elem[0].channel_type.nelements ) { \
294 __rep = (IOStateReportValues*) &(__info->elem[__info->curr_state].values); \
295 if (__info->update_ts) \
296 __rep->upticks += (changeTime) - __info->update_ts; \
297 __info->elem[(newStateIdx)].timestamp = (changeTime); \
298 __rep = (IOStateReportValues*) &(__info->elem[(newStateIdx)].values); \
299 __rep->intransitions++; \
300 __info->curr_state = (newStateIdx); \
301 __info->update_ts = (changeTime); \
306 * Prepare a StateReport for
307 * IOService::updateReport(kIOReportCopyChannelData...)
309 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
310 * uint64_t currentTime - current timestamp
311 * void* ptr2cpy - filled in with pointer to buffer to be copied out
312 * size_t size2cpy - filled in with the size of the buffer to copy out
314 #define STATEREPORT_UPDATEPREP(state_buf, currentTime, ptr2cpy, size2cpy) \
316 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
317 IOReportElement *__elem; \
318 IOStateReportValues *__state; \
319 (size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement); \
320 (ptr2cpy) = (void *) &__info->elem[0]; \
321 if (__info->update_ts) { \
322 __elem = &__info->elem[__info->curr_state]; \
323 __state = (IOStateReportValues *)&__elem->values; \
324 __elem->timestamp = (currentTime); \
325 __state->upticks += (currentTime) - __info->update_ts; \
326 __info->update_ts = (currentTime); \
331 * Update the result field received as a parameter for kIOReportGetDimensions &
332 * kIOReportCopyChannelData actions.
334 * void* state_buf - memory initialized by STATEREPORT_INIT()
335 * IOReportConfigureAction action - configure/updateReport() 'action'
336 * void* result - configure/updateReport() 'result'
339 #define STATEREPORT_UPDATERES(state_buf, action, result) \
341 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
342 IOReportElement *__elem; \
343 int *__nElements = (int *)(result); \
344 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
345 __elem = &(__info->elem[0]); \
346 *__nElements += __elem->channel_type.nelements; \
352 * Get the 64-bit channel ID of a StateReport.
354 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
356 #define STATEREPORT_GETCHID(state_buf) \
357 (((IOStateReportInfo *)(state_buf))->elem[0].channel_id)
360 * Get the IOReportChannelType of a StateReport.
362 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
364 #define STATEREPORT_GETCHTYPE(state_buf) \
365 (*(uint64_t*)&(((IOStateReportInfo *)(state_buf))->elem[0].channel_type))
368 * Get the number of transitions into a given state.
370 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
371 * unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
374 #define STATEREPORT_GETTRANSITIONS(state_buf, stateIdx) \
375 (((stateIdx) < ((IOStateReportInfo *)(state_buf))->elem[0].channel_type.nelements) \
376 ? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->intransitions \
377 : kIOReportInvalidValue)
380 * Get the total number of ticks spent in a given state.
382 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
383 * unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
385 #define STATEREPORT_GETTICKS(state_buf, stateIdx) \
386 (((stateIdx) < ((IOStateReportInfo*)(state_buf))->elem[0].channel_type.nelements) \
387 ? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->upticks \
388 : kIOReportInvalidValue)
391 /* ----- Reporting an Array of Integers (SimpleArrayReport) ----- */
394 * Determine the buffer size for a SimpleArrayReport.
396 * int nValues - number of values to be reported
399 #define SIMPLEARRAY_BUFSIZE(nValues) \
400 ((((nValues)/IOR_VALUES_PER_ELEMENT) + (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1:0)) \
401 * sizeof(IOReportElement))
404 * Initialize a buffer for use as a SimpleArrayReport.
406 * int nValues - number of elements to be reported
407 * void* buf - ptr to SIMPLEARRAY_BUFSIZE(nValues) bytes
408 * size_t bufSize - sanity check of buffer's size
409 * uint64_t providerID - registry Entry ID of the reporting service
410 * uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
411 * IOReportCategories categories - categories of this channel
413 * If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT().
414 * If that returns, the buffer is left full of '&'.
417 #define SIMPLEARRAY_INIT(nValues, buf, bufSize, providerID, channelID, cats) \
419 memset((buf), '&', (bufSize)); \
420 IOSimpleArrayReportValues *__rep; \
421 IOReportElement *__elem; \
422 uint32_t __nElems = (((nValues) / IOR_VALUES_PER_ELEMENT) + \
423 (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1 : 0)); \
424 if ((bufSize) >= SIMPLEARRAY_BUFSIZE(nValues)) { \
425 for (unsigned __no = 0; __no < __nElems; __no++) { \
426 __elem = &(((IOReportElement *)(buf))[__no]); \
427 __rep = (IOSimpleArrayReportValues *) &(__elem->values); \
428 __elem->provider_id = (providerID); \
429 __elem->channel_id = (channelID); \
430 __elem->channel_type.report_format = kIOReportFormatSimpleArray; \
431 __elem->channel_type.reserved = 0; \
432 __elem->channel_type.categories = (cats); \
433 __elem->channel_type.nelements = (__nElems); \
434 __elem->channel_type.element_idx = __no; \
435 __elem->timestamp = 0; \
436 __rep->simple_values[0] = kIOReportInvalidIntValue; \
437 __rep->simple_values[1] = kIOReportInvalidIntValue; \
438 __rep->simple_values[2] = kIOReportInvalidIntValue; \
439 __rep->simple_values[3] = kIOReportInvalidIntValue; \
443 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
448 /* SimpleArrayReport helpers */
450 #define __SA_FINDREP(array_buf, idx) \
451 IOSimpleArrayReportValues *__rep; \
452 IOReportElement *__elem; \
453 unsigned __elemIdx = (idx) / IOR_VALUES_PER_ELEMENT; \
454 unsigned __valueIdx = (idx) % IOR_VALUES_PER_ELEMENT; \
455 __elem = &(((IOReportElement *)(array_buf))[0]); \
456 if (__elemIdx < __elem->channel_type.nelements) { \
457 __elem = &(((IOReportElement *)(array_buf))[__elemIdx]); \
458 __rep = (IOSimpleArrayReportValues *) &(__elem->values); \
460 #define __SA_MAXINDEX(array_buf) \
461 ((((IOReportElement*)(array_buf))->channel_type.nelements) \
462 * IOR_VALUES_PER_ELEMENT) - 1
465 * Set a value at a specified index in a SimpleArrayReport.
467 * void* array_bufbuf - ptr to memory initialized by SIMPLEARRAY_INIT()
468 * unsigned idx - array index, out of bounds -> no-op
469 * uint64_t newValue - new value to be stored at array[idx]
471 #define SIMPLEARRAY_SETVALUE(array_buf, idx, newValue) \
473 __SA_FINDREP((array_buf), (idx)) \
474 __rep->simple_values[__valueIdx] = (newValue); \
479 * Increment an array value within a SimpleArrayReport.
481 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
482 * unsigned idx - array index to increment, out of bounds -> no-op
483 * int64_t value - amount by which to increment array[idx]
485 #define SIMPLEARRAY_INCREMENTVALUE(array_buf, idx, value) \
487 __SA_FINDREP((array_buf), (idx)) \
488 __rep->simple_values[__valueIdx] += (value); \
494 * Prepare a SimpleArrayReport for
495 * IOService::updateReport(kIOReportCopyChannelData...)
497 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
498 * void* ptr2cpy - filled in with pointer to buffer to be copied out
499 * size_t size2cpy - filled in with the size of the buffer to copy out
502 #define SIMPLEARRAY_UPDATEPREP(array_buf, ptr2cpy, size2cpy) \
504 IOReportElement *__elem; \
505 __elem = &(((IOReportElement *)(array_buf))[0]); \
506 (ptr2cpy) = (void *) (array_buf); \
507 (size2cpy) = __elem->channel_type.nelements * sizeof(IOReportElement); \
512 * Update the result field received as a parameter for kIOReportGetDimensions &
513 * kIOReportCopyChannelData actions.
515 * void* array_buf - memory initialized by SIMPLEARRAY_INIT()
516 * IOReportConfigureAction action - configure/updateReport() 'action'
517 * void* result - configure/updateReport() 'result'
520 #define SIMPLEARRAY_UPDATERES(array_buf, action, result) \
522 IOReportElement *__elem; \
523 int *__nElements = (int *)(result); \
524 __elem = &(((IOReportElement *)(array_buf))[0]); \
525 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
526 *__nElements += __elem->channel_type.nelements; \
532 * Get the 64-bit channel ID of a SimpleArrayReport.
534 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
536 #define SIMPLEARRAY_GETCHID(array_buf) \
537 (((IOReportElement *)(array_buf))->channel_id)
541 * Get the IOReportChannelType of a SimpleArrayReport.
543 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
545 #define SIMPLEARRAY_GETCHTYPE(array_buf) \
546 (*(uint64_t*)&(((IOReportElement *)(array_buf))->channel_type))
549 * Get a value from a SimpleArrayReport.
551 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
552 * unsigned idx - index of the value, out of bounds -> kIOReportInvalidValue
554 #define SIMPLEARRAY_GETVALUE(array_buf, idx) \
555 (((idx) > __SA_MAXINDEX(array_buf) || (idx) < 0) ? kIOReportInvalidIntValue : \
556 ((IOSimpleArrayReportValues*)&( \
557 ((IOReportElement*)(array_buf))[(idx) / IOR_VALUES_PER_ELEMENT].values)) \
558 ->simple_values[(idx) % IOR_VALUES_PER_ELEMENT])
561 /* ----- Histogram Reporting (HistogramReport) ----- */
563 // Internal struct for HistogramReport
566 IOReportElement elem
[]; // Array of elements
570 * Determine the size required for a HistogramReport buffer.
572 * int nbuckets - number of buckets in the histogram
574 #define HISTREPORT_BUFSIZE(nbuckets) \
575 (sizeof(IOHistReportInfo) + ((nbuckets) * sizeof(IOReportElement)))
578 * Initialize a HistogramReport buffer. Supports only linear scale histogram.
580 * int nbuckets - number of buckets data is combined into
581 * uint32_t bucketWidth - size of each bucket
582 * void* buffer - ptr to HISTREPORT_BUFSIZE(nbuckets) bytes
583 * size_t bufSize - sanity check of buffer's size
584 * uint64_t providerID - registry Entry ID of the reporting service
585 * uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
586 * IOReportCategories categories - categories of this channel
588 * If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT.
589 * If that returns, the buffer is left full of '&'.
591 #define HISTREPORT_INIT(nbuckets, bktSize, buf, bufSize, providerID, channelID, cats) \
593 memset((buf), '&', (bufSize)); \
594 IOHistReportInfo *__info = (IOHistReportInfo *)(buf); \
595 IOReportElement *__elem; \
596 IOHistogramReportValues *__rep; \
597 if ((bufSize) >= HISTREPORT_BUFSIZE(nbuckets)) { \
598 __info->bucketWidth = (bktSize); \
599 for (unsigned __no = 0; __no < (nbuckets); __no++) { \
600 __elem = &(__info->elem[__no]); \
601 __rep = (IOHistogramReportValues *) &(__elem->values); \
602 __elem->provider_id = (providerID); \
603 __elem->channel_id = (channelID); \
604 __elem->channel_type.report_format = kIOReportFormatHistogram; \
605 __elem->channel_type.reserved = 0; \
606 __elem->channel_type.categories = (cats); \
607 __elem->channel_type.nelements = (nbuckets); \
608 __elem->channel_type.element_idx = __no; \
609 __elem->timestamp = 0; \
610 memset(__rep, '\0', sizeof(IOHistogramReportValues)); \
614 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
619 * Update histogram with a new value.
622 * void* hist_buf - pointer to memory initialized by HISTREPORT_INIT()
623 * int64_t value - new value to add to the histogram
625 #define HISTREPORT_TALLYVALUE(hist_buf, value) \
627 IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf); \
628 IOReportElement *__elem; \
629 IOHistogramReportValues *__rep; \
630 for (unsigned __no = 0; __no < __info->elem[0].channel_type.nelements; __no++) { \
631 if ((value) <= __info->bucketWidth * (__no+1)) { \
632 __elem = &(__info->elem[__no]); \
633 __rep = (IOHistogramReportValues *) &(__elem->values); \
634 if (__rep->bucket_hits == 0) { \
635 __rep->bucket_min = __rep->bucket_max = (value); \
637 else if ((value) < __rep->bucket_min) { \
638 __rep->bucket_min = (value); \
640 else if ((value) > __rep->bucket_max) { \
641 __rep->bucket_max = (value); \
643 __rep->bucket_sum += (value); \
644 __rep->bucket_hits++; \
651 * Prepare a HistogramReport for
652 * IOService::updateReport(kIOReportCopyChannelData...)
654 * void* array_buf - ptr to memory initialized by HISTREPORT_INIT()
655 * void* ptr2cpy - filled in with pointer to buffer to be copied out
656 * size_t size2cpy - filled in with the size of the buffer to copy out
659 #define HISTREPORT_UPDATEPREP(hist_buf, ptr2cpy, size2cpy) \
661 IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf); \
662 (size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement); \
663 (ptr2cpy) = (void *) &__info->elem[0]; \
668 * Update the result field received as a parameter for kIOReportGetDimensions &
669 * kIOReportCopyChannelData actions.
671 * void* array_buf - memory initialized by HISTREPORT_INIT()
672 * IOReportConfigureAction action - configure/updateReport() 'action'
673 * void* result - configure/updateReport() 'result'
676 #define HISTREPORT_UPDATERES(hist_buf, action, result) \
678 IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf); \
679 int *__nElements = (int *)(result); \
680 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
681 *__nElements += __info->elem[0].channel_type.nelements; \
686 * Get the 64-bit channel ID of a HistogramReport.
688 * void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
690 #define HISTREPORT_GETCHID(hist_buf) \
691 (((IOHistReportInfo *)(hist_buf))->elem[0].channel_id)
694 * Get the IOReportChannelType of a HistogramReport.
696 * void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
698 #define HISTREPORT_GETCHTYPE(hist_buf) \
699 (*(uint64_t*)&(((IOHistReportInfo *)(hist_buf))->elem[0].channel_type))
705 #endif // _IOREPORT_MACROS_H_