1e13b1fa5SApple OSS Distributions /* 2a5e72196SApple OSS Distributions * Copyright (c) 1998-2019 Apple Inc. All rights reserved. 3e13b1fa5SApple OSS Distributions * 4e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5e13b1fa5SApple OSS Distributions * 6e13b1fa5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7e13b1fa5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8e13b1fa5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9e13b1fa5SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10e13b1fa5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11e13b1fa5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12e13b1fa5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13e13b1fa5SApple OSS Distributions * terms of an Apple operating system software license agreement. 14e13b1fa5SApple OSS Distributions * 15e13b1fa5SApple OSS Distributions * Please obtain a copy of the License at 16e13b1fa5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17e13b1fa5SApple OSS Distributions * 18e13b1fa5SApple OSS Distributions * The Original Code and all software distributed under the License are 19e13b1fa5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20e13b1fa5SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21e13b1fa5SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22e13b1fa5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23e13b1fa5SApple OSS Distributions * Please see the License for the specific language governing rights and 24e13b1fa5SApple OSS Distributions * limitations under the License. 25e13b1fa5SApple OSS Distributions * 26e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27e13b1fa5SApple OSS Distributions */ 28e13b1fa5SApple OSS Distributions 29e13b1fa5SApple OSS Distributions #ifndef _IOKIT_IOSHAREDDATAQUEUE_H 30e13b1fa5SApple OSS Distributions #define _IOKIT_IOSHAREDDATAQUEUE_H 31e13b1fa5SApple OSS Distributions 32a3bb9fccSApple OSS Distributions #define DISABLE_DATAQUEUE_WARNING /* IODataQueue is deprecated, please use IOSharedDataQueue instead */ 33a3bb9fccSApple OSS Distributions 34e13b1fa5SApple OSS Distributions #include <IOKit/IODataQueue.h> 35bb611c8fSApple OSS Distributions #include <libkern/c++/OSPtr.h> 36e13b1fa5SApple OSS Distributions 37a3bb9fccSApple OSS Distributions #undef DISABLE_DATAQUEUE_WARNING 38a3bb9fccSApple OSS Distributions 39e13b1fa5SApple OSS Distributions typedef struct _IODataQueueEntry IODataQueueEntry; 40e13b1fa5SApple OSS Distributions 41e13b1fa5SApple OSS Distributions /*! 42e13b1fa5SApple OSS Distributions * @class IOSharedDataQueue : public IODataQueue 43e13b1fa5SApple OSS Distributions * @abstract A generic queue designed to pass data both from the kernel to a user process and from a user process to the kernel. 44e13b1fa5SApple OSS Distributions * @discussion The IOSharedDataQueue class is designed to also allow a user process to queue data to kernel code. IOSharedDataQueue objects are designed to be used in a single producer / single consumer situation. As such, there are no locks on the data itself. Because the kernel enqueue and user-space dequeue methods follow a strict set of guidelines, no locks are necessary to maintain the integrity of the data struct. 45e13b1fa5SApple OSS Distributions * 46e13b1fa5SApple OSS Distributions * <br>Each data entry can be variable sized, but the entire size of the queue data region (including overhead for each entry) must be specified up front. 47e13b1fa5SApple OSS Distributions * 48e13b1fa5SApple OSS Distributions * <br>In order for the IODataQueue instance to notify the user process that data is available, a notification mach port must be set. When the queue is empty and a new entry is added, a message is sent to the specified port. 49e13b1fa5SApple OSS Distributions * 50e13b1fa5SApple OSS Distributions * <br>In order to make the data queue memory available to a user process, the method getMemoryDescriptor() must be used to get an IOMemoryDescriptor instance that can be mapped into a user process. Typically, the clientMemoryForType() method on an IOUserClient instance will be used to request the IOMemoryDescriptor and then return it to be mapped into the user process. 51e13b1fa5SApple OSS Distributions */ 52e13b1fa5SApple OSS Distributions class IOSharedDataQueue : public IODataQueue 53e13b1fa5SApple OSS Distributions { 54a5e72196SApple OSS Distributions OSDeclareDefaultStructors(IOSharedDataQueue); 55e13b1fa5SApple OSS Distributions 56e13b1fa5SApple OSS Distributions struct ExpansionData { 57a3bb9fccSApple OSS Distributions UInt32 queueSize; 58e13b1fa5SApple OSS Distributions }; 59e13b1fa5SApple OSS Distributions /*! @var reserved 60a5e72196SApple OSS Distributions * Reserved for future use. (Internal use only) */ 61e13b1fa5SApple OSS Distributions ExpansionData * _reserved; 62e13b1fa5SApple OSS Distributions 63e13b1fa5SApple OSS Distributions protected: 640f3703acSApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE; 65e13b1fa5SApple OSS Distributions 66a3bb9fccSApple OSS Distributions /*! 67a3bb9fccSApple OSS Distributions * @function getQueueSize 68a3bb9fccSApple OSS Distributions * @abstract Returns the size of the data queue. 69a3bb9fccSApple OSS Distributions * @discussion Use this method to access the size of the data queue. Do not access the value of size directly, as it can get modified from userspace and is not reliable. 70a3bb9fccSApple OSS Distributions * @result Returns the size of the data queue, or zero in case of failure. 71a3bb9fccSApple OSS Distributions */ 72a3bb9fccSApple OSS Distributions UInt32 getQueueSize(); 73a3bb9fccSApple OSS Distributions 74a3bb9fccSApple OSS Distributions /*! 75a3bb9fccSApple OSS Distributions * @function setQueueSize 76a3bb9fccSApple OSS Distributions * @abstract Stores the value of the size of the data queue. 77a3bb9fccSApple OSS Distributions * @discussion Use this method to store the value of the size of the data queue. Do not access the value of size directly, as it can get modified from userspace and is not reliable. 78a3bb9fccSApple OSS Distributions * @param size The size of the data queue. 79a3bb9fccSApple OSS Distributions * @result Returns true in case of success, false otherwise. 80a3bb9fccSApple OSS Distributions */ 81a3bb9fccSApple OSS Distributions Boolean setQueueSize(UInt32 size); 82a3bb9fccSApple OSS Distributions 83e13b1fa5SApple OSS Distributions public: 84e13b1fa5SApple OSS Distributions /*! 85e13b1fa5SApple OSS Distributions * @function withCapacity 86e13b1fa5SApple OSS Distributions * @abstract Static method that creates a new IOSharedDataQueue instance with the capacity specified in the size parameter. 87e13b1fa5SApple OSS Distributions * @discussion The actual size of the entire data queue memory region (to be shared into a user process) is equal to the capacity plus the IODataQueueMemory overhead. This overhead value can be determined from the DATA_QUEUE_MEMORY_HEADER_SIZE macro in <IOKit/IODataQueueShared.h>. The size of the data queue memory region must include space for the overhead of each IODataQueueEntry. This entry overhead can be determined from the DATA_QUEUE_ENTRY_HEADER_SIZE macro in <IOKit/IODataQueueShared.h>.<br> This method allocates a new IODataQueue instance and then calls initWithCapacity() with the given size parameter. If the initWithCapacity() fails, the new instance is released and zero is returned. 88e13b1fa5SApple OSS Distributions * @param size The size of the data queue memory region. 89e13b1fa5SApple OSS Distributions * @result Returns the newly allocated IOSharedDataQueue instance. Zero is returned on failure. 90e13b1fa5SApple OSS Distributions */ 91*8d741a5dSApple OSS Distributions static OSPtr<IOSharedDataQueue> withCapacity(UInt32 size __xnu_data_size); 92e13b1fa5SApple OSS Distributions 93e13b1fa5SApple OSS Distributions /*! 94e13b1fa5SApple OSS Distributions * @function withEntries 95e13b1fa5SApple OSS Distributions * @abstract Static method that creates a new IOSharedDataQueue instance with the specified number of entries of the given size. 96e13b1fa5SApple OSS Distributions * @discussion This method will create a new IOSharedDataQueue instance with enough capacity for numEntries of entrySize. It does account for the IODataQueueEntry overhead for each entry. Note that the numEntries and entrySize are simply used to determine the data region size. They do not actually restrict the size of number of entries that can be added to the queue.<br> This method allocates a new IODataQueue instance and then calls initWithEntries() with the given numEntries and entrySize parameters. If the initWithEntries() fails, the new instance is released and zero is returned. 97e13b1fa5SApple OSS Distributions * @param numEntries Number of entries to allocate space for. 98e13b1fa5SApple OSS Distributions * @param entrySize Size of each entry. 99e13b1fa5SApple OSS Distributions * @result Reeturns the newly allocated IOSharedDataQueue instance. Zero is returned on failure. 100e13b1fa5SApple OSS Distributions */ 101*8d741a5dSApple OSS Distributions static OSPtr<IOSharedDataQueue> withEntries(UInt32 numEntries, UInt32 entrySize __xnu_data_size); 102e13b1fa5SApple OSS Distributions 103e13b1fa5SApple OSS Distributions /*! 104e13b1fa5SApple OSS Distributions * @function initWithCapacity 105e13b1fa5SApple OSS Distributions * @abstract Initializes an IOSharedDataQueue instance with the capacity specified in the size parameter. 106e13b1fa5SApple OSS Distributions * @discussion The actual size of the entire data queue memory region (to be shared into a user process) is equal to the capacity plus the IODataQueueMemory overhead. This overhead value can be determined from the DATA_QUEUE_MEMORY_HEADER_SIZE and DATA_QUEUE_MEMORY_APPENDIX_SIZE macro in <IOKit/IODataQueueShared.h>. The size of the data queue memory region must include space for the overhead of each IODataQueueEntry. This entry overhead can be determined from the DATA_QUEUE_ENTRY_HEADER_SIZE macro in <IOKit/IODataQueueShared.h>. 107e13b1fa5SApple OSS Distributions * @param size The size of the data queue memory region. 108e13b1fa5SApple OSS Distributions * @result Returns true on success and false on failure. 109e13b1fa5SApple OSS Distributions */ 1100f3703acSApple OSS Distributions virtual Boolean initWithCapacity(UInt32 size) APPLE_KEXT_OVERRIDE; 111e13b1fa5SApple OSS Distributions 112e13b1fa5SApple OSS Distributions /*! 113e13b1fa5SApple OSS Distributions * @function getMemoryDescriptor 114e13b1fa5SApple OSS Distributions * @abstract Returns a memory descriptor covering the IODataQueueMemory region. 115e13b1fa5SApple OSS Distributions * @discussion The IOMemoryDescriptor instance returned by this method is intended to be mapped into a user process. This is the memory region that the IODataQueueClient code operates on. 116e13b1fa5SApple OSS Distributions * @result Returns a newly allocated IOMemoryDescriptor for the IODataQueueMemory region. Returns zero on failure. 117e13b1fa5SApple OSS Distributions */ 118bb611c8fSApple OSS Distributions virtual OSPtr<IOMemoryDescriptor> getMemoryDescriptor() APPLE_KEXT_OVERRIDE; 119e13b1fa5SApple OSS Distributions 120e13b1fa5SApple OSS Distributions /*! 121e13b1fa5SApple OSS Distributions * @function peek 122e13b1fa5SApple OSS Distributions * @abstract Used to peek at the next entry on the queue. 123e13b1fa5SApple OSS Distributions * @discussion This function can be used to look at the next entry which allows the entry to be received without having to copy it with dequeue. In order to do this, call peek to get the entry. Then call dequeue with a NULL data pointer. That will cause the head to be moved to the next entry, but no memory to be copied. 124e13b1fa5SApple OSS Distributions * @result Returns a pointer to the next IODataQueueEntry if one is available. 0 (NULL) is returned if the queue is empty. 125e13b1fa5SApple OSS Distributions */ 126e13b1fa5SApple OSS Distributions virtual IODataQueueEntry * peek(); 127e13b1fa5SApple OSS Distributions 128e13b1fa5SApple OSS Distributions /*! 129e13b1fa5SApple OSS Distributions * @function dequeue 130e13b1fa5SApple OSS Distributions * @abstract Dequeues the next available entry on the queue and copies it into the given data pointer. 131e13b1fa5SApple OSS Distributions * @discussion This function will dequeue the next available entry on the queue. If a data pointer is provided, it will copy the data into the memory region if there is enough space available as specified in the dataSize parameter. If no data pointer is provided, it will simply move the head value past the current entry. 132e13b1fa5SApple OSS Distributions * @param data A pointer to the data memory region in which to copy the next entry data on the queue. If this parameter is 0 (NULL), it will simply move to the next entry. 133e13b1fa5SApple OSS Distributions * @param dataSize A pointer to the size of the data parameter. On return, this contains the size of the actual entry data - even if the original size was not large enough. 134e13b1fa5SApple OSS Distributions * @result Returns true on success and false on failure. Typically failure means that the queue is empty. 135e13b1fa5SApple OSS Distributions */ 136e13b1fa5SApple OSS Distributions virtual Boolean dequeue(void *data, UInt32 *dataSize); 137e13b1fa5SApple OSS Distributions 138a3bb9fccSApple OSS Distributions /*! 139a3bb9fccSApple OSS Distributions * @function enqueue 140a3bb9fccSApple OSS Distributions * @abstract Enqueues a new entry on the queue. 141a3bb9fccSApple OSS Distributions * @discussion This method adds a new data entry of dataSize to the queue. It sets the size parameter of the entry pointed to by the tail value and copies the memory pointed to by the data parameter in place in the queue. Once that is done, it moves the tail to the next available location. When attempting to add a new entry towards the end of the queue and there isn't enough space at the end, it wraps back to the beginning.<br> If the queue is empty when a new entry is added, sendDataAvailableNotification() is called to send a message to the user process that data is now available. 142a3bb9fccSApple OSS Distributions * @param data Pointer to the data to be added to the queue. 143a3bb9fccSApple OSS Distributions * @param dataSize Size of the data pointed to by data. 144a3bb9fccSApple OSS Distributions * @result Returns true on success and false on failure. Typically failure means that the queue is full. 145a3bb9fccSApple OSS Distributions */ 1460f3703acSApple OSS Distributions virtual Boolean enqueue(void *data, UInt32 dataSize) APPLE_KEXT_OVERRIDE; 147a3bb9fccSApple OSS Distributions 148cc9a6355SApple OSS Distributions #ifdef PRIVATE 149cc9a6355SApple OSS Distributions /* workaround for queue.h redefine, please do not use */ 150a5e72196SApple OSS Distributions __inline__ Boolean enqueue_tail(void * data,UInt32 dataSize)151a5e72196SApple OSS Distributions enqueue_tail(void *data, UInt32 dataSize) 152a5e72196SApple OSS Distributions { 153a5e72196SApple OSS Distributions return IOSharedDataQueue::enqueue(data, dataSize); 154a5e72196SApple OSS Distributions } 155cc9a6355SApple OSS Distributions #endif 156cc9a6355SApple OSS Distributions 157cc9a6355SApple OSS Distributions #if APPLE_KEXT_VTABLE_PADDING 158e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 0); 159e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 1); 160e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 2); 161e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 3); 162e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 4); 163e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 5); 164e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 6); 165e13b1fa5SApple OSS Distributions OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 7); 166cc9a6355SApple OSS Distributions #endif 167e13b1fa5SApple OSS Distributions }; 168e13b1fa5SApple OSS Distributions 169e13b1fa5SApple OSS Distributions #endif /* _IOKIT_IOSHAREDDATAQUEUE_H */ 170