@Drewbadour
Yes, I have overriden init() to initialize DEXT IVars and I'm calling super::init()
Also I have overriden Start method and calling Start(provider, SUPERDISPATCH). In Start(), I'm calling Open(this, 0) and this Open call in Start method is failing with error code kIOReturnNotOpen(0x2cd) but still able to read/write configuration space and MemoryRead is also successful.
Below is the code I have implemented with reference from Modernize PCI and SCSI drivers with DriverKit
bool
MyDriver::init()
{
if (!super::init())
{
return false;
}
ivars = IONewZero(MyDriver_IVars, 1);
if (!ivars)
{
return false;
}
//Initialization of IVars here
-------------------------------
return true;
}
// Open fails with error code kIOReturnNotOpen(0x2cd)
kern_return_t
IMPL(MyDriver, Start)
{
kern_return_t ret = kIOReturnSuccess;
ret = Start(provider, SUPERDISPATCH);
if(ret != kIOReturnSuccess)
{
return kIOReturnNoDevice;
}
ivars->mIOPCIDeviceObj = OSDynamicCast(IOPCIDevice, provider);
if(nullptr == ivars->mIOPCIDeviceObj)
{
return kIOReturnNoDevice;
}
ret = ivars->mIOPCIDeviceObj->Open(this, 0);
if(kIOReturnSuccess != ret)
{
// Open call is always failing with 0x2cd but still proceeding further
//return kIOReturnNoDevice;
}
// Enabling Bus Master and Memory Space
ivars->mIOPCIDeviceObj->ConfigurationRead16(kIOPCIConfigurationOffsetCommand, &commandRegister);
commandRegister |= (kIOPCICommandBusMaster | kIOPCICommandMemorySpace);
ivars->mIOPCIDeviceObj->ConfigurationWrite16(kIOPCIConfigurationOffsetCommand, commandRegister);
if (kIOReturnSuccess != RegisterService())
{
return kIOReturnError;
}
return kIOReturnSuccess;
}
// Issue arises in this method, MemoryWriteXX always crashes
kern_return_t
MyDriver::CommunicateWithDevice(IOByteCount offset)
{
uint64_t Offset = some offset in controller registers
uint32_t Data = some data;
// Memory Read, This works fine
ivars->mIOPCIDeviceObj->MemoryRead32(0, Offset, &Data);
//Memory Write, This crashes always
ivars->mIOPCIDeviceObj->MemoryWrite32(0, Offset, Data);
return kIOReturnSuccess;
}
void
IMPL(MyDriver, Stop)
{
uint16_t commandRegister;
// Disable Bus Master and Memory Space
ivars->mIOPCIDeviceObj->ConfigurationRead16(kIOPCIConfigurationOffsetCommand, &commandRegister);
commandRegister &= ~(kIOPCICommandBusMaster | kIOPCICommandMemorySpace);
ivars->mIOPCIDeviceObj->ConfigurationWrite16(kIOPCIConfigurationOffsetCommand, commandRegister);
ivars->mIOPCIDeviceObj->Close(this, 0);
Stop(provider, SUPERDISPATCH);
}
void
MyDriver::free()
{
IODelete(ivars, MyDriver_IVars, 1);
super::free();
}