]>
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"
38 #ifndef IOREPORT_ABORT
39 #define IOREPORT_ABORT panic
45 These macros allow non-I/O Kit software to generate IOReporting
46 reports. Clients must prevent concurrent access to any given
47 report buffer from multiple threads.
49 While these macros allow non-I/O Kit software to participate
50 in IOReporting, an IOService instance must lend its driver ID,
51 respond to the appropriate IOService overrides, and shuttle
52 data back and forth. In some cases, it may be useful to have
53 the I/O Kit driver initialize the report buffer with the
58 /* ----- Reporting Single Integers (SimpleReport) ----- */
61 * The buffer size required for a SimpleReport.
64 #define SIMPLEREPORT_BUFSIZE (sizeof(IOReportElement))
68 * Initialize a buffer to hold a SimpleReport.
70 * void* buffer - ptr to SIMPLEREPORT_BUFSIZE bytes
71 * size_t bufSize - sanity check of buffer's size
72 * uint64_t providerID - registry Entry ID of the reporting service
73 * uint64_t channelID - the report's channel ID
74 * IOReportCategories categories - categories of this channel
76 * If the buffer is not of sufficient size, the macro calls IOREPORT_ABORT().
77 * If that returns, the buffer is filled with 0xbadcafe.
80 #define SIMPLEREPORT_INIT(buffer, bufSize, providerID, channelID, cats) \
82 IOReportElement *__elem = (IOReportElement *)(buffer); \
83 IOSimpleReportValues *__vals; \
84 if ((bufSize) >= SIMPLEREPORT_BUFSIZE) { \
85 __elem->channel_id = (channelID); \
86 __elem->provider_id = (providerID); \
87 __elem->channel_type.report_format = kIOReportFormatSimple; \
88 __elem->channel_type.reserved = 0; \
89 __elem->channel_type.categories = (cats); \
90 __elem->channel_type.nelements = 1; \
91 __elem->channel_type.element_idx = 0; \
92 __elem->timestamp = 0; \
93 __vals = (IOSimpleReportValues*)&__elem->values; \
94 __vals->simple_value = kIOReportInvalidIntValue; \
97 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
98 __POLLUTE_BUF((buffer), (bufSize)); \
104 * Set a SimpleReport to a new value.
106 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
107 * int64_t new_value - new value for the report
110 #define SIMPLEREPORT_SETVALUE(simp_buf, new_value) \
112 IOReportElement *__elem = (IOReportElement *)(simp_buf); \
113 IOSimpleReportValues *__vals; \
114 __vals = (IOSimpleReportValues*)&__elem->values; \
115 __vals->simple_value = (new_value); \
120 * Increment the value of a SimpleReport.
122 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
123 * int64_t increment - amount by which to increment the value
125 #define SIMPLEREPORT_INCREMENTVALUE(simp_buf, new_value) \
127 IOReportElement *__elem = (IOReportElement *)(simp_buf); \
128 IOSimpleReportValues *__vals; \
129 __vals = (IOSimpleReportValues*)&__elem->values; \
130 __vals->simple_value += (new_value); \
135 * Prepare a SimpleReport for
136 * IOService::updateReport(kIOReportCopyChannelData...)
138 * void* simp_buf - Ptr to memory updated by SIMPLEREPORT_SETVALUE()
139 * void* ptr2cpy - On return, 'ptr2cpy' points to the memory that needs to be
140 * copied for kIOReportCopyChannelData.
141 * size_t size2cpy - On return, 'size2cpy' is set to the size of the report
142 * data that needs to be copied for kIOReportCopyChannelData.
145 #define SIMPLEREPORT_UPDATEPREP(simp_buf, ptr2cpy, size2cpy) \
147 (ptr2cpy) = (simp_buf); \
148 (size2cpy) = sizeof(IOReportElement); \
153 * Update the result field received as a parameter for
154 * kIOReportGetDimensions & kIOReportCopyChannelData actions.
156 * IOReportConfigureAction action - configure/updateReport() 'action' param
157 * void* result - configure/updateReport() 'result' param
160 #define SIMPLEREPORT_UPDATERES(action, result) \
162 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
163 int *__nElements = (int *)(result); \
170 * Get the 64-bit channel ID of a SimpleReport.
172 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
175 #define SIMPLEREPORT_GETCHID(simp_buf) \
176 (((IOReportElement *)(simp_buf))->channel_id)
179 * Get the IOReportChannelType of a SimpleReport.
181 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
184 #define SIMPLEREPORT_GETCHTYPE(simp_buf) \
185 (*(uint64_t*)&(((IOReportElement *)(simp_buf))->channel_type))
189 * Get the integer value of a SimpleReport.
191 * void* simp_buf - memory initialized by SIMPLEREPORT_INIT()
194 #define SIMPLEREPORT_GETVALUE(simp_buf) \
195 (((IOSimpleReportValues*)&(((IOReportElement*)(simp_buf))->values)) \
199 /* ----- State Machine Reporting (StateReport) ----- */
201 // Internal struct for StateReport
205 IOReportElement elem
[]; // Array of elements
209 * Determine the size required for a StateReport buffer.
211 * int nstates - number of states to be reported
213 #define STATEREPORT_BUFSIZE(nstates) \
214 (sizeof(IOStateReportInfo) + (nstates) * sizeof(IOReportElement))
218 * Initialize a StateReport buffer.
220 * int nstates - number of states to be reported
221 * void* buffer - ptr to STATEREPORT_BUFSIZE(nstates) bytes
222 * size_t bufSize - sanity check of buffer's size
223 * uint64_t providerID - registry Entry ID of the reporting service
224 * uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
225 * IOReportCategories categories - categories of this channel
227 * If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT.
228 * If that returns, the buffer is filled with 0xbadcafe.
230 #define STATEREPORT_INIT(nstates, buf, bufSize, providerID, channelID, cats) \
232 IOStateReportInfo *__info = (IOStateReportInfo *)(buf); \
233 IOStateReportValues *__rep; \
234 IOReportElement *__elem; \
235 if ((bufSize) >= STATEREPORT_BUFSIZE(nstates)) { \
236 for (unsigned __no = 0; __no < (nstates); __no++) { \
237 __elem = &(__info->elem[__no]); \
238 __rep = (IOStateReportValues *) &(__elem->values); \
239 __elem->channel_id = (channelID); \
240 __elem->provider_id = (providerID); \
241 __elem->channel_type.report_format = kIOReportFormatState; \
242 __elem->channel_type.reserved = 0; \
243 __elem->channel_type.categories = (cats); \
244 __elem->channel_type.nelements = (nstates); \
245 __elem->channel_type.element_idx = __no; \
246 __elem->timestamp = 0; \
247 __rep->state_id = __no; \
248 __rep->intransitions = 0; \
249 __rep->upticks = 0; \
251 __info->curr_state = 0; \
252 __info->update_ts = 0; \
255 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
256 __POLLUTE_BUF((buf), (bufSize)); \
261 * Initialize the state id field of a state with the specified value. By
262 * default, STATEREPORT_INIT() initializes the state IDs with the index of
263 * that state. This macro can be used to provide a more descriptive state id.
265 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
266 * unsigned stateIdx - index of the state, out of bounds -> no-op
267 * uint64_t stateID - new state id, see IOREPORT_MAKEID()
269 #define STATEREPORT_SETSTATEID(state_buf, stateIdx, stateID) \
271 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
272 IOStateReportValues *__rep; \
273 if ((stateIdx) < __info->elem[0].channel_type.nelements) { \
274 __rep = (IOStateReportValues*) &(__info->elem[(stateIdx)].values); \
275 __rep->state_id = (stateID); \
281 * Set the state of a StateReport.
283 * void* state_buf - pointer to memory initialized by STATEREPORT_INIT()
284 * unsigned newStateIdx - index of new state, out of bounds -> no-op
285 * uint64_t changeTime - time at which the transition occurred
287 #define STATEREPORT_SETSTATE(state_buf, newStateIdx, changeTime) \
289 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
290 IOStateReportValues *__rep; \
291 if ((newStateIdx) < __info->elem[0].channel_type.nelements ) { \
292 __rep = (IOStateReportValues*) &(__info->elem[__info->curr_state].values); \
293 if (__info->update_ts) \
294 __rep->upticks += (changeTime) - __info->update_ts; \
295 __info->elem[(newStateIdx)].timestamp = (changeTime); \
296 __rep = (IOStateReportValues*) &(__info->elem[(newStateIdx)].values); \
297 __rep->intransitions++; \
298 __info->curr_state = (newStateIdx); \
299 __info->update_ts = (changeTime); \
304 * Prepare a StateReport for
305 * IOService::updateReport(kIOReportCopyChannelData...)
307 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
308 * uint64_t currentTime - current timestamp
309 * void* ptr2cpy - filled in with pointer to buffer to be copied out
310 * size_t size2cpy - filled in with the size of the buffer to copy out
312 #define STATEREPORT_UPDATEPREP(state_buf, currentTime, ptr2cpy, size2cpy) \
314 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
315 IOReportElement *__elem; \
316 IOStateReportValues *__state; \
317 (size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement); \
318 (ptr2cpy) = (void *) &__info->elem[0]; \
319 if (__info->update_ts) { \
320 __elem = &__info->elem[__info->curr_state]; \
321 __state = (IOStateReportValues *)&__elem->values; \
322 __elem->timestamp = (currentTime); \
323 __state->upticks += (currentTime) - __info->update_ts; \
324 __info->update_ts = (currentTime); \
329 * Update the result field received as a parameter for kIOReportGetDimensions &
330 * kIOReportCopyChannelData actions.
332 * void* state_buf - memory initialized by STATEREPORT_INIT()
333 * IOReportConfigureAction action - configure/updateReport() 'action'
334 * void* result - configure/updateReport() 'result'
337 #define STATEREPORT_UPDATERES(state_buf, action, result) \
339 IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf); \
340 IOReportElement *__elem; \
341 int *__nElements = (int *)(result); \
342 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
343 __elem = &(__info->elem[0]); \
344 *__nElements += __elem->channel_type.nelements; \
350 * Get the 64-bit channel ID of a StateReport.
352 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
354 #define STATEREPORT_GETCHID(state_buf) \
355 (((IOStateReportInfo *)(state_buf))->elem[0].channel_id)
358 * Get the IOReportChannelType of a StateReport.
360 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
362 #define STATEREPORT_GETCHTYPE(state_buf) \
363 (*(uint64_t*)&(((IOStateReportInfo *)(state_buf))->elem[0].channel_type))
366 * Get the number of transitions into a given state.
368 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
369 * unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
372 #define STATEREPORT_GETTRANSITIONS(state_buf, stateIdx) \
373 (((stateIdx) < ((IOStateReportInfo *)(state_buf))->elem[0].channel_type.nelements) \
374 ? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->intransitions \
375 : kIOReportInvalidValue)
378 * Get the total number of ticks spent in a given state.
380 * void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
381 * unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
383 #define STATEREPORT_GETTICKS(state_buf, stateIdx) \
384 (((stateIdx) < ((IOStateReportInfo*)(state_buf))->elem[0].channel_type.nelements) \
385 ? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->upticks \
386 : kIOReportInvalidValue)
389 /* ----- Reporting an Array of Integers (SimpleArrayReport) ----- */
392 * Determine the buffer size for a SimpleArrayReport.
394 * int nValues - number of values to be reported
397 #define SIMPLEARRAY_BUFSIZE(nValues) \
398 ((((nValues)/IOR_VALUES_PER_ELEMENT) + (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1:0)) \
399 * sizeof(IOReportElement))
402 * Initialize a buffer for use as a SimpleArrayReport.
404 * int nValues - number of elements to be reported
405 * void* buf - ptr to SIMPLEARRAY_BUFSIZE(nValues) bytes
406 * size_t bufSize - sanity check of buffer's size
407 * uint64_t providerID - registry Entry ID of the reporting service
408 * uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
409 * IOReportCategories categories - categories of this channel
411 * If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT()
412 * and, if that returns, fills the buffer with 0xbadcafe.
415 #define SIMPLEARRAY_INIT(nValues, buf, bufSize, providerID, channelID, cats) \
417 IOSimpleArrayReportValues *__rep; \
418 IOReportElement *__elem; \
419 uint32_t __nElems = (((nValues) / IOR_VALUES_PER_ELEMENT) + \
420 (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1 : 0)); \
421 if ((bufSize) >= SIMPLEARRAY_BUFSIZE(nValues)) { \
422 for (unsigned __no = 0; __no < __nElems; __no++) { \
423 __elem = &(((IOReportElement *)(buf))[__no]); \
424 __rep = (IOSimpleArrayReportValues *) &(__elem->values); \
425 __elem->channel_id = (channelID); \
426 __elem->provider_id = (providerID); \
427 __elem->channel_type.report_format = kIOReportFormatSimpleArray; \
428 __elem->channel_type.reserved = 0; \
429 __elem->channel_type.categories = (cats); \
430 __elem->channel_type.nelements = (__nElems); \
431 __elem->channel_type.element_idx = __no; \
432 __elem->timestamp = 0; \
433 __rep->simple_values[0] = kIOReportInvalidIntValue; \
434 __rep->simple_values[1] = kIOReportInvalidIntValue; \
435 __rep->simple_values[2] = kIOReportInvalidIntValue; \
436 __rep->simple_values[3] = kIOReportInvalidIntValue; \
440 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
441 __POLLUTE_BUF((buf), (bufSize)); \
446 /* SimpleArrayReport helpers */
448 #define __SA_FINDREP(array_buf, idx) \
449 IOSimpleArrayReportValues *__rep; \
450 IOReportElement *__elem; \
451 unsigned __elemIdx = (idx) / IOR_VALUES_PER_ELEMENT; \
452 unsigned __valueIdx = (idx) % IOR_VALUES_PER_ELEMENT; \
453 __elem = &(((IOReportElement *)(array_buf))[0]); \
454 if (__elemIdx < __elem->channel_type.nelements) { \
455 __elem = &(((IOReportElement *)(array_buf))[__elemIdx]); \
456 __rep = (IOSimpleArrayReportValues *) &(__elem->values); \
458 #define __SA_MAXINDEX(array_buf) \
459 ((((IOReportElement*)(array_buf))->channel_type.nelements) \
460 * IOR_VALUES_PER_ELEMENT) - 1
463 * Set a value at a specified index in a SimpleArrayReport.
465 * void* array_bufbuf - ptr to memory initialized by SIMPLEARRAY_INIT()
466 * unsigned idx - array index, out of bounds -> no-op
467 * uint64_t newValue - new value to be stored at array[idx]
469 #define SIMPLEARRAY_SETVALUE(array_buf, idx, newValue) \
471 __SA_FINDREP((array_buf), (idx)) \
472 __rep->simple_values[__valueIdx] = (newValue); \
477 * Increment an array value within a SimpleArrayReport.
479 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
480 * unsigned idx - array index to increment, out of bounds -> no-op
481 * int64_t value - amount by which to increment array[idx]
483 #define SIMPLEARRAY_INCREMENTVALUE(array_buf, idx, value) \
485 __SA_FINDREP((array_buf), (idx)) \
486 __rep->simple_values[__valueIdx] += (value); \
492 * Prepare a SimpleArrayReport for
493 * IOService::updateReport(kIOReportCopyChannelData...)
495 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
496 * void* ptr2cpy - filled in with pointer to buffer to be copied out
497 * size_t size2cpy - filled in with the size of the buffer to copy out
500 #define SIMPLEARRAY_UPDATEPREP(array_buf, ptr2cpy, size2cpy) \
502 IOReportElement *__elem; \
503 __elem = &(((IOReportElement *)(array_buf))[0]); \
504 (ptr2cpy) = (void *) (array_buf); \
505 (size2cpy) = __elem->channel_type.nelements * sizeof(IOReportElement); \
510 * Update the result field received as a parameter for kIOReportGetDimensions &
511 * kIOReportCopyChannelData actions.
513 * void* array_buf - memory initialized by SIMPLEARRAY_INIT()
514 * IOReportConfigureAction action - configure/updateReport() 'action'
515 * void* result - configure/updateReport() 'result'
518 #define SIMPLEARRAY_UPDATERES(array_buf, action, result) \
520 IOReportElement *__elem; \
521 int *__nElements = (int *)(result); \
522 __elem = &(((IOReportElement *)(array_buf))[0]); \
523 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
524 *__nElements += __elem->channel_type.nelements; \
530 * Get the 64-bit channel ID of a SimpleArrayReport.
532 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
534 #define SIMPLEARRAY_GETCHID(array_buf) \
535 (((IOReportElement *)(array_buf))->channel_id)
539 * Get the IOReportChannelType of a SimpleArrayReport.
541 * void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
543 #define SIMPLEARRAY_GETCHTYPE(array_buf) \
544 (*(uint64_t*)&(((IOReportElement *)(array_buf))->channel_type))
547 * Get a value from a SimpleArrayReport.
549 * void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
550 * unsigned idx - index of the value, out of bounds -> kIOReportInvalidValue
552 #define SIMPLEARRAY_GETVALUE(array_buf, idx) \
553 (((idx) > __SA_MAXINDEX(array_buf) || (idx) < 0) ? kIOReportInvalidIntValue : \
554 ((IOSimpleArrayReportValues*)&( \
555 ((IOReportElement*)(array_buf))[(idx) / IOR_VALUES_PER_ELEMENT].values)) \
556 ->simple_values[(idx) % IOR_VALUES_PER_ELEMENT])
559 /* ----- Histogram Reporting (HistogramReport) ----- */
561 // Internal struct for HistogramReport
564 IOReportElement elem
[]; // Array of elements
568 * Determine the size required for a HistogramReport buffer.
570 * int nbuckets - number of buckets in the histogram
572 #define HISTREPORT_BUFSIZE(nbuckets) \
573 (sizeof(IOHistReportInfo) + ((nbuckets) * sizeof(IOReportElement)))
576 * Initialize a HistogramReport buffer. Supports only linear scale histogram.
578 * int nbuckets - number of buckets data is combined into
579 * uint32_t bucketWidth - size of each bucket
580 * void* buffer - ptr to HISTREPORT_BUFSIZE(nbuckets) bytes
581 * size_t bufSize - sanity check of buffer's size
582 * uint64_t providerID - registry Entry ID of the reporting service
583 * uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
584 * IOReportCategories categories - categories of this channel
586 * If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT.
587 * If that returns, the buffer is filled with 0xbadcafe.
589 #define HISTREPORT_INIT(nbuckets, bktSize, buf, bufSize, providerID, channelID, cats) \
591 IOHistReportInfo *__info = (IOHistReportInfo *)(buf); \
592 IOReportElement *__elem; \
593 IOHistogramReportValues *__rep; \
594 if ((bufSize) >= HISTREPORT_BUFSIZE(nbuckets)) { \
595 __info->bucketWidth = (bktSize); \
596 for (unsigned __no = 0; __no < (nbuckets); __no++) { \
597 __elem = &(__info->elem[__no]); \
598 __rep = (IOHistogramReportValues *) &(__elem->values); \
599 __elem->channel_id = (channelID); \
600 __elem->provider_id = (providerID); \
601 __elem->channel_type.report_format = kIOReportFormatHistogram; \
602 __elem->channel_type.reserved = 0; \
603 __elem->channel_type.categories = (cats); \
604 __elem->channel_type.nelements = (nbuckets); \
605 __elem->channel_type.element_idx = __no; \
606 __elem->timestamp = 0; \
607 bzero(__rep, sizeof(IOHistogramReportValues)); \
611 IOREPORT_ABORT("bufSize is smaller than the required size\n"); \
612 __POLLUTE_BUF((buf), (bufSize)); \
617 * Update histogram with a new value.
620 * void* hist_buf - pointer to memory initialized by HISTREPORT_INIT()
621 * int64_t value - new value to add to the histogram
623 #define HISTREPORT_TALLYVALUE(hist_buf, value) \
625 IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf); \
626 IOReportElement *__elem; \
627 IOHistogramReportValues *__rep; \
628 for (unsigned __no = 0; __no < __info->elem[0].channel_type.nelements; __no++) { \
629 if ((value) <= __info->bucketWidth * (__no+1)) { \
630 __elem = &(__info->elem[__no]); \
631 __rep = (IOHistogramReportValues *) &(__elem->values); \
632 if (__rep->bucket_hits == 0) { \
633 __rep->bucket_min = __rep->bucket_max = (value); \
635 else if ((value) < __rep->bucket_min) { \
636 __rep->bucket_min = (value); \
638 else if ((value) > __rep->bucket_max) { \
639 __rep->bucket_max = (value); \
641 __rep->bucket_sum += (value); \
642 __rep->bucket_hits++; \
649 * Prepare a HistogramReport for
650 * IOService::updateReport(kIOReportCopyChannelData...)
652 * void* array_buf - ptr to memory initialized by HISTREPORT_INIT()
653 * void* ptr2cpy - filled in with pointer to buffer to be copied out
654 * size_t size2cpy - filled in with the size of the buffer to copy out
657 #define HISTREPORT_UPDATEPREP(hist_buf, ptr2cpy, size2cpy) \
659 IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf); \
660 (size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement); \
661 (ptr2cpy) = (void *) &__info->elem[0]; \
666 * Update the result field received as a parameter for kIOReportGetDimensions &
667 * kIOReportCopyChannelData actions.
669 * void* array_buf - memory initialized by HISTREPORT_INIT()
670 * IOReportConfigureAction action - configure/updateReport() 'action'
671 * void* result - configure/updateReport() 'result'
674 #define HISTREPORT_UPDATERES(hist_buf, action, result) \
676 IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf); \
677 int *__nElements = (int *)(result); \
678 if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) { \
679 *__nElements += __info->elem[0].channel_type.nelements; \
684 * Get the 64-bit channel ID of a HistogramReport.
686 * void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
688 #define HISTREPORT_GETCHID(hist_buf) \
689 (((IOHistReportInfo *)(hist_buf))->elem[0].channel_id)
692 * Get the IOReportChannelType of a HistogramReport.
694 * void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
696 #define HISTREPORT_GETCHTYPE(hist_buf) \
697 (*(uint64_t*)&(((IOHistReportInfo *)(hist_buf))->elem[0].channel_type))
701 /* generic utilities */
703 #define __POLLUTE_BUF(buf, bufSize) \
705 int __cnt = (bufSize)/sizeof(uint32_t); \
706 while (--__cnt >= 0) \
707 ((uint32_t*)(buf))[__cnt] = 0xbadcafe; \
714 #endif // _IOREPORT_MACROS_H_