2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
26 * 23 Nov 98 sdouglas created from objc version.
29 #include <IOKit/system.h>
31 #include <IOKit/pci/IOPCIBridge.h>
32 #include <IOKit/pci/IOPCIDevice.h>
33 #include <IOKit/pci/IOAGPDevice.h>
34 #include <IOKit/IOPlatformExpert.h>
36 #include <IOKit/IOLib.h>
37 #include <IOKit/assert.h>
39 #include <libkern/c++/OSContainers.h>
41 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43 #define super IOService
45 OSDefineMetaClassAndStructors(IOPCIDevice
, IOService
)
46 OSMetaClassDefineReservedUnused(IOPCIDevice
, 0);
47 OSMetaClassDefineReservedUnused(IOPCIDevice
, 1);
48 OSMetaClassDefineReservedUnused(IOPCIDevice
, 2);
49 OSMetaClassDefineReservedUnused(IOPCIDevice
, 3);
50 OSMetaClassDefineReservedUnused(IOPCIDevice
, 4);
51 OSMetaClassDefineReservedUnused(IOPCIDevice
, 5);
52 OSMetaClassDefineReservedUnused(IOPCIDevice
, 6);
53 OSMetaClassDefineReservedUnused(IOPCIDevice
, 7);
54 OSMetaClassDefineReservedUnused(IOPCIDevice
, 8);
55 OSMetaClassDefineReservedUnused(IOPCIDevice
, 9);
56 OSMetaClassDefineReservedUnused(IOPCIDevice
, 10);
57 OSMetaClassDefineReservedUnused(IOPCIDevice
, 11);
58 OSMetaClassDefineReservedUnused(IOPCIDevice
, 12);
59 OSMetaClassDefineReservedUnused(IOPCIDevice
, 13);
60 OSMetaClassDefineReservedUnused(IOPCIDevice
, 14);
61 OSMetaClassDefineReservedUnused(IOPCIDevice
, 15);
63 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
65 // stub driver has two power states, off and on
67 enum { kIOPCIDevicePowerStateCount
= 2 };
69 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
72 // We clamp power on. The effect is
73 // to prevent system sleep. If a driver is loaded which can
74 // power manage the device, it will become our child and we
75 // will remove the clamp. This prevents the system
76 // from sleeping when there are non-power-managed
77 // PCI cards installed.
78 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
80 bool IOPCIDevice::attach( IOService
* provider
)
82 static const IOPMPowerState powerStates
[ kIOPCIDevicePowerStateCount
] = {
83 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
84 { 1, IOPMPowerOn
, IOPMPowerOn
, IOPMPowerOn
, 0, 0, 0, 0, 0, 0, 0, 0 }
87 // initialize superclass variables
89 // register as controlling driver
90 registerPowerDriver( this, (IOPMPowerState
*) powerStates
,
91 kIOPCIDevicePowerStateCount
);
93 provider
->joinPMtree( this);
95 // clamp power on if this is a slot device
96 slotNameProperty
= provider
->getProperty ("AAPL,slot-name");
97 if (slotNameProperty
!= NULL
)
98 changePowerStateToPriv (1);
100 return super::attach(provider
);
104 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
105 // maxCapabilityForDomainState
107 // If the power domain is supplying power, the device
108 // can be on. If there is no power it can only be off.
109 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
111 unsigned long IOPCIDevice::maxCapabilityForDomainState(
112 IOPMPowerFlags domainState
)
114 if( domainState
& IOPMPowerOn
)
115 return( kIOPCIDevicePowerStateCount
- 1);
121 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
122 // initialPowerStateForDomainState
124 // This is our first information about the power domain state.
125 // If power is on in the new state, the device is on.
126 // If domain power is off, the device is also off.
127 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
128 unsigned long IOPCIDevice::initialPowerStateForDomainState(
129 IOPMPowerFlags domainState
)
131 if( domainState
& IOPMPowerOn
)
132 return( kIOPCIDevicePowerStateCount
- 1);
137 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
138 // powerStateForDomainState
140 // The power domain may be changing state.
141 // If power is on in the new state, the device will be on.
142 // If domain power is off, the device will be off.
143 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
145 unsigned long IOPCIDevice::powerStateForDomainState(
146 IOPMPowerFlags domainState
)
148 if( domainState
& IOPMPowerOn
)
149 return( pm_vars
->myCurrentState
);
154 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
157 // Saves and restores PCI config space if power is going down or up.
158 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
160 IOReturn
IOPCIDevice::setPowerState( unsigned long powerState
,
161 IOService
* whatDevice
)
163 parent
->setDevicePowerState( this, powerState
);
165 return( IOPMAckImplied
);
168 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
172 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
174 IOReturn
IOPCIDevice::addPowerChild ( IOService
* theChild
)
176 IOReturn result
= IOPMNoErr
;
178 result
= super::addPowerChild (theChild
);
180 if ((slotNameProperty
!= NULL
) && (result
== IOPMNoErr
))
181 changePowerStateToPriv(0);
186 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
189 // A policy-maker for our PCI device calls here when initializing,
190 // to be attached into the power management hierarchy.
191 // We attach this driver as our child so we can save and restore its config
192 // space across power cycles.
194 // This overrides the default function of the IOService joinPMtree.
195 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
197 void IOPCIDevice::joinPMtree( IOService
* driver
)
199 // hook it into the tree
200 pm_vars
->thePlatform
->PMRegisterDevice( this, driver
);
203 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
205 bool IOPCIDevice::matchPropertyTable( OSDictionary
* table
, SInt32
* score
)
207 return( parent
->matchNubWithPropertyTable( this, table
, score
));
210 bool IOPCIDevice::compareName( OSString
* name
, OSString
** matched
= 0 ) const
212 return( parent
->compareNubName( this, name
, matched
));
215 IOReturn
IOPCIDevice::getResources( void )
217 return( parent
->getNubResources( this ));
220 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
222 UInt32
IOPCIDevice::configRead32( IOPCIAddressSpace _space
,
225 return( parent
->configRead32( _space
, offset
));
228 void IOPCIDevice::configWrite32( IOPCIAddressSpace _space
,
229 UInt8 offset
, UInt32 data
)
231 parent
->configWrite32( _space
, offset
, data
);
234 UInt16
IOPCIDevice::configRead16( IOPCIAddressSpace _space
,
237 return( parent
->configRead16( _space
, offset
));
240 void IOPCIDevice::configWrite16( IOPCIAddressSpace _space
,
241 UInt8 offset
, UInt16 data
)
243 parent
->configWrite16( _space
, offset
, data
);
246 UInt8
IOPCIDevice::configRead8( IOPCIAddressSpace _space
,
249 return( parent
->configRead8( _space
, offset
));
252 void IOPCIDevice::configWrite8( IOPCIAddressSpace _space
,
253 UInt8 offset
, UInt8 data
)
255 parent
->configWrite8( _space
, offset
, data
);
258 UInt32
IOPCIDevice::configRead32( UInt8 offset
)
260 return( parent
->configRead32( space
, offset
));
263 void IOPCIDevice::configWrite32( UInt8 offset
, UInt32 data
)
265 parent
->configWrite32( space
, offset
, data
);
268 UInt16
IOPCIDevice::configRead16( UInt8 offset
)
270 return( parent
->configRead16( space
, offset
));
273 void IOPCIDevice::configWrite16( UInt8 offset
, UInt16 data
)
275 parent
->configWrite16( space
, offset
, data
);
278 UInt8
IOPCIDevice::configRead8( UInt8 offset
)
280 return( parent
->configRead8( space
, offset
));
283 void IOPCIDevice::configWrite8( UInt8 offset
, UInt8 data
)
285 parent
->configWrite8( space
, offset
, data
);
288 IOReturn
IOPCIDevice::saveDeviceState( IOOptionBits options
= 0 )
290 return( parent
->saveDeviceState( this, options
) );
293 IOReturn
IOPCIDevice::restoreDeviceState( IOOptionBits options
= 0 )
295 return( parent
->restoreDeviceState( this, options
) );
298 UInt32
IOPCIDevice::findPCICapability( UInt8 capabilityID
, UInt8
* offset
= 0 )
300 return( parent
->findPCICapability( space
, capabilityID
, offset
));
303 UInt32
IOPCIDevice::setConfigBits( UInt8 reg
, UInt32 mask
, UInt32 value
)
308 bits
= configRead32( reg
);
311 bits
|= (value
& mask
);
312 configWrite32( reg
, bits
);
317 bool IOPCIDevice::setBusMasterEnable( bool enable
)
319 return( 0 != setConfigBits( kIOPCIConfigCommand
, kIOPCICommandBusMaster
,
320 enable
? kIOPCICommandBusMaster
: 0));
323 bool IOPCIDevice::setMemoryEnable( bool enable
)
325 return( 0 != setConfigBits( kIOPCIConfigCommand
, kIOPCICommandMemorySpace
,
326 enable
? kIOPCICommandMemorySpace
: 0));
329 bool IOPCIDevice::setIOEnable( bool enable
, bool /* exclusive = false */ )
331 // exclusive is TODO.
332 return( 0 != setConfigBits( kIOPCIConfigCommand
, kIOPCICommandIOSpace
,
333 enable
? kIOPCICommandIOSpace
: 0));
336 UInt8
IOPCIDevice::getBusNumber( void )
338 return( space
.s
.busNum
);
341 UInt8
IOPCIDevice::getDeviceNumber( void )
343 return( space
.s
.deviceNum
);
346 UInt8
IOPCIDevice::getFunctionNumber( void )
348 return( space
.s
.functionNum
);
351 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
353 IODeviceMemory
* IOPCIDevice::getDeviceMemoryWithRegister( UInt8 reg
)
356 IODeviceMemory
* range
;
359 array
= (OSArray
*) getProperty( gIODeviceMemoryKey
);
363 while( (range
= (IODeviceMemory
*) array
->getObject( i
++ ))) {
364 if( reg
== (range
->getTag() & 0xff))
371 IOMemoryMap
* IOPCIDevice:: mapDeviceMemoryWithRegister( UInt8 reg
,
372 IOOptionBits options
= 0 )
374 IODeviceMemory
* range
;
377 range
= getDeviceMemoryWithRegister( reg
);
379 map
= range
->map( options
);
386 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
388 IODeviceMemory
* IOPCIDevice::ioDeviceMemory( void )
390 return( parent
->ioDeviceMemory() );
393 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
395 IOService
* IOPCIDevice::matchLocation( IOService
* /* client */ )
400 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
403 #define super IOPCIDevice
405 OSDefineMetaClassAndStructors(IOAGPDevice
, IOPCIDevice
)
406 OSMetaClassDefineReservedUnused(IOAGPDevice
, 0);
407 OSMetaClassDefineReservedUnused(IOAGPDevice
, 1);
408 OSMetaClassDefineReservedUnused(IOAGPDevice
, 2);
409 OSMetaClassDefineReservedUnused(IOAGPDevice
, 3);
410 OSMetaClassDefineReservedUnused(IOAGPDevice
, 4);
411 OSMetaClassDefineReservedUnused(IOAGPDevice
, 5);
412 OSMetaClassDefineReservedUnused(IOAGPDevice
, 6);
413 OSMetaClassDefineReservedUnused(IOAGPDevice
, 7);
414 OSMetaClassDefineReservedUnused(IOAGPDevice
, 8);
415 OSMetaClassDefineReservedUnused(IOAGPDevice
, 9);
416 OSMetaClassDefineReservedUnused(IOAGPDevice
, 10);
417 OSMetaClassDefineReservedUnused(IOAGPDevice
, 11);
418 OSMetaClassDefineReservedUnused(IOAGPDevice
, 12);
419 OSMetaClassDefineReservedUnused(IOAGPDevice
, 13);
420 OSMetaClassDefineReservedUnused(IOAGPDevice
, 14);
421 OSMetaClassDefineReservedUnused(IOAGPDevice
, 15);
422 OSMetaClassDefineReservedUnused(IOAGPDevice
, 16);
424 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
426 IOReturn
IOAGPDevice::createAGPSpace( IOOptionBits options
,
427 IOPhysicalAddress
* address
,
428 IOPhysicalLength
* length
)
430 return( parent
->createAGPSpace( this, options
, address
, length
));
433 IOReturn
IOAGPDevice::destroyAGPSpace( void )
435 return( parent
->destroyAGPSpace( this ));
438 IORangeAllocator
* IOAGPDevice::getAGPRangeAllocator( void )
440 return( parent
->getAGPRangeAllocator( this ));
443 IOOptionBits
IOAGPDevice::getAGPStatus( IOOptionBits options
= 0 )
445 return( parent
->getAGPStatus( this, options
));
448 IOReturn
IOAGPDevice::resetAGP( IOOptionBits options
= 0 )
450 return( parent
->resetAGPDevice( this, options
));
453 IOReturn
IOAGPDevice::getAGPSpace( IOPhysicalAddress
* address
,
454 IOPhysicalLength
* length
)
456 return( parent
->getAGPSpace( this, address
, length
));
459 IOReturn
IOAGPDevice::commitAGPMemory( IOMemoryDescriptor
* memory
,
460 IOByteCount agpOffset
,
461 IOOptionBits options
= 0 )
463 return( parent
->commitAGPMemory( this, memory
, agpOffset
, options
));
466 IOReturn
IOAGPDevice::releaseAGPMemory( IOMemoryDescriptor
* memory
,
467 IOByteCount agpOffset
,
468 IOOptionBits options
= 0 )
470 return( parent
->releaseAGPMemory( this, memory
, agpOffset
, options
));