Loading...
iokit/Kernel/IOReporter.cpp xnu-12377.101.15 /dev/null
--- xnu/xnu-12377.101.15/iokit/Kernel/IOReporter.cpp
+++ /dev/null
@@ -1,1131 +0,0 @@
-/*
- * Copyright (c) 2012-2013 Apple Computer, Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#define IOKIT_ENABLE_SHARED_PTR
-
-#include <IOKit/IOKernelReportStructs.h>
-#include <IOKit/IOKernelReporters.h>
-#include "IOReporterDefs.h"
-
-#include <string.h>
-#include <sys/param.h>
-#include <IOKit/IORegistryEntry.h>
-
-#define super OSObject
-OSDefineMetaClassAndStructors(IOReporter, OSObject);
-
-static OSSharedPtr<const OSSymbol> gIOReportNoChannelName;
-
-// * We might someday want an IOReportManager (vs. these static funcs)
-
-/**************************************/
-/***         STATIC METHODS         ***/
-/**************************************/
-IOReturn
-IOReporter::configureAllReports(OSSet *reporters,
-    IOReportChannelList *channelList,
-    IOReportConfigureAction action,
-    void *result,
-    void *destination)
-{
-	IOReturn rval = kIOReturnError;
-	OSSharedPtr<OSCollectionIterator> iterator;
-
-	if (reporters == NULL || channelList == NULL || result == NULL) {
-		rval = kIOReturnBadArgument;
-		goto finish;
-	}
-
-	switch (action) {
-	case kIOReportGetDimensions:
-	case kIOReportEnable:
-	case kIOReportDisable:
-	{
-		OSObject * object;
-		iterator = OSCollectionIterator::withCollection(reporters);
-
-		while ((object = iterator->getNextObject())) {
-			IOReporter *rep = OSDynamicCast(IOReporter, object);
-
-			if (rep) {
-				(void)rep->configureReport(channelList, action, result, destination);
-			} else {
-				rval = kIOReturnUnsupported; // kIOReturnNotFound?
-				goto finish;
-			}
-		}
-
-		break;
-	}
-
-	case kIOReportTraceOnChange:
-	case kIOReportNotifyHubOnChange:
-	default:
-		rval = kIOReturnUnsupported;
-		goto finish;
-	}
-
-	rval = kIOReturnSuccess;
-
-finish:
-	return rval;
-}
-
-// the duplication in these functions almost makes one want Objective-C SEL* ;)
-IOReturn
-IOReporter::updateAllReports(OSSet *reporters,
-    IOReportChannelList *channelList,
-    IOReportConfigureAction action,
-    void *result,
-    void *destination)
-{
-	IOReturn rval = kIOReturnError;
-	OSSharedPtr<OSCollectionIterator> iterator;
-
-	if (reporters == NULL ||
-	    channelList == NULL ||
-	    result == NULL ||
-	    destination == NULL) {
-		rval = kIOReturnBadArgument;
-		goto finish;
-	}
-
-	switch (action) {
-	case kIOReportCopyChannelData:
-	{
-		OSObject * object;
-		iterator = OSCollectionIterator::withCollection(reporters);
-
-		while ((object = iterator->getNextObject())) {
-			IOReporter *rep = OSDynamicCast(IOReporter, object);
-
-			if (rep) {
-				(void)rep->updateReport(channelList, action, result, destination);
-			} else {
-				rval = kIOReturnUnsupported; // kIOReturnNotFound?
-				goto finish;
-			}
-		}
-
-		break;
-	}
-
-	case kIOReportTraceChannelData:
-	default:
-		rval = kIOReturnUnsupported;
-		goto finish;
-	}
-
-	rval = kIOReturnSuccess;
-
-finish:
-	return rval;
-}
-
-
-/**************************************/
-/***       COMMON INIT METHODS      ***/
-/**************************************/
-
-bool
-IOReporter::init(IOService *reportingService,
-    IOReportChannelType channelType,
-    IOReportUnit unit)
-{
-	bool success = false;
-
-	// ::free() relies on these being initialized
-	_reporterLock = NULL;
-	_configLock = NULL;
-	_elements = NULL;
-	_enableCounts = NULL;
-	_channelNames = nullptr;
-
-	if (channelType.report_format == kIOReportInvalidFormat) {
-		IORLOG("init ERROR: Channel Type ill-defined");
-		goto finish;
-	}
-
-	_driver_id = reportingService->getRegistryEntryID();
-	if (_driver_id == 0) {
-		IORLOG("init() ERROR: no registry ID");
-		goto finish;
-	}
-
-	if (!super::init()) {
-		return false;
-	}
-
-	if (channelType.nelements > INT16_MAX) {
-		return false;
-	}
-	_channelDimension = channelType.nelements;
-	_channelType = channelType;
-	// FIXME: need to look up dynamically
-	if (unit == kIOReportUnitHWTicks) {
-#if defined(__arm64__)
-		unit = kIOReportUnit24MHzTicks;
-#elif defined(__i386__) || defined(__x86_64__)
-		// Most, but not all Macs use 1GHz
-		unit = kIOReportUnit1GHzTicks;
-#else
-#error kIOReportUnitHWTicks not defined
-#endif
-	}
-	_unit = unit;
-
-	// Allocate a reporter (data) lock
-	_reporterLock = IOSimpleLockAlloc();
-	if (!_reporterLock) {
-		goto finish;
-	}
-	_reporterIsLocked = false;
-
-	// Allocate a config lock
-	_configLock = IOLockAlloc();
-	if (!_configLock) {
-		goto finish;
-	}
-	_reporterConfigIsLocked = false;
-
-	// Allocate channel names array
-	_channelNames = OSArray::withCapacity(1);
-	if (!_channelNames) {
-		goto finish;
-	}
-
-	// success
-	success = true;
-
-finish:
-	return success;
-}
-
-
-/*******************************/
-/***      PUBLIC METHODS     ***/
-/*******************************/
-
-void
-IOReporter::initialize(void)
-{
-	gIOReportNoChannelName = OSSymbol::withCString("_NO_NAME_4");
-}
-
-// init() [possibly via init*()] must be called before free()
-// to ensure that _<var> = NULL
-void
-IOReporter::free(void)
-{
-	if (_configLock) {
-		IOLockFree(_configLock);
-	}
-	if (_reporterLock) {
-		IOSimpleLockFree(_reporterLock);
-	}
-
-	if (_elements) {
-		PREFL_MEMOP_PANIC(_nElements, IOReportElement);
-		IOFreeData(_elements, (size_t)_nElements * sizeof(IOReportElement));
-	}
-	if (_enableCounts) {
-		PREFL_MEMOP_PANIC(_nChannels, int);
-		IOFreeData(_enableCounts, (size_t)_nChannels * sizeof(int));
-	}
-
-	super::free();
-}
-
-/*
- #define TESTALLOC() do { \
- *   void *tbuf;                 \
- *   tbuf = IOMalloc(10);        \
- *   IOFree(tbuf, 10);           \
- *   IORLOG("%s:%d - _reporterIsLocked = %d & allocation successful", \
- *           __PRETTY_FUNCTION__, __LINE__, _reporterIsLocked); \
- *  } while (0);
- */
-IOReturn
-IOReporter::addChannel(uint64_t channelID,
-    const char *channelName /* = NULL */)
-{
-	IOReturn res = kIOReturnError, kerr;
-	OSSharedPtr<const OSSymbol> symChannelName;
-	int oldNChannels, newNChannels = 0, freeNChannels = 0;
-
-	IORLOG("IOReporter::addChannel %llx", channelID);
-
-	// protect instance variables (but not contents)
-	lockReporterConfig();
-
-	// FIXME: Check if any channel is already present and return error
-
-	// addChannel() always adds one channel
-	oldNChannels = _nChannels;
-	if (oldNChannels < 0 || oldNChannels > INT_MAX - 1) {
-		res = kIOReturnOverrun;
-		goto finish;
-	}
-	newNChannels = oldNChannels + 1;
-	freeNChannels = newNChannels;   // until swap success
-
-	// Expand addChannel()-specific data structure
-	if (_channelNames->ensureCapacity((unsigned)newNChannels) <
-	    (unsigned)newNChannels) {
-		res = kIOReturnNoMemory; goto finish;
-	}
-	if (channelName) {
-		symChannelName = OSSymbol::withCString(channelName);
-		if (!symChannelName) {
-			res = kIOReturnNoMemory; goto finish;
-		}
-	} else {
-		// grab a reference to our shared global
-		symChannelName = gIOReportNoChannelName;
-	}
-
-	// allocate new buffers into _swap* variables
-	if ((kerr = handleSwapPrepare(newNChannels))) {
-		// on error, channels are *not* swapped
-		res = kerr; goto finish;
-	}
-
-	// exchange main and _swap* buffers with buffer contents protected
-	// IOReporter::handleAddChannelSwap() also increments _nElements, etc
-	lockReporter();
-	res = handleAddChannelSwap(channelID, symChannelName.get());
-	unlockReporter();
-	// On failure, handleAddChannelSwap() leaves *new* buffers in _swap*.
-	// On success, it's the old buffers, so we put the right size in here.
-	if (res == kIOReturnSuccess) {
-		freeNChannels = oldNChannels;
-	}
-
-finish:
-	// free up not-in-use buffers (tracked by _swap*)
-	handleSwapCleanup(freeNChannels);
-
-	unlockReporterConfig();
-
-	return res;
-}
-
-
-OSSharedPtr<IOReportLegendEntry>
-IOReporter::createLegend(void)
-{
-	OSSharedPtr<IOReportLegendEntry> legendEntry;
-
-	lockReporterConfig();
-
-	legendEntry = handleCreateLegend();
-
-	unlockReporterConfig();
-
-	return legendEntry;
-}
-
-
-IOReturn
-IOReporter::configureReport(IOReportChannelList *channelList,
-    IOReportConfigureAction action,
-    void *result,
-    void *destination)
-{
-	IOReturn res = kIOReturnError;
-
-	lockReporterConfig();
-
-	res = handleConfigureReport(channelList, action, result, destination);
-
-	unlockReporterConfig();
-
-	return res;
-}
-
-
-IOReturn
-IOReporter::updateReport(IOReportChannelList *channelList,
-    IOReportConfigureAction action,
-    void *result,
-    void *destination)
-{
-	IOReturn res = kIOReturnError;
-
-	lockReporter();
-
-	res = handleUpdateReport(channelList, action, result, destination);
-
-	unlockReporter();
-
-	return res;
-}
-
-
-/*******************************/
-/***    PROTECTED METHODS    ***/
-/*******************************/
-
-
-void
-IOReporter::lockReporter()
-{
-	_interruptState = IOSimpleLockLockDisableInterrupt(_reporterLock);
-	_reporterIsLocked = true;
-}
-
-
-void
-IOReporter::unlockReporter()
-{
-	_reporterIsLocked = false;
-	IOSimpleLockUnlockEnableInterrupt(_reporterLock, _interruptState);
-}
-
-void
-IOReporter::lockReporterConfig()
-{
-	IOLockLock(_configLock);
-	_reporterConfigIsLocked = true;
-}
-
-void
-IOReporter::unlockReporterConfig()
-{
-	_reporterConfigIsLocked = false;
-	IOLockUnlock(_configLock);
-}
-
-
-IOReturn
-IOReporter::handleSwapPrepare(int newNChannels)
-{
-	IOReturn res = kIOReturnError;
-	int newNElements;
-	size_t newElementsSize, newECSize;
-
-	// analyzer appeasement
-	newElementsSize = newECSize = 0;
-
-	//IORLOG("IOReporter::handleSwapPrepare");
-
-	IOREPORTER_CHECK_CONFIG_LOCK();
-
-	if (newNChannels < _nChannels) {
-		panic("%s doesn't support shrinking", __func__);
-	}
-	if (newNChannels <= 0 || _channelDimension <= 0) {
-		res = kIOReturnUnderrun;
-		goto finish;
-	}
-	if (_swapElements || _swapEnableCounts) {
-		panic("IOReporter::_swap* already in use");
-	}
-
-	// calculate the number of elements given #ch & the dimension of each
-	if (newNChannels < 0 || newNChannels > INT_MAX / _channelDimension) {
-		res = kIOReturnOverrun;
-		goto finish;
-	}
-	newNElements = newNChannels * _channelDimension;
-
-	// Allocate memory for the new array of report elements
-	PREFL_MEMOP_FAIL(newNElements, IOReportElement);
-	newElementsSize = (size_t)newNElements * sizeof(IOReportElement);
-	_swapElements = (IOReportElement *)IOMallocZeroData(newElementsSize);
-	if (_swapElements == NULL) {
-		res = kIOReturnNoMemory; goto finish;
-	}
-
-	// Allocate memory for the new array of channel watch counts
-	PREFL_MEMOP_FAIL(newNChannels, int);
-	newECSize = (size_t)newNChannels * sizeof(int);
-	_swapEnableCounts = (int *)IOMallocZeroData(newECSize);
-	if (_swapEnableCounts == NULL) {
-		res = kIOReturnNoMemory; goto finish;
-	}
-
-	// success
-	res = kIOReturnSuccess;
-
-finish:
-	if (res) {
-		if (_swapElements) {
-			IOFreeData(_swapElements, newElementsSize);
-			_swapElements = NULL;
-		}
-		if (_swapEnableCounts) {
-			IOFreeData(_swapEnableCounts, newECSize);
-			_swapEnableCounts = NULL;
-		}
-	}
-
-	return res;
-}
-
-
-IOReturn
-IOReporter::handleAddChannelSwap(uint64_t channel_id,
-    const OSSymbol *symChannelName)
-{
-	IOReturn res = kIOReturnError;
-	int cnt;
-	int *tmpWatchCounts = NULL;
-	IOReportElement *tmpElements = NULL;
-	bool swapComplete = false;
-
-	//IORLOG("IOReporter::handleSwap");
-
-	IOREPORTER_CHECK_CONFIG_LOCK();
-	IOREPORTER_CHECK_LOCK();
-
-	if (!_swapElements || !_swapEnableCounts) {
-		IORLOG("IOReporter::handleSwap ERROR swap variables uninitialized!");
-		goto finish;
-	}
-
-	// Copy any existing elements to the new location
-	//IORLOG("handleSwap (base) -> copying %u elements over...", _nChannels);
-	if (_elements) {
-		PREFL_MEMOP_PANIC(_nElements, IOReportElement);
-		memcpy(_swapElements, _elements,
-		    (size_t)_nElements * sizeof(IOReportElement));
-
-		PREFL_MEMOP_PANIC(_nElements, int);
-		memcpy(_swapEnableCounts, _enableCounts,
-		    (size_t)_nChannels * sizeof(int));
-	}
-
-	// Update principal instance variables, keep old buffers for cleanup
-	tmpElements = _elements;
-	_elements = _swapElements;
-	_swapElements = tmpElements;
-
-	tmpWatchCounts = _enableCounts;
-	_enableCounts = _swapEnableCounts;
-	_swapEnableCounts = tmpWatchCounts;
-
-	swapComplete = true;
-
-	// but _nChannels & _nElements is still the old (one smaller) size
-
-	// Initialize new element metadata (existing elements copied above)
-	for (cnt = 0; cnt < _channelDimension; cnt++) {
-		_elements[_nElements + cnt].channel_id = channel_id;
-		_elements[_nElements + cnt].provider_id = _driver_id;
-		_elements[_nElements + cnt].channel_type = _channelType;
-		_elements[_nElements + cnt].channel_type.element_idx = ((int16_t) cnt);
-
-		//IOREPORTER_DEBUG_ELEMENT(_swapNElements + cnt);
-	}
-
-	// Store a channel name at the end
-	if (!_channelNames->setObject((unsigned)_nChannels, symChannelName)) {
-		// Should never happen because we ensured capacity in addChannel()
-		res = kIOReturnNoMemory;
-		goto finish;
-	}
-
-	// And update the metadata: addChannel() always adds just one channel
-	_nChannels += 1;
-	_nElements += _channelDimension;
-
-	// success
-	res = kIOReturnSuccess;
-
-finish:
-	if (res && swapComplete) {
-		// unswap so new buffers get cleaned up instead of old
-		tmpElements = _elements;
-		_elements = _swapElements;
-		_swapElements = tmpElements;
-
-		tmpWatchCounts = _enableCounts;
-		_enableCounts = _swapEnableCounts;
-		_swapEnableCounts = tmpWatchCounts;
-	}
-	return res;
-}
-
-void
-IOReporter::handleSwapCleanup(int swapNChannels)
-{
-	int swapNElements;
-
-	if (!_channelDimension || swapNChannels > INT_MAX / _channelDimension) {
-		panic("%s - can't free %d channels of dimension %d", __func__,
-		    swapNChannels, _channelDimension);
-	}
-	swapNElements = swapNChannels * _channelDimension;
-
-	IOREPORTER_CHECK_CONFIG_LOCK();
-
-	// release buffers no longer used after swapping
-	if (_swapElements) {
-		PREFL_MEMOP_PANIC(swapNElements, IOReportElement);
-		IOFreeData(_swapElements, (size_t)swapNElements * sizeof(IOReportElement));
-		_swapElements = NULL;
-	}
-	if (_swapEnableCounts) {
-		PREFL_MEMOP_PANIC(swapNChannels, int);
-		IOFreeData(_swapEnableCounts, (size_t)swapNChannels * sizeof(int));
-		_swapEnableCounts = NULL;
-	}
-}
-
-
-// The reporter wants to know if its channels have observers.
-// Eventually we'll add some sort of bool ::anyChannelsInUse() which
-// clients can use to cull unused reporters after configureReport(disable).
-IOReturn
-IOReporter::handleConfigureReport(IOReportChannelList *channelList,
-    IOReportConfigureAction action,
-    void *result,
-    void *destination)
-{
-	IOReturn res = kIOReturnError;
-	int channel_index = 0;
-	uint32_t chIdx;
-	int *nElements, *nChannels;
-
-	// Check on channelList and result because used below
-	if (!channelList || !result) {
-		goto finish;
-	}
-
-	//IORLOG("IOReporter::configureReport action %u for %u channels",
-	//       action, channelList->nchannels);
-
-	// Make sure channel is present, increase matching watch count, 'result'
-	for (chIdx = 0; chIdx < channelList->nchannels; chIdx++) {
-		if (getChannelIndex(channelList->channels[chIdx].channel_id,
-		    &channel_index) == kIOReturnSuccess) {
-			// IORLOG("reporter %p recognizes channel %lld", this, channelList->channels[chIdx].channel_id);
-
-			switch (action) {
-			case kIOReportEnable:
-				nChannels = (int*)result;
-				_enabled++;
-				_enableCounts[channel_index]++;
-				(*nChannels)++;
-				break;
-
-			case kIOReportDisable:
-				nChannels = (int*)result;
-				_enabled--;
-				_enableCounts[channel_index]--;
-				(*nChannels)++;
-				break;
-
-			case kIOReportGetDimensions:
-				nElements = (int *)result;
-				*nElements += _channelDimension;
-				break;
-
-			default:
-				IORLOG("ERROR configureReport unknown action!");
-				break;
-			}
-		}
-	}
-
-	// success
-	res = kIOReturnSuccess;
-
-finish:
-	return res;
-}
-
-static const uint32_t UNLOCK_PERIOD = 1 << 5;
-static_assert(powerof2(UNLOCK_PERIOD),
-    "unlock period not a power of 2: period check must be efficient");
-static const uint32_t UNLOCK_PERIOD_MASK = UNLOCK_PERIOD - 1;
-
-IOReturn
-IOReporter::handleUpdateReport(IOReportChannelList *channelList,
-    IOReportConfigureAction action,
-    void *result,
-    void *destination)
-{
-	IOReturn res = kIOReturnError;
-	int *nElements = (int *)result;
-	int channel_index = 0;
-	uint32_t chIdx;
-	IOBufferMemoryDescriptor *dest;
-
-	if (!channelList || !result || !destination) {
-		goto finish;
-	}
-
-	dest = OSDynamicCast(IOBufferMemoryDescriptor, (OSObject *)destination);
-	if (dest == NULL) {
-		// Invalid destination
-		res = kIOReturnBadArgument;
-		goto finish;
-	}
-
-	if (!_enabled) {
-		goto finish;
-	}
-
-	for (chIdx = 0; chIdx < channelList->nchannels; chIdx++) {
-		// Drop the lock periodically to allow reporters to emit data, as they
-		// might be running in interrupt context.
-		//
-		// This is safe because the spinlock is really only protecting the
-		// element array, any other changes to the reporter will need to
-		// take the configuration lock.   Keeping the lock between channels
-		// isn't protecting us from anything, because there's no API to
-		// update multiple channels atomically anyway.
-		if ((chIdx & UNLOCK_PERIOD_MASK) == UNLOCK_PERIOD_MASK) {
-			unlockReporter();
-			delay(1);
-			lockReporter();
-		}
-		if (getChannelIndex(channelList->channels[chIdx].channel_id,
-		    &channel_index) == kIOReturnSuccess) {
-			//IORLOG("%s - found channel_id %llx @ index %d", __func__,
-			//       channelList->channels[chIdx].channel_id,
-			//       channel_index);
-
-			switch (action) {
-			case kIOReportCopyChannelData:
-				res = updateChannelValues(channel_index);
-				if (res) {
-					IORLOG("ERROR: updateChannelValues() failed: %x", res);
-					goto finish;
-				}
-
-				res = updateReportChannel(channel_index, nElements, dest);
-				if (res) {
-					IORLOG("ERROR: updateReportChannel() failed: %x", res);
-					goto finish;
-				}
-				break;
-
-			default:
-				IORLOG("ERROR updateReport unknown action!");
-				res = kIOReturnError;
-				goto finish;
-			}
-		}
-	}
-
-	// success
-	res = kIOReturnSuccess;
-
-finish:
-	return res;
-}
-
-
-OSSharedPtr<IOReportLegendEntry>
-IOReporter::handleCreateLegend(void)
-{
-	OSSharedPtr<IOReportLegendEntry> legendEntry = nullptr;
-	OSSharedPtr<OSArray> channelIDs;
-
-	channelIDs = copyChannelIDs();
-
-	if (channelIDs) {
-		legendEntry = IOReporter::legendWith(channelIDs.get(), _channelNames.get(), _channelType, _unit);
-	}
-
-	return legendEntry;
-}
-
-
-IOReturn
-IOReporter::setElementValues(int element_index,
-    IOReportElementValues *values,
-    uint64_t record_time /* = 0 */)
-{
-	IOReturn res = kIOReturnError;
-
-	IOREPORTER_CHECK_LOCK();
-
-	if (record_time == 0) {
-		record_time = mach_absolute_time();
-	}
-
-	if (element_index >= _nElements || values == NULL) {
-		res = kIOReturnBadArgument;
-		goto finish;
-	}
-
-	memcpy(&_elements[element_index].values, values, sizeof(IOReportElementValues));
-
-	_elements[element_index].timestamp = record_time;
-
-	//IOREPORTER_DEBUG_ELEMENT(index);
-
-	res = kIOReturnSuccess;
-
-finish:
-	return res;
-}
-
-
-const IOReportElementValues*
-IOReporter::getElementValues(int element_index)
-{
-	IOReportElementValues *elementValues = NULL;
-
-	IOREPORTER_CHECK_LOCK();
-
-	if (element_index < 0 || element_index >= _nElements) {
-		IORLOG("ERROR getElementValues out of bounds!");
-		goto finish;
-	}
-
-	elementValues = &_elements[element_index].values;
-
-finish:
-	return elementValues;
-}
-
-
-IOReturn
-IOReporter::updateChannelValues(int channel_index)
-{
-	return kIOReturnSuccess;
-}
-
-
-IOReturn
-IOReporter::updateReportChannel(int channel_index,
-    int *nElements,
-    IOBufferMemoryDescriptor *destination)
-{
-	IOReturn res = kIOReturnError;
-	int start_element_idx, chElems;
-	size_t       size2cpy;
-
-	res = kIOReturnBadArgument;
-	if (!nElements || !destination) {
-		goto finish;
-	}
-	if (channel_index > _nChannels) {
-		goto finish;
-	}
-
-	IOREPORTER_CHECK_LOCK();
-
-	res = kIOReturnOverrun;
-
-	start_element_idx = channel_index * _channelDimension;
-	if (start_element_idx >= _nElements) {
-		goto finish;
-	}
-
-	chElems = _elements[start_element_idx].channel_type.nelements;
-
-	// make sure we don't go beyond the end of _elements[_nElements-1]
-	if (start_element_idx + chElems > _nElements) {
-		goto finish;
-	}
-
-	PREFL_MEMOP_FAIL(chElems, IOReportElement);
-	size2cpy = (size_t)chElems * sizeof(IOReportElement);
-
-	// make sure there's space in the destination
-	if (size2cpy > (destination->getCapacity() - destination->getLength())) {
-		IORLOG("CRITICAL ERROR: Report Buffer Overflow (buffer cap %luB, length %luB, size2cpy %luB",
-		    (unsigned long)destination->getCapacity(),
-		    (unsigned long)destination->getLength(),
-		    (unsigned long)size2cpy);
-		goto finish;
-	}
-
-	destination->appendBytes(&_elements[start_element_idx], size2cpy);
-	*nElements += chElems;
-
-	res = kIOReturnSuccess;
-
-finish:
-	return res;
-}
-
-
-IOReturn
-IOReporter::copyElementValues(int element_index,
-    IOReportElementValues *elementValues)
-{
-	IOReturn res = kIOReturnError;
-
-	if (!elementValues) {
-		goto finish;
-	}
-
-	IOREPORTER_CHECK_LOCK();
-
-	if (element_index >= _nElements) {
-		IORLOG("ERROR getElementValues out of bounds!");
-		res = kIOReturnBadArgument;
-		goto finish;
-	}
-
-	memcpy(elementValues, &_elements[element_index].values, sizeof(IOReportElementValues));
-	res = kIOReturnSuccess;
-
-finish:
-	return res;
-}
-
-
-IOReturn
-IOReporter::getFirstElementIndex(uint64_t channel_id,
-    int *index)
-{
-	IOReturn res = kIOReturnError;
-	int channel_index = 0, element_index = 0;
-
-	if (!index) {
-		goto finish;
-	}
-
-	res = getChannelIndices(channel_id, &channel_index, &element_index);
-
-	if (res == kIOReturnSuccess) {
-		*index = element_index;
-	}
-
-finish:
-	return res;
-}
-
-
-IOReturn
-IOReporter::getChannelIndex(uint64_t channel_id,
-    int *index)
-{
-	IOReturn res = kIOReturnError;
-	int channel_index = 0, element_index = 0;
-
-	if (!index) {
-		goto finish;
-	}
-
-	res = getChannelIndices(channel_id, &channel_index, &element_index);
-
-	if (res == kIOReturnSuccess) {
-		*index = channel_index;
-	}
-
-finish:
-	return res;
-}
-
-
-IOReturn
-IOReporter::getChannelIndices(uint64_t channel_id,
-    int *channel_index,
-    int *element_index)
-{
-	IOReturn res = kIOReturnNotFound;
-	int chIdx, elemIdx;
-
-	if (!channel_index || !element_index) {
-		goto finish;
-	}
-
-	for (chIdx = 0; chIdx < _nChannels; chIdx++) {
-		elemIdx = chIdx * _channelDimension;
-		if (elemIdx >= _nElements) {
-			IORLOG("ERROR getChannelIndices out of bounds!");
-			res = kIOReturnOverrun;
-			goto finish;
-		}
-
-		if (channel_id == _elements[elemIdx].channel_id) {
-			// The channel index does not care about the depth of elements...
-			*channel_index = chIdx;
-			*element_index = elemIdx;
-
-			res = kIOReturnSuccess;
-			goto finish;
-		}
-	}
-
-finish:
-	return res;
-}
-
-/********************************/
-/***      PRIVATE METHODS     ***/
-/********************************/
-
-
-// copyChannelIDs relies on the caller to take lock
-OSSharedPtr<OSArray>
-IOReporter::copyChannelIDs()
-{
-	int    cnt, cnt2;
-	OSSharedPtr<OSArray>    channelIDs;
-	OSSharedPtr<OSNumber>   tmpNum;
-
-	channelIDs = OSArray::withCapacity((unsigned)_nChannels);
-
-	if (!channelIDs) {
-		return nullptr;
-	}
-
-	for (cnt = 0; cnt < _nChannels; cnt++) {
-		cnt2 = cnt * _channelDimension;
-
-		// Encapsulate the Channel ID in OSNumber
-		tmpNum = OSNumber::withNumber(_elements[cnt2].channel_id, 64);
-		if (!tmpNum) {
-			IORLOG("ERROR: Could not create array of channelIDs");
-			return nullptr;
-		}
-
-		channelIDs->setObject((unsigned)cnt, tmpNum.get());
-		tmpNum.reset();
-	}
-
-	return channelIDs;
-}
-
-
-// DO NOT REMOVE THIS METHOD WHICH IS THE MAIN LEGEND CREATION FUNCTION
-/*static */ OSPtr<IOReportLegendEntry>
-IOReporter::legendWith(OSArray *channelIDs,
-    OSArray *channelNames,
-    IOReportChannelType channelType,
-    IOReportUnit unit)
-{
-	unsigned int            cnt, chCnt;
-	uint64_t                type64;
-	OSSharedPtr<OSNumber>   tmpNum;
-	const OSSymbol          *tmpSymbol;
-	OSSharedPtr<OSArray>    channelLegendArray;
-	OSSharedPtr<OSArray>    tmpChannelArray;
-	OSSharedPtr<OSDictionary> channelInfoDict;
-	OSSharedPtr<IOReportLegendEntry> legendEntry = nullptr;
-
-	// No need to check validity of channelNames because param is optional
-	if (!channelIDs) {
-		goto finish;
-	}
-	chCnt = channelIDs->getCount();
-
-	channelLegendArray = OSArray::withCapacity(chCnt);
-
-	for (cnt = 0; cnt < chCnt; cnt++) {
-		tmpChannelArray = OSArray::withCapacity(3);
-
-		// Encapsulate the Channel ID in OSNumber
-		tmpChannelArray->setObject(kIOReportChannelIDIdx, channelIDs->getObject(cnt));
-
-		// Encapsulate the Channel Type in OSNumber
-		memcpy(&type64, &channelType, sizeof(type64));
-		tmpNum = OSNumber::withNumber(type64, 64);
-		if (!tmpNum) {
-			goto finish;
-		}
-		tmpChannelArray->setObject(kIOReportChannelTypeIdx, tmpNum.get());
-		tmpNum.reset();
-
-		// Encapsulate the Channel Name in OSSymbol
-		// Use channelNames if provided
-		if (channelNames != NULL) {
-			tmpSymbol = OSDynamicCast(OSSymbol, channelNames->getObject(cnt));
-			if (tmpSymbol && tmpSymbol != gIOReportNoChannelName) {
-				tmpChannelArray->setObject(kIOReportChannelNameIdx, tmpSymbol);
-			} // Else, skip and leave name field empty
-		}
-
-		channelLegendArray->setObject(cnt, tmpChannelArray.get());
-		tmpChannelArray.reset();
-	}
-
-	// Stuff the legend entry only if we have channels...
-	if (channelLegendArray->getCount() != 0) {
-		channelInfoDict = OSDictionary::withCapacity(1);
-
-		if (!channelInfoDict) {
-			goto finish;
-		}
-
-		tmpNum = OSNumber::withNumber(unit, 64);
-		if (tmpNum) {
-			channelInfoDict->setObject(kIOReportLegendUnitKey, tmpNum.get());
-		}
-
-		legendEntry = OSDictionary::withCapacity(1);
-
-		if (legendEntry) {
-			legendEntry->setObject(kIOReportLegendChannelsKey, channelLegendArray.get());
-			legendEntry->setObject(kIOReportLegendInfoKey, channelInfoDict.get());
-		}
-	}
-
-finish:
-	return legendEntry;
-}
-
-/*static */ OSPtr<IOReportLegendEntry>
-IOReporter::legendWith(const uint64_t *channelIDs,
-    const char **channelNames,
-    int channelCount,
-    IOReportChannelType channelType,
-    IOReportUnit unit)
-{
-	OSSharedPtr<OSArray>            channelIDsArray;
-	OSSharedPtr<OSArray>            channelNamesArray;
-	OSSharedPtr<OSNumber>           channelID;
-	OSSharedPtr<const OSSymbol>     channelName;
-	int                             cnt;
-
-	channelIDsArray = OSArray::withCapacity(channelCount);
-	channelNamesArray = OSArray::withCapacity(channelCount);
-	if (!channelIDsArray || !channelNamesArray) {
-		return nullptr;
-	}
-
-	for (cnt = 0; cnt < channelCount; cnt++) {
-		channelID = OSNumber::withNumber(*channelIDs++, 64);
-		const char *name = *channelNames++;
-		if (name) {
-			channelName = OSSymbol::withCString(name);
-		} else {
-			// grab a reference to our shared global
-			channelName = gIOReportNoChannelName;
-		}
-		if (!channelID || !channelName) {
-			return nullptr;
-		}
-		if (!channelIDsArray->setObject(cnt, channelID) ||
-		    !channelNamesArray->setObject(cnt, channelName)) {
-			return nullptr;
-		}
-	}
-
-	return legendWith(channelIDsArray.get(), channelNamesArray.get(), channelType, unit);
-}