/* * Copyright (c) 2021 Apple 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@ */ #ifndef _IOKIT_UIOWORKGROUP_H #define _IOKIT_UIOWORKGROUP_H #include #include enum { kIOWorkGroupMaxNameLength = 64, }; /*! * @class IOWorkGroup * * @abstract * Workgroups allow multiple threads to coordinate activities for realtime operations. * * @discussion * * Applications that open user clients to a DriverKit driver can send a workgroup to use in the driver. * * The application will have to first create an workgroup object. The application then should copy the * workgroup port with os_workgroup_copy_port(). To send the workgroup port to the driver, use: * * const char * name = "Work Group Name"; // This must match the name the driver used in IOWorkGroup::Create(). * kern_return_t ret = IOConnectTrap3(connect, // user client connection (io_connect_t) * 1, // specifies event link configuration trap * (uintptr_t)name, * (uintptr_t)strlen(name), * (uintptr_t)wgPort // port from os_workgroup_copy_port * ); * * Once the workgroup port has been sent to the driver, the driver should be notified with a user-defined external method * or other existing signaling mechanism. */ class NATIVE KERNEL IOWorkGroup : public OSObject { public: virtual bool init() override; virtual void free() override; /*! * @brief Create an IOWorkGroup object. This object is not functional until a workgroup port has been set. * @param name Name of the workgroup * @param userClient Userclient to create the workgroup in. The DriverKit runtime will retain the userclient, and will * release it in Invalidate() or when the IOWorkGroup is freed. * @param workgroup Created IOWorkGroup with +1 retain count to be released by the caller. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ static kern_return_t Create(OSString * name, IOUserClient * userClient, IOWorkGroup ** workgroup) LOCAL; #if DRIVERKIT_PRIVATE /*! * @brief Set the port for this workgroup. This should not be called directly. * @param port Workgroup port * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ virtual kern_return_t SetWorkGroupPort(mach_port_t port PORTCOPYSEND) LOCAL; #endif /* DRIVERKIT_PRIVATE */ /*! * @brief Get the size of the workgroup token. * @discussion Join() and Leave() require the caller to pass a token. This token should be allocated by the caller, and freed when * no longer needed. Use this method to determine how much memory to allocate for the token. * @return Workgroup token size */ size_t GetTokenSize() LOCALONLY; /*! * @brief Join the workgroup. * @discussion Before calling this method, the caller must allocate a token. This token must be passed to this method. When leaving * a workgroup with Leave(), use the same token that was passed to Join(). * @param token The workgroup token. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ kern_return_t Join(void * token) LOCALONLY; /*! * @brief Leave the workgroup. * @discussion The workgroup must have been joined with Join(). Use the same token in Join() for this method. * @param token The workgroup token. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ kern_return_t Leave(void * token) LOCALONLY; /*! * @brief Invalidate the IOWorkGroup. * @discussion This releases the kernel reference to the IOWorkGroup, allowing the name to be used for a different * IOWorkGroup. This method should be called after the client has configured the eventlink with the IOConnectTrap * call. After invalidation, the IOWorkGroup can no longer be configured through the IOConnectTrap call. No other * functionality is affected. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ kern_return_t Invalidate() LOCALONLY; #if DRIVERKIT_PRIVATE virtual kern_return_t InvalidateKernel(IOUserClient * client); #endif /* DRIVERKIT_PRIVATE */ }; #endif /* ! _IOKIT_UIOWORKGROUP_H */