1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23
24#ifndef _IOKIT_IOPCIDEVICE_H
25#define _IOKIT_IOPCIDEVICE_H
26
27#include <IOKit/IOTypes.h>
28
29/* Definitions of PCI Config Registers */
30enum {
31    kIOPCIConfigVendorID                = 0x00,
32    kIOPCIConfigDeviceID                = 0x02,
33    kIOPCIConfigCommand                 = 0x04,
34    kIOPCIConfigStatus                  = 0x06,
35    kIOPCIConfigRevisionID              = 0x08,
36    kIOPCIConfigClassCode               = 0x09,
37    kIOPCIConfigCacheLineSize           = 0x0C,
38    kIOPCIConfigLatencyTimer            = 0x0D,
39    kIOPCIConfigHeaderType              = 0x0E,
40    kIOPCIConfigBIST                    = 0x0F,
41    kIOPCIConfigBaseAddress0            = 0x10,
42    kIOPCIConfigBaseAddress1            = 0x14,
43    kIOPCIConfigBaseAddress2            = 0x18,
44    kIOPCIConfigBaseAddress3            = 0x1C,
45    kIOPCIConfigBaseAddress4            = 0x20,
46    kIOPCIConfigBaseAddress5            = 0x24,
47    kIOPCIConfigCardBusCISPtr           = 0x28,
48    kIOPCIConfigSubSystemVendorID       = 0x2C,
49    kIOPCIConfigSubSystemID             = 0x2E,
50    kIOPCIConfigExpansionROMBase        = 0x30,
51    kIOPCIConfigCapabilitiesPtr         = 0x34,
52    kIOPCIConfigInterruptLine           = 0x3C,
53    kIOPCIConfigInterruptPin            = 0x3D,
54    kIOPCIConfigMinimumGrant            = 0x3E,
55    kIOPCIConfigMaximumLatency          = 0x3F
56};
57
58/* Definitions of Capabilities PCI Config Register */
59enum {
60    kIOPCICapabilityIDOffset            = 0x00,
61    kIOPCINextCapabilityOffset          = 0x01,
62
63    kIOPCIPowerManagementCapability     = 0x01,
64    kIOPCIAGPCapability                 = 0x02,
65    kIOPCIVitalProductDataCapability    = 0x03,
66    kIOPCISlotIDCapability              = 0x04,
67    kIOPCIMSICapability                 = 0x05,
68    kIOPCICPCIHotswapCapability         = 0x06,
69    kIOPCIPCIXCapability                = 0x07,
70    kIOPCILDTCapability                 = 0x08,
71    kIOPCIVendorSpecificCapability      = 0x09,
72    kIOPCIDebugPortCapability           = 0x0a,
73    kIOPCICPCIResourceControlCapability = 0x0b,
74    kIOPCIHotplugCapability             = 0x0c,
75    kIOPCIAGP8Capability                = 0x0e,
76    kIOPCISecureCapability              = 0x0f,
77    kIOPCIPCIExpressCapability          = 0x10,
78    kIOPCIMSIXCapability                = 0x11,
79
80    kIOPCIExpressErrorReportingCapability            = -0x01UL,
81    kIOPCIExpressVirtualChannelCapability            = -0x02UL,
82    kIOPCIExpressDeviceSerialNumberCapability        = -0x03UL,
83    kIOPCIExpressPowerBudgetCapability               = -0x04UL,
84    kIOPCIExpressLatencyTolerenceReportingCapability = -0x18UL,
85    kIOPCIExpressL1PMSubstatesCapability             = -0x1EUL,
86};
87
88/* Space definitions */
89enum {
90    kIOPCIConfigSpace           = 0,
91    kIOPCIIOSpace               = 1,
92    kIOPCI32BitMemorySpace      = 2,
93    kIOPCI64BitMemorySpace      = 3
94};
95
96/* Command register definitions */
97enum {
98    kIOPCICommandIOSpace                = 0x0001,
99    kIOPCICommandMemorySpace            = 0x0002,
100    kIOPCICommandBusMaster              = 0x0004,
101    kIOPCICommandSpecialCycles          = 0x0008,
102    kIOPCICommandMemWrInvalidate        = 0x0010,
103    kIOPCICommandPaletteSnoop           = 0x0020,
104    kIOPCICommandParityError            = 0x0040,
105    kIOPCICommandAddressStepping        = 0x0080,
106    kIOPCICommandSERR                   = 0x0100,
107    kIOPCICommandFastBack2Back          = 0x0200,
108    kIOPCICommandInterruptDisable       = 0x0400
109};
110
111/* Status register definitions */
112enum {
113	kIOPCIStatusInterrupt				= 0x0008,
114    kIOPCIStatusCapabilities            = 0x0010,
115    kIOPCIStatusPCI66                   = 0x0020,
116    kIOPCIStatusUDF                     = 0x0040,
117    kIOPCIStatusFastBack2Back           = 0x0080,
118    kIOPCIStatusDevSel0                 = 0x0000,
119    kIOPCIStatusDevSel1                 = 0x0200,
120    kIOPCIStatusDevSel2                 = 0x0400,
121    kIOPCIStatusDevSel3                 = 0x0600,
122    kIOPCIStatusTargetAbortCapable      = 0x0800,
123    kIOPCIStatusTargetAbortActive       = 0x1000,
124    kIOPCIStatusMasterAbortActive       = 0x2000,
125    kIOPCIStatusSERRActive              = 0x4000,
126    kIOPCIStatusParityErrActive         = 0x8000
127};
128
129enum {
130    kPCI2PCIPrimaryBus          = 0x18,
131    kPCI2PCISecondaryBus        = 0x19,
132    kPCI2PCISubordinateBus      = 0x1a,
133    kPCI2PCISecondaryLT         = 0x1b,
134    kPCI2PCIIORange             = 0x1c,
135    kPCI2PCIMemoryRange         = 0x20,
136    kPCI2PCIPrefetchMemoryRange = 0x24,
137    kPCI2PCIPrefetchUpperBase   = 0x28,
138    kPCI2PCIPrefetchUpperLimit  = 0x2c,
139    kPCI2PCIUpperIORange        = 0x30,
140    kPCI2PCIBridgeControl       = 0x3e
141};
142
143// constants which are part of the PCI Bus Power Management Spec.
144enum
145{
146    // capabilities bits in the 16 bit capabilities register
147    kPCIPMCPMESupportFromD3Cold = 0x8000,
148    kPCIPMCPMESupportFromD3Hot  = 0x4000,
149    kPCIPMCPMESupportFromD2             = 0x2000,
150    kPCIPMCPMESupportFromD1             = 0x1000,
151    kPCIPMCPMESupportFromD0             = 0x0800,
152    kPCIPMCD2Support                    = 0x0400,
153    kPCIPMCD1Support                    = 0x0200,
154
155    kPCIPMCD3Support                    = 0x0001
156};
157
158enum
159{
160    // bits in the power management control/status register
161    kPCIPMCSPMEStatus                   = 0x8000,
162    kPCIPMCSPMEEnable                   = 0x0100,
163    kPCIPMCSPowerStateMask              = 0x0003,
164    kPCIPMCSPowerStateD3                = 0x0003,
165    kPCIPMCSPowerStateD2                = 0x0002,
166    kPCIPMCSPowerStateD1                = 0x0001,
167    kPCIPMCSPowerStateD0                = 0x0000,
168
169    kPCIPMCSDefaultEnableBits           = (~(IOOptionBits)0)
170};
171
172union IOPCIAddressSpace {
173    UInt32              bits;
174    struct {
175#if __BIG_ENDIAN__
176        unsigned int    reloc:1;
177        unsigned int    prefetch:1;
178        unsigned int    t:1;
179        unsigned int    resv:3;
180        unsigned int    space:2;
181        unsigned int    busNum:8;
182        unsigned int    deviceNum:5;
183        unsigned int    functionNum:3;
184        unsigned int    registerNum:8;
185#elif __LITTLE_ENDIAN__
186        unsigned int    registerNum:8;
187        unsigned int    functionNum:3;
188        unsigned int    deviceNum:5;
189        unsigned int    busNum:8;
190        unsigned int    space:2;
191        unsigned int    resv:3;
192        unsigned int    t:1;
193        unsigned int    prefetch:1;
194        unsigned int    reloc:1;
195#endif
196    } s;
197    struct {
198#if __BIG_ENDIAN__
199        unsigned int    resv:4;
200        unsigned int    registerNumExtended:4;
201        unsigned int    busNum:8;
202        unsigned int    deviceNum:5;
203        unsigned int    functionNum:3;
204        unsigned int    registerNum:8;
205#elif __LITTLE_ENDIAN__
206        unsigned int    registerNum:8;
207        unsigned int    functionNum:3;
208        unsigned int    deviceNum:5;
209        unsigned int    busNum:8;
210        unsigned int    registerNumExtended:4;
211        unsigned int    resv:4;
212#endif
213    } es;
214};
215typedef union IOPCIAddressSpace IOPCIAddressSpace;
216
217struct IOPCIPhysicalAddress {
218    IOPCIAddressSpace   physHi;
219#if defined(__i386__) || defined(__x86_64__)
220    UInt32              physMid;
221    UInt32              physLo;
222    UInt32              lengthHi;
223    UInt32              lengthLo;
224#else
225    UInt32              physLo;
226    UInt32              physMid;
227    UInt32              lengthLo;
228    UInt32              lengthHi;
229#endif
230};
231
232// IOPCIDevice matching property names
233#define kIOPCIMatchKey                  "IOPCIMatch"
234#define kIOPCIPrimaryMatchKey           "IOPCIPrimaryMatch"
235#define kIOPCISecondaryMatchKey         "IOPCISecondaryMatch"
236#define kIOPCIClassMatchKey             "IOPCIClassMatch"
237#define kIOPCITunnelCompatibleKey       "IOPCITunnelCompatible"
238#define kIOPCITunnelledKey 		  		"IOPCITunnelled"
239#define kIOPCITunnelL1EnableKey	  		"IOPCITunnelL1Enable"
240
241#define kIOPCIPauseCompatibleKey        "IOPCIPauseCompatible"
242
243// property to control PCI default config space save on sleep
244#define kIOPMPCIConfigSpaceVolatileKey  "IOPMPCIConfigSpaceVolatile"
245// property to disable express link on sleep
246#define kIOPMPCISleepLinkDisableKey     "IOPMPCISleepLinkDisable"
247// property to reset secondary bus on sleep
248#define kIOPMPCISleepResetKey           "IOPMPCISleepReset"
249
250// pci express capabilities
251#define kIOPCIExpressCapabilitiesKey       "IOPCIExpressCapabilities"
252// pci express link status
253#define kIOPCIExpressLinkStatusKey       "IOPCIExpressLinkStatus"
254// pci express link capabilities
255#define kIOPCIExpressLinkCapabilitiesKey "IOPCIExpressLinkCapabilities"
256// pci express slot status
257#define kIOPCIExpressSlotStatusKey       "IOPCIExpressSlotStatus"
258// pci express slot capabilities
259#define kIOPCIExpressSlotCapabilitiesKey "IOPCIExpressSlotCapabilities"
260
261#ifndef kIOPlatformDeviceASPMEnableKey
262#define kIOPlatformDeviceASPMEnableKey  "IOPlatformDeviceASPMEnable"
263#endif
264
265#ifndef kIOPCIDeviceASPMSupportedKey
266#define kIOPCIDeviceASPMSupportedKey    "pci-aspm-supported"
267#endif
268
269#define kIOPCIPMEOptionsKey             "IOPCIPMEOptions"
270
271#define kIOPCITunnelIDKey               "IOPCITunnelID"
272#define kIOPCITunnelControllerIDKey     "IOPCITunnelControllerID"
273
274#define kIOPCIBridgeInterruptESKey      "IOPCIBridgeInterruptES"
275
276enum {
277    kIOPCIDevicePowerStateCount = 4,
278    kIOPCIDeviceOffState        = 0,
279    kIOPCIDeviceDozeState       = 1,
280    kIOPCIDeviceOnState         = 2,
281    kIOPCIDevicePausedState     = 3,
282};
283
284enum
285{
286    // bits getInterruptType result
287    kIOInterruptTypePCIMessaged = 0x00010000
288};
289
290// setLatencyTolerance options
291enum
292{
293    kIOPCILatencySnooped   = 0x00000001,
294    kIOPCILatencyUnsnooped = 0x00000002,
295};
296
297enum
298{
299    kIOPCIProbeOptionDone      = 0x80000000,
300
301    kIOPCIProbeOptionEject     = 0x00100000,
302    kIOPCIProbeOptionNeedsScan = 0x00200000,
303};
304
305#if defined(KERNEL)
306
307#include <IOKit/IOService.h>
308#include <IOKit/IOEventSource.h>
309
310class IOPCIDevice;
311class IOPCIBridge;
312class IOPCI2PCIBridge;
313class IOPCIMessagedInterruptController;
314class IOPCIConfigurator;
315class IOPCIEventSource;
316
317
318// IOPCIEvent.event
319enum
320{
321    kIOPCIEventCorrectableError = 1,
322    kIOPCIEventNonFatalError    = 2,
323    kIOPCIEventFatalError       = 3,
324    kIOPCIEventLinkEnableChange = 4,
325};
326
327struct IOPCIEvent
328{
329    IOPCIDevice * reporter;
330    uint32_t      event;
331    uint32_t      data[5];
332};
333
334class IOPCIEventSource : public IOEventSource
335{
336    friend class IOPCIBridge;
337    friend class IOPCI2PCIBridge;
338
339    OSDeclareDefaultStructors(IOPCIEventSource);
340public:
341    typedef void (*Action)(OSObject * owner, IOPCIEventSource * es,
342                           const IOPCIEvent * event );
343#define IOPCIEventAction IOPCIEventSource::Action
344
345private:
346    queue_chain_t     fQ;
347    IOPCI2PCIBridge * fRoot;
348    IOPCIDevice *     fDevice;
349    uint8_t           fReadIndex;
350    uint8_t           fWriteIndex;
351    IOPCIEvent *      fEvents;
352
353public:
354    virtual void enable();
355    virtual void disable();
356
357protected:
358    virtual void free(void);
359    virtual bool checkForWork(void);
360};
361
362
363typedef IOReturn (*IOPCIDeviceConfigHandler)(void * ref,
364                                                IOMessage message, IOPCIDevice * device, uint32_t state);
365
366/*! @class IOPCIDevice : public IOService
367    @abstract An IOService class representing a PCI device.
368    @discussion The discovery of a PCI device by the PCI bus family results in an instance of the IOPCIDevice being created and published. It provides services for looking up and mapping memory mapped hardware, and access to the PCI configuration and I/O spaces.
369
370<br><br>Matching Supported by IOPCIDevice<br><br>
371
372Two types of matching are available, OpenFirmware name matching and PCI register matching. Currently, only one of these two matching schemes can be used in the same property table.
373
374<br><br>OpenFirmware Name Matching<br><br>
375
376IOService performs matching based on the IONameMatch property (see IOService). IOPCIDevices created with OpenFirmware device tree entries will name match based on the standard OpenFirmware name matching properties.
377
378<br><br>PCI Register Matching<br><br>
379
380A PCI device driver can also match on the values of certain config space registers.
381
382In each case, several matching values can be specified, and an optional mask for the value of the config space register may follow the value, preceded by an '&' character.
383<br>
384<br>
385        kIOPCIMatchKey, "IOPCIMatch"
386<br>
387The kIOPCIMatchKey property matches the vendor and device ID (0x00) register, or the subsystem register (0x2c).
388<br>
389<br>
390        kIOPCIPrimaryMatchKey, "IOPCIPrimaryMatch"
391<br>
392The kIOPCIPrimaryMatchKey property matches the vendor and device ID (0x00) register.
393<br>
394<br>
395        kIOPCISecondaryMatchKey, "IOPCISecondaryMatch"
396<br>
397The kIOPCISecondaryMatchKey property matches the subsystem register (0x2c).
398<br>
399<br>
400        kIOPCIClassMatchKey, "IOPCIClassMatch"
401<br>
402The kIOPCIClassMatchKey property matches the class code register (0x08). The default mask for this register is 0xffffff00.
403<br>
404<br>
405Examples:
406<br>
407<br>
408      &ltkey&gtIOPCIMatch&lt/key&gt             <br>
409        &ltstring&gt0x00261011&lt/string&gt
410<br>
411Matches a device whose vendor ID is 0x1011, and device ID is 0x0026, including subsystem IDs.
412<br>
413<br>
414      &ltkey&gtIOPCIMatch&lt/key&gt             <br>
415        &ltstring&gt0x00789004&0x00ffffff 0x78009004&0x0xff00ffff&lt/string&gt
416<br>
417Matches with any device with a vendor ID of 0x9004, and a device ID of 0xzz78 or 0x78zz, where 'z' is don't care.
418<br>
419<br>
420      &ltkey&gtIOPCIClassMatch&lt/key&gt        <br>
421        &ltstring&gt0x02000000&0xffff0000&lt/string&gt
422<br>
423<br>
424Matches a device whose class code is 0x0200zz, an ethernet device.
425
426*/
427
428class IOPCIDevice : public IOService
429{
430    OSDeclareDefaultStructors(IOPCIDevice)
431
432    friend class IOPCIBridge;
433    friend class IOPCI2PCIBridge;
434    friend class IOPCIMessagedInterruptController;
435    friend class IOPCIConfigurator;
436
437protected:
438    IOPCIBridge *       parent;
439    IOMemoryMap *       ioMap;
440    OSObject *          slotNameProperty;
441
442/*! @var reserved
443    Reserved for future use.  (Internal use only)  */
444    struct IOPCIDeviceExpansionData * reserved;
445
446public:
447    IOPCIAddressSpace   space;
448    UInt32      *       savedConfig;
449
450public:
451    /* IOService/IORegistryEntry methods */
452
453    virtual bool init( OSDictionary *  propTable );
454    virtual bool init( IORegistryEntry * from,
455                                const IORegistryPlane * inPlane );
456    virtual void free();
457    virtual bool attach( IOService * provider );
458    virtual void detach( IOService * provider );
459	virtual void detachAbove(const IORegistryPlane *);
460
461    virtual IOReturn newUserClient( task_t owningTask, void * securityID,
462                                    UInt32 type,  OSDictionary * properties,
463                                    IOUserClient ** handler );
464
465    virtual IOReturn requestProbe( IOOptionBits options );
466
467    virtual IOReturn powerStateWillChangeTo (IOPMPowerFlags  capabilities,
468                                             unsigned long   stateNumber,
469                                             IOService*      whatDevice);
470    virtual IOReturn setPowerState( unsigned long, IOService * );
471
472	virtual unsigned long maxCapabilityForDomainState ( IOPMPowerFlags domainState );
473	virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags domainState );
474	virtual unsigned long powerStateForDomainState ( IOPMPowerFlags domainState );
475
476    virtual bool compareName( OSString * name, OSString ** matched = 0 ) const;
477    virtual bool matchPropertyTable( OSDictionary *     table,
478                                     SInt32       *     score );
479    virtual IOService * matchLocation( IOService * client );
480    virtual IOReturn getResources( void );
481    virtual IOReturn setProperties(OSObject * properties);
482    virtual IOReturn callPlatformFunction(const OSSymbol * functionName,
483                                          bool waitForFunction,
484                                          void * p1, void * p2,
485                                          void * p3, void * p4);
486    virtual IOReturn callPlatformFunction(const char * functionName,
487                                          bool waitForFunction,
488                                          void * p1, void * p2,
489                                          void * p3, void * p4);
490    virtual IODeviceMemory * getDeviceMemoryWithIndex(unsigned int index);
491
492private:
493	bool configAccess(bool write);
494	bool initReserved(void);
495    IOReturn setPCIPowerState(uint8_t powerState, uint32_t options);
496    void     updateWakeReason(uint16_t pmeState);
497    IOReturn enableLTR(IOPCIDevice * device, bool enable);
498
499public:
500
501    /* Config space accessors */
502
503    virtual UInt32 configRead32( IOPCIAddressSpace space, UInt8 offset );
504    virtual void configWrite32( IOPCIAddressSpace space,
505                                        UInt8 offset, UInt32 data );
506    virtual UInt16 configRead16( IOPCIAddressSpace space, UInt8 offset );
507    virtual void configWrite16( IOPCIAddressSpace space,
508                                        UInt8 offset, UInt16 data );
509    virtual UInt8 configRead8( IOPCIAddressSpace space, UInt8 offset );
510    virtual void configWrite8( IOPCIAddressSpace space,
511                                        UInt8 offset, UInt8 data );
512
513#if __IOPCIDEVICE_INTERNAL__
514
515#if APPLE_KEXT_VTABLE_PADDING
516    virtual UInt32 configRead32( UInt8 offset );
517    virtual UInt16 configRead16( UInt8 offset );
518    virtual UInt8  configRead8( UInt8 offset );
519    virtual void   configWrite32( UInt8 offset, UInt32 data );
520    virtual void   configWrite16( UInt8 offset, UInt16 data );
521    virtual void   configWrite8( UInt8 offset, UInt8 data );
522#endif /* APPLE_KEXT_VTABLE_PADDING */
523
524#else /* !__IOPCIDEVICE_INTERNAL__ */
525
526/*! @function configRead32
527    @abstract Reads a 32-bit value from the PCI device's configuration space.
528    @discussion This method reads a 32-bit configuration space register on the device and returns its value.
529    @param offset An offset into configuration space, of which bits 0-1 are ignored.
530    @result An 32-bit value in host byte order (big endian on PPC). */
531
532    UInt32 configRead32( IOByteCount offset ) { return (extendedConfigRead32(offset)); }
533
534/*! @function configRead16
535    @abstract Reads a 16-bit value from the PCI device's configuration space.
536    @discussion This method reads a 16-bit configuration space register on the device and returns its value.
537    @param offset An offset into configuration space, of which bit 0 is ignored.
538    @result An 16-bit value in host byte order (big endian on PPC). */
539
540    UInt16 configRead16( IOByteCount offset ) { return (extendedConfigRead16(offset)); }
541
542/*! @function configRead8
543    @abstract Reads a 8-bit value from the PCI device's configuration space.
544    @discussion This method reads a 8-bit configuration space register on the device and returns its value.
545    @param offset An offset into configuration space.
546    @result An 8-bit value. */
547
548    UInt8 configRead8( IOByteCount offset ) { return (extendedConfigRead8(offset)); }
549
550/*! @function configWrite32
551    @abstract Writes a 32-bit value to the PCI device's configuration space.
552    @discussion This method write a 32-bit value to a configuration space register on the device.
553    @param offset An offset into configuration space, of which bits 0-1 are ignored.
554    @param data An 32-bit value to be written in host byte order (big endian on PPC). */
555
556    void configWrite32( IOByteCount offset, UInt32 data ) { return (extendedConfigWrite32(offset, data)); }
557
558/*! @function configWrite16
559    @abstract Writes a 16-bit value to the PCI device's configuration space.
560    @discussion This method write a 16-bit value to a configuration space register on the device.
561    @param offset An offset into configuration space, of which bit 0 is ignored.
562    @param data An 16-bit value to be written in host byte order (big endian on PPC). */
563
564    void configWrite16( IOByteCount offset, UInt16 data ) { return (extendedConfigWrite16(offset, data)); }
565
566/*! @function configWrite8
567    @abstract Writes a 8-bit value to the PCI device's configuration space.
568    @discussion This method write a 8-bit value to a configuration space register on the device.
569    @param offset An offset into configuration space.
570    @param data An 8-bit value to be written. */
571
572    void configWrite8( IOByteCount offset, UInt8 data ) { return (extendedConfigWrite8(offset, data)); }
573
574    OSMetaClassDeclareReservedUnused(IOPCIDevice,  16);
575    OSMetaClassDeclareReservedUnused(IOPCIDevice,  17);
576    OSMetaClassDeclareReservedUnused(IOPCIDevice,  18);
577    OSMetaClassDeclareReservedUnused(IOPCIDevice,  19);
578    OSMetaClassDeclareReservedUnused(IOPCIDevice,  20);
579    OSMetaClassDeclareReservedUnused(IOPCIDevice,  21);
580public:
581
582#endif /* !__IOPCIDEVICE_INTERNAL__ */
583
584    virtual IOReturn saveDeviceState( IOOptionBits options = 0 );
585    virtual IOReturn restoreDeviceState( IOOptionBits options = 0 );
586
587/*! @function setConfigBits
588    @abstract Sets masked bits in a configuration space register.
589    @discussion This method sets masked bits in a configuration space register on the device by reading and writing the register. The value of the masked bits before the write is returned.
590    @param offset An 8-bit offset into configuration space, of which bits 0-1 are ignored.
591    @param mask An 32-bit mask indicating which bits in the value parameter are valid.
592    @param data An 32-bit value to be written in host byte order (big endian on PPC).
593    @result The value of the register masked with the mask before the write. */
594
595    virtual UInt32 setConfigBits( UInt8 offset, UInt32 mask, UInt32 value );
596
597/*! @function setMemoryEnable
598    @abstract Sets the device's memory space response.
599    @discussion This method sets the memory space response bit in the device's command config space register to the passed value, and returns the previous state of the enable.
600    @param enable True or false to enable or disable the memory space response.
601    @result True if the memory space response was previously enabled, false otherwise. */
602
603    virtual bool setMemoryEnable( bool enable );
604
605/*! @function setIOEnable
606    @abstract Sets the device's I/O space response.
607    @discussion This method sets the I/O space response bit in the device's command config space register to the passed value, and returns the previous state of the enable. The exclusive option allows only one exclusive device on the bus to be enabled concurrently, this should be only for temporary access.
608    @param enable True or false to enable or disable the I/O space response.
609    @param exclusive If true, only one setIOEnable with the exclusive flag set will be allowed at a time on the bus, this should be only for temporary access.
610    @result True if the I/O space response was previously enabled, false otherwise. */
611
612    virtual bool setIOEnable( bool enable, bool exclusive = false );
613
614/*! @function setBusMasterEnable
615    @abstract Sets the device's bus master enable.
616    @discussion This method sets the bus master enable bit in the device's command config space register to the passed value, and returns the previous state of the enable.
617    @param enable True or false to enable or disable bus mastering.
618    @result True if bus mastering was previously enabled, false otherwise. */
619
620    virtual bool setBusMasterEnable( bool enable );
621
622/*! @function findPCICapability
623    @abstract Search configuration space for a PCI capability register.
624    @discussion This method searches the device's config space for a PCI capability register matching the passed capability ID, if the device supports PCI capabilities. To search for PCI Express extended capabilities or for multiple capablities with the same ID, use the extendedFindPCICapability() method.
625    @param capabilityID An 8-bit PCI capability ID.
626    @param offset An optional pointer to return the offset into config space where the capability was found.
627    @result The 32-bit value of the capability register if one was found, zero otherwise. */
628
629    virtual UInt32 findPCICapability( UInt8 capabilityID, UInt8 * offset = 0 );
630
631/*! @function getBusNumber
632    @abstract Accessor to return the PCI device's assigned bus number.
633    @discussion This method is an accessor to return the PCI device's assigned bus number.
634    @result The 8-bit value of device's PCI bus number. */
635
636    virtual UInt8 getBusNumber( void );
637
638/*! @function getDeviceNumber
639    @abstract Accessor to return the PCI device's device number.
640    @discussion This method is an accessor to return the PCI device's device number.
641    @result The 5-bit value of device's device number. */
642
643    virtual UInt8 getDeviceNumber( void );
644
645/*! @function getFunctionNumber
646    @abstract Accessor to return the PCI device's function number.
647    @discussion This method is an accessor to return the PCI device's function number.
648    @result The 3-bit value of device's function number. */
649
650    virtual UInt8 getFunctionNumber( void );
651
652    /* Device memory accessors */
653
654/*! @function getDeviceMemoryWithRegister
655    @abstract Returns an instance of IODeviceMemory representing one of the device's memory mapped ranges.
656    @discussion This method will return a pointer to an instance of IODeviceMemory for the physical memory range that was assigned to the configuration space base address register passed in. It is analogous to IOService::getDeviceMemoryWithIndex.
657    @param reg The 8-bit configuration space register that is the base address register for the desired range.
658    @result A pointer to an instance of IODeviceMemory, or zero no such range was found. The IODeviceMemory is retained by the provider, so is valid while attached, or while any mappings to it exist. It should not be released by the caller. */
659
660    virtual IODeviceMemory * getDeviceMemoryWithRegister( UInt8 reg );
661
662/*! @function mapDeviceMemoryWithRegister
663    @abstract Maps a physical range of the device.
664    @discussion This method will create a mapping for the IODeviceMemory for the physical memory range that was assigned to the configuration space base address register passed in, with IODeviceMemory::map(options). The mapping is represented by the returned instance of IOMemoryMap, which should not be released until the mapping is no longer required. This method is analogous to IOService::mapDeviceMemoryWithIndex.
665    @param reg The 8-bit configuration space register that is the base address register for the desired range.
666    @param options Options to be passed to the IOMemoryDescriptor::map() method.
667    @result An instance of IOMemoryMap, or zero if the index is beyond the count available. The mapping should be released only when access to it is no longer required. */
668
669    virtual IOMemoryMap * mapDeviceMemoryWithRegister( UInt8 reg,
670                                                IOOptionBits options = 0 );
671
672/*! @function ioDeviceMemory
673    @abstract Accessor to the I/O space aperture for the bus.
674    @discussion This method will return a reference to the IODeviceMemory for the I/O aperture of the bus the device is on.
675    @result A pointer to an IODeviceMemory object for the I/O aperture. The IODeviceMemory is retained by the provider, so is valid while attached, or while any mappings to it exist. It should not be released by the caller. */
676
677    virtual IODeviceMemory * ioDeviceMemory( void );
678
679    /* I/O space accessors */
680
681/*! @function ioWrite32
682    @abstract Writes a 32-bit value to an I/O space aperture.
683    @discussion This method will write a 32-bit value to a 4 byte aligned offset in an I/O space aperture. If a map object is passed in, the value is written relative to it, otherwise to the value is written relative to the I/O space aperture for the bus. This function encapsulates the differences between architectures in generating I/O space operations. An eieio instruction is included on PPC.
684    @param offset An offset into a bus or device's I/O space aperture.
685    @param value The value to be written in host byte order (big endian on PPC).
686    @param map If the offset is relative to the beginning of a device's aperture, an IOMemoryMap object for that object should be passed in. Otherwise, passing zero will write the value relative to the beginning of the bus' I/O space. */
687
688    virtual void ioWrite32( UInt16 offset, UInt32 value,
689                                IOMemoryMap * map = 0 );
690
691/*! @function ioWrite16
692    @abstract Writes a 16-bit value to an I/O space aperture.
693    @discussion This method will write a 16-bit value to a 2 byte aligned offset in an I/O space aperture. If a map object is passed in, the value is written relative to it, otherwise to the value is written relative to the I/O space aperture for the bus. This function encapsulates the differences between architectures in generating I/O space operations. An eieio instruction is included on PPC.
694    @param offset An offset into a bus or device's I/O space aperture.
695    @param value The value to be written in host byte order (big endian on PPC).
696    @param map If the offset is relative to the beginning of a device's aperture, an IOMemoryMap object for that object should be passed in. Otherwise, passing zero will write the value relative to the beginning of the bus' I/O space. */
697
698    virtual void ioWrite16( UInt16 offset, UInt16 value,
699                                IOMemoryMap * map = 0 );
700
701/*! @function ioWrite8
702    @abstract Writes a 8-bit value to an I/O space aperture.
703    @discussion This method will write a 8-bit value to an offset in an I/O space aperture. If a map object is passed in, the value is written relative to it, otherwise to the value is written relative to the I/O space aperture for the bus. This function encapsulates the differences between architectures in generating I/O space operations. An eieio instruction is included on PPC.
704    @param offset An offset into a bus or device's I/O space aperture.
705    @param value The value to be written in host byte order (big endian on PPC).
706    @param map If the offset is relative to the beginning of a device's aperture, an IOMemoryMap object for that object should be passed in. Otherwise, passing zero will write the value relative to the beginning of the bus' I/O space. */
707
708    virtual void ioWrite8( UInt16 offset, UInt8 value,
709                                IOMemoryMap * map = 0 );
710
711/*! @function ioRead32
712    @abstract Reads a 32-bit value from an I/O space aperture.
713    @discussion This method will read a 32-bit value from a 4 byte aligned offset in an I/O space aperture. If a map object is passed in, the value is read relative to it, otherwise to the value is read relative to the I/O space aperture for the bus. This function encapsulates the differences between architectures in generating I/O space operations. An eieio instruction is included on PPC.
714    @param offset An offset into a bus or device's I/O space aperture.
715    @param map If the offset is relative to the beginning of a device's aperture, an IOMemoryMap object for that object should be passed in. Otherwise, passing zero will write the value relative to the beginning of the bus' I/O space.
716    @result The value read in host byte order (big endian on PPC). */
717
718    virtual UInt32 ioRead32( UInt16 offset, IOMemoryMap * map = 0 );
719
720/*! @function ioRead16
721    @abstract Reads a 16-bit value from an I/O space aperture.
722    @discussion This method will read a 16-bit value from a 2 byte aligned offset in an I/O space aperture. If a map object is passed in, the value is read relative to it, otherwise to the value is read relative to the I/O space aperture for the bus. This function encapsulates the differences between architectures in generating I/O space operations. An eieio instruction is included on PPC.
723    @param offset An offset into a bus or device's I/O space aperture.
724    @param map If the offset is relative to the beginning of a device's aperture, an IOMemoryMap object for that object should be passed in. Otherwise, passing zero will write the value relative to the beginning of the bus' I/O space.
725    @result The value read in host byte order (big endian on PPC). */
726
727    virtual UInt16 ioRead16( UInt16 offset, IOMemoryMap * map = 0 );
728
729/*! @function ioRead8
730    @abstract Reads a 8-bit value from an I/O space aperture.
731    @discussion This method will read a 8-bit value from an offset in an I/O space aperture. If a map object is passed in, the value is read relative to it, otherwise to the value is read relative to the I/O space aperture for the bus. This function encapsulates the differences between architectures in generating I/O space operations. An eieio instruction is included on PPC.
732    @param offset An offset into a bus or device's I/O space aperture.
733    @param map If the offset is relative to the beginning of a device's aperture, an IOMemoryMap object for that object should be passed in. Otherwise, passing zero will write the value relative to the beginning of the bus' I/O space.
734    @result The value read. */
735
736    virtual UInt8 ioRead8( UInt16 offset, IOMemoryMap * map = 0 );
737
738    OSMetaClassDeclareReservedUsed(IOPCIDevice,  0);
739/*! @function hasPCIPowerManagement
740    @abstract determine whether or not the device supports PCI Bus Power Management.
741    @discussion This method will look at the device's capabilties registers and determine whether or not the device supports the PCI BUS Power Management Specification.
742    @param state(optional) Check for support of a specific state (e.g. kPCIPMCPMESupportFromD3Cold). If state is not suuplied or is 0, then check for a property in the registry which tells which state the hardware expects the device to go to during sleep.
743    @result true if the specified state is supported */
744    virtual bool hasPCIPowerManagement(IOOptionBits state = 0);
745
746    OSMetaClassDeclareReservedUsed(IOPCIDevice,  1);
747/*! @function enablePCIPowerManagement
748    @abstract enable PCI power management for sleep state
749    @discussion This method will enable PCI Bus Powermanagement when going to sleep mode.
750    @param state(optional) Enables PCI Power Management by placing the function in the given state (e.g. kPCIPMCSPowerStateD3). If state is not specified or is 0xffffffff, then the IOPCIDevice determines the desired state. If state is kPCIPMCSPowerStateD0 (0) then PCI Power Management is disabled.
751    @result kIOReturnSuccess if there were no errors */
752    virtual IOReturn enablePCIPowerManagement(IOOptionBits state = 0xffffffff);
753
754    OSMetaClassDeclareReservedUsed(IOPCIDevice,  2);
755/*! @function extendedFindPCICapability
756    @abstract Search configuration space for a PCI capability register.
757    @discussion This method searches the device's config space for a PCI capability register matching the passed capability ID, if the device supports PCI capabilities.
758    @param capabilityID A PCI capability ID. PCI Express devices may support extended capabilities in config space starting at offset 0x100. To search this space, the ID passed should be the negated value of the PCI-SIG assigned ID for the extended capability.
759    @param offset An optional in/out parameter to return the offset into config space where the capability was found, and to set the start point of the next search. Initialize the offset to zero before the first call to extendedFindPCICapability() and subsequent calls will find all capabilty blocks that may exist on the device with the same ID.
760    @result The 32-bit value of the capability register if one was found, zero otherwise. */
761
762    virtual UInt32 extendedFindPCICapability( UInt32 capabilityID, IOByteCount * offset = 0 );
763
764    // Unused Padding
765    OSMetaClassDeclareReservedUnused(IOPCIDevice,  3);
766    OSMetaClassDeclareReservedUnused(IOPCIDevice,  4);
767    OSMetaClassDeclareReservedUnused(IOPCIDevice,  5);
768    OSMetaClassDeclareReservedUnused(IOPCIDevice,  6);
769    OSMetaClassDeclareReservedUnused(IOPCIDevice,  7);
770    OSMetaClassDeclareReservedUnused(IOPCIDevice,  8);
771    OSMetaClassDeclareReservedUnused(IOPCIDevice,  9);
772    OSMetaClassDeclareReservedUnused(IOPCIDevice, 10);
773    OSMetaClassDeclareReservedUnused(IOPCIDevice, 11);
774    OSMetaClassDeclareReservedUnused(IOPCIDevice, 12);
775    OSMetaClassDeclareReservedUnused(IOPCIDevice, 13);
776    OSMetaClassDeclareReservedUnused(IOPCIDevice, 14);
777    OSMetaClassDeclareReservedUnused(IOPCIDevice, 15);
778
779public:
780
781/*! @function extendedConfigRead32
782    @abstract Reads a 32-bit value from the PCI device's configuration space.
783    @discussion This method reads a 32-bit configuration space register on the device and returns its value.
784    @param offset A byte offset into configuration space, of which bits 0-1 are ignored.
785    @result An 32-bit value in host byte order (big endian on PPC). */
786
787    UInt32 extendedConfigRead32( IOByteCount offset );
788
789/*! @function extendedConfigRead16
790    @abstract Reads a 16-bit value from the PCI device's configuration space.
791    @discussion This method reads a 16-bit configuration space register on the device and returns its value.
792    @param offset A byte offset into configuration space, of which bit 0 is ignored.
793    @result An 16-bit value in host byte order (big endian on PPC). */
794
795    UInt16 extendedConfigRead16( IOByteCount offset );
796
797/*! @function extendedConfigRead8
798    @abstract Reads a 8-bit value from the PCI device's configuration space.
799    @discussion This method reads a 8-bit configuration space register on the device and returns its value.
800    @param offset A byte offset into configuration space.
801    @result An 8-bit value. */
802
803    UInt8 extendedConfigRead8( IOByteCount offset );
804
805/*! @function extendedConfigWrite32
806    @abstract Writes a 32-bit value to the PCI device's configuration space.
807    @discussion This method writes a 32-bit value to a configuration space register on the device.
808    @param offset A byte offset into configuration space, of which bits 0-1 are ignored.
809    @param data An 32-bit value to be written in host byte order (big endian on PPC). */
810
811    void extendedConfigWrite32( IOByteCount offset, UInt32 data );
812
813/*! @function extendedConfigWrite16
814    @abstract Writes a 16-bit value to the PCI device's configuration space.
815    @discussion This method writes a 16-bit value to a configuration space register on the device.
816    @param offset A byte offset into configuration space, of which bit 0 is ignored.
817    @param data An 16-bit value to be written in host byte order (big endian on PPC). */
818
819    void extendedConfigWrite16( IOByteCount offset, UInt16 data );
820
821/*! @function extendedConfigWrite8
822    @abstract Writes a 8-bit value to the PCI device's configuration space.
823    @discussion This method writes a 8-bit value to a configuration space register on the device.
824    @param offset A byte offset into configuration space.
825    @param data An 8-bit value to be written. */
826
827    void extendedConfigWrite8( IOByteCount offset, UInt8 data );
828
829    // pass NULL or currentHandler, currentRef to get current handler installed
830    // pass NULL or handler, ref to set handler for device
831    // messages: kIOMessageDeviceWillPowerOff, kIOMessageDeviceHasPoweredOff,
832    //           kIOMessageDeviceWillPowerOn, kIOMessageDeviceHasPoweredOn
833    // state: D3
834    IOReturn setConfigHandler(IOPCIDeviceConfigHandler handler, void * ref,
835                              IOPCIDeviceConfigHandler * currentHandler, void ** currentRef);
836
837    //
838    IOReturn kernelRequestProbe(uint32_t options);
839
840	// (kIOPCIConfigSpace, VM_PROT_READ/WRITE to disable that access)
841	IOReturn protectDevice(uint32_t space, uint32_t prot);
842
843	IOReturn checkLink(uint32_t options = 0);
844
845	IOReturn relocate(uint32_t options = 0);
846
847	IOReturn setLatencyTolerance(IOOptionBits type, uint64_t nanoseconds);
848
849    IOPCIEventSource * createEventSource(OSObject * owner, IOPCIEventSource::Action action, uint32_t options);
850
851    // allow tunnel controller to enter L1, client should be an attached driver calling
852    // this method in its IOPCIDevice provider.
853	IOReturn setTunnelL1Enable(IOService * client, bool l1Enable);
854
855	IOReturn setASPMState(IOService * client, IOOptionBits state);
856};
857
858#endif /* defined(KERNEL) */
859
860#endif /* ! _IOKIT_IOPCIDEVICE_H */
861
862