@anshu1102 I also have a KEXT where getProvider() was used to get the parent of the provider object for performing a specific operation. But it seems like DriverKit does not have any alternative for this and I am stuck with this issue.
Post
Replies
Boosts
Views
Activity
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 but still able to read/write configuration space and Memory Read is also successful.
Basically I'm following Modernize PCI and SCSI drivers with DriverKit.
I have posted the code that I have referenced in the answer section.
@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();
}
I am also facing this exact issue where Open(this, 0) call fails in Start() but accessing the configuration space using ConfigurationReadXX/ConfigurationWriteXX works fine. In case of accessing the memory space, MemoryReadXX is successful but MemoryWriteXX crashes whenever I try to access any offset in memory index 0.
@dune_sea_jedi
Given below are the Info.plist and entitlement files we use for our driver. The driver matches against the device and we are able to communicate with the device. We want to know whether we are missing something in our steps of accessing memory space using MemoryWriteXX APIs.
Driver Info.plist details
IOClass: IOUserService
IOMatchCategory: MyDriver
IOPCIMatch: 0xDEVID and VID
IOPCISecondaryMatch: 0xDEVID and VID
IOResourceMatch: IOKit
IOUserClass: MyDriver
IOProviderClass: IOPCIDevice
IOUserServerName: com.mycompany.mypcidevice.MyDriver
UserClientProperties (Dictionary)
IOUserClass: MyDriverUserClient
IOClass: IOUserUserClient
Driver Entitlements
com.apple.developer.driverkit
com.apple.developer.driverkit.transport.pci (Array)
Item 0
IOPCIMatch: 0xVID and DEVID
Item 1:
IOPCISecondaryMatch: 0xVID and DEVID
App Entitlements
com.apple.developer.system-extension.install
com.apple.developer.system-extension.uninstall
com.apple.developer.driverkit.userclient-access (Array)
Item 0: com.mycompany.mypcidevice.MyDriver
@anshu1102 @Drewbadour
Finally we got GetProvider API with MacOS 12 Developer Beta Release and Xcode 13 Beta. I'm excited to complete my DEXT.
Using this API, I got first (primary) provider but after that when I iterated to retrieve the provider of the primary provider, it's returning null. Since this API is in beta release, I'm expecting this to work properly in future releases.
Has anyone tested this GetProvider API in DEXT??