1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
30 *
31 * HISTORY
32 *
33 */
34
35
36#ifndef _IOKIT_IOCATALOGUE_H
37#define _IOKIT_IOCATALOGUE_H
38
39#include <libkern/c++/OSObject.h>
40#include <libkern/c++/OSCollectionIterator.h>
41#include <libkern/c++/OSArray.h>
42#include <libkern/c++/OSDictionary.h>
43#include <IOKit/IOLocks.h>
44#include <sys/cdefs.h>
45
46#include <IOKit/IOKitServer.h>
47
48class IOService;
49
50/*!
51    @class IOCatalogue
52    @abstract In-kernel database for IOKit driver personalities.
53    @discussion The IOCatalogue is a database which contains all IOKit driver personalities.  IOService uses this resource when matching devices to their associated drivers.
54*/
55class IOCatalogue : public OSObject
56{
57    OSDeclareDefaultStructors(IOCatalogue)
58
59private:
60    OSCollectionIterator   * kernelTables;
61    OSArray                * array;
62    IOLock *                 lock;
63    SInt32                   generation;
64
65    IOLock *                 kld_lock;
66
67public:
68    /*!
69        @function initialize
70        @abstract Creates and initializes the database object and poputates it with in-kernel driver personalities.
71    */
72    static void initialize( void );
73
74    /*!
75        @function init
76        @abstract Initializes the database object.
77        @param initArray  The initial array of driver personalities to populate the database.
78    */
79    bool init( OSArray * initArray );
80
81    /*!
82        @function free
83        @abstract Cleans up the database and deallocates memory allocated at initialization.  This is never called in normal operation of the system.
84    */
85    void free( void );
86
87    /*!
88        @function findDrivers
89        @abstract This is the primary entry point for IOService.
90        @param service
91        @param generationCount  Returns a reference to the generation count of the database. The generation count increases only when personalities are added to the database *and* IOService matching has been initiated.
92        @result Returns an ordered set of driver personalities ranked on probe-scores.  The ordered set must be released by the receiver.
93    */
94    OSOrderedSet * findDrivers( IOService * service, SInt32 * generationCount );
95
96    /*!
97        @function findDrivers
98        @abstract A more general purpose interface which allows one to retreive driver personalities based the intersection of the 'matching' dictionary and the personality's own property list.
99        @param matching  A dictionary containing only keys and values which are to be used for matching. For example, a matching dictionary containing 'IOProviderClass'='IOPCIDevice' will return all personalities with an IOProviderClass key and a value of IOPCIDevice.
100        @param generationCount  Returns a reference to the current generation of the database. The generation count increases only when personalities are added to the database *and* IOService matching has been initiated.
101        @result Returns an ordered set of driver personalities ranked on probe-scores. The ordered set must be released by the receiver.
102    */
103    OSOrderedSet * findDrivers( OSDictionary * matching, SInt32 * generationCount );
104
105    /*!
106        @function addDrivers
107        @abstract Adds an array of driver personalities to the database.
108        @param array Array of driver personalities to be added to the database.
109        @param doNubMatchng Start matching process after personalities have been added.
110        @result Returns true if driver personality was added to the database successfully. Failure is due to a memory allocation failure.
111    */
112    bool addDrivers( OSArray * array, bool doNubMatching = true );
113
114    /*!
115        @function removeDrivers
116        @abstract Remove driver personalities from the database based on matching information provided.
117        @param matching  A dictionary whose keys and values are used for matching personalities in the database.  For example, a matching dictionary containing a 'IOProviderClass' key with the value 'IOPCIDevice' will remove all personalities which have the key 'IOProviderClass' equal to 'IOPCIDevice'.
118        @param doNubMatchng Start matching process after personalities have been removed.  Matching criteria is based on IOProviderClass of those personalities which were removed.  This is to allow drivers which haven't been matched to match against NUB's which were blocked by the previous personalities.
119        @result Returns true if personality was removed successfully. Failure is due to a memory allocation failure.
120    */
121    bool removeDrivers( OSDictionary * matching, bool doNubMatching = true );
122
123    /*!
124        @function getGenerationCount
125        @abstract Get the current generation count of the database.
126    */
127    SInt32 getGenerationCount( void ) const;
128
129    /*!
130        @function isModuleLoaded
131        @abstract Reports if a kernel module has been loaded.
132        @param moduleName  Name of the module.
133        @result Returns true if the associated kernel module has been loaded into the kernel.
134    */
135    bool isModuleLoaded( OSString * moduleName ) const;
136
137    /*!
138        @function isModuleLoaded
139        @abstract Reports if a kernel module has been loaded.
140        @param moduleName  Name of the module.
141        @result Returns true if the associated kernel module has been loaded into the kernel.
142    */
143    bool isModuleLoaded( const char * moduleName ) const;
144
145    /*!
146        @function isModuleLoaded
147        @abstract Reports if a kernel module has been loaded for a particular personality.
148        @param driver  A driver personality's property list.
149        @result Returns true if the associated kernel module has been loaded into the kernel for a particular driver personality on which it depends.
150    */
151    bool isModuleLoaded( OSDictionary * driver ) const;
152
153    /*!
154        @function moduleHasLoaded
155        @abstract Callback function called after a IOKit dependent kernel module is loaded.
156        @param name  Name of the kernel module.
157    */
158    void moduleHasLoaded( OSString * name );
159
160    /*!
161        @function moduleHasLoaded
162        @abstract Callback function called after a IOKit dependent kernel module is loaded.
163        @param name  Name of the kernel module.
164    */
165    void moduleHasLoaded( const char * name );
166
167    /*!
168        @function terminateDrivers
169        @abstract Terminates all instances of a driver which match the contents of the matching dictionary. Does not unload module.
170        @param matching  A dictionary whose keys and values are used for matching personalities in the database.  For example, a matching dictionary containing a 'IOProviderClass' key with the value 'IOPCIDevice' will cause termination for all instances whose personalities have the key 'IOProviderClass' equal to 'IOPCIDevice'.
171     */
172    IOReturn terminateDrivers( OSDictionary * matching );
173
174    /*!
175        @function terminateDriversForModule
176        @abstract Terminates all instances of a driver which depends on a particular module and unloads the module.
177        @param moduleName Name of the module which is used to determine which driver instances to terminate and unload.
178        @param unload Flag to cause the actual unloading of the module.
179     */
180    IOReturn terminateDriversForModule( OSString * moduleName, bool unload = true);
181
182    /*!
183        @function terminateDriversForModule
184        @abstract Terminates all instances of a driver which depends on a particular module and unloads the module.
185        @param moduleName Name of the module which is used to determine which driver instances to terminate and unload.
186        @param unload Flag to cause the actual unloading of the module.
187     */
188    IOReturn terminateDriversForModule( const char * moduleName, bool unload = true);
189
190    /*!
191        @function startMatching
192        @abstract Starts an IOService matching thread where matching keys and values are provided by the matching dictionary.
193        @param matching  A dictionary whose keys and values are used for matching personalities in the database.  For example, a matching dictionary containing a 'IOProviderClass' key with the value 'IOPCIDevice' will start matching for all personalities which have the key 'IOProviderClass' equal to 'IOPCIDevice'.
194     */
195    bool startMatching( OSDictionary * matching );
196
197    /*!
198        @function reset
199        @abstract Return the Catalogue to its initial state.
200    */
201    void reset(void);
202
203    /*!
204        @function serialize
205        @abstract Serializes the catalog for transport to the user.
206        @param s The serializer object.
207        @result Returns false if unable to serialize database, most likely due to memory shortage.
208     */
209    virtual bool serialize(OSSerialize * s) const;
210
211    bool serializeData(IOOptionBits kind, OSSerialize * s) const;
212
213    /*!
214        @function recordStartupExtensions
215        @abstract Records extensions made available by the primary booter.
216            <p>
217            This function is for internal use by the kernel startup linker.
218            Kernel extensions should never call it.
219        @result Returns true if startup extensions were successfully recorded,
220            false if not.
221    */
222    virtual bool recordStartupExtensions(void);
223
224    /*!
225        @function addExtensionsFromArchive()
226        @abstract Records an archive of extensions, as from device ROM.
227            <p>
228            This function is currently for internal use.
229            Kernel extensions should never call it.
230        @param mkext An OSData object containing a multikext archive.
231        @result Returns true if mkext was properly unserialized and its
232                contents recorded, false if not.
233    */
234    virtual bool addExtensionsFromArchive(OSData * mkext);
235
236
237    /*!
238        @function removeKernelLinker
239        @abstract Removes from memory all code and data related to
240            boot-time loading of kernel extensions. kextd triggers
241            this when it first starts in order to pass responsibility
242            for loading extensions from the kernel itself to kextd.
243        @result Returns KERN_SUCCESS if the kernel linker is successfully
244            removed or wasn't present, KERN_FAILURE otherwise.
245    */
246    virtual kern_return_t removeKernelLinker(void);
247
248    static void disableExternalLinker(void);
249
250private:
251
252    /*!
253        @function unloadModule
254        @abstract Unloads the reqested module if no driver instances are currently depending on it.
255        @param moduleName An OSString containing the name of the module to unload.
256     */
257    IOReturn unloadModule( OSString * moduleName ) const;
258};
259
260__BEGIN_DECLS
261/*!
262    @function IOKitRelocStart
263    @abstract Deprecated API.
264*/
265kmod_start_func_t IOKitRelocStart;
266/*!
267    @function IOKitRelocStop
268    @abstract Deprecated API.
269*/
270kmod_stop_func_t IOKitRelocStop;
271__END_DECLS
272
273extern const OSSymbol *		gIOClassKey;
274extern const OSSymbol *		gIOProbeScoreKey;
275extern IOCatalogue *            gIOCatalogue;
276
277#endif /* ! _IOKIT_IOCATALOGUE_H */
278