I've been following the https://docs.microsoft.com/en-us/windows-hardware/drivers/gpio/ Windows GPIO Driver Design Guide and have the Intel Controller Driver installed; which I downloaded from https://www.intel.com/content/dam/www/public/us/en/zip/atom-e3900-board-support-package-iot-platforms.zip here.
I then followed the https://github.com/Microsoft/Windows-driver-samples/tree/master/gpio/samples/simdevice WDK GPIO simdevice sample making only changes to the inf to load for the new ACPI device I defined in a new BIOS build. My new ACPI device shows up in the Windows device manager, my simdevice peripheral driver loads for it and PrepareHardware hands me the 8 GpioIo I defined in ASL. When calling WdfCmResourceListGetDescriptor(ResourcesTranslated, index); for each resource their descriptor types are CmResourceTypeConnection; as expected. Their connection class is CM_RESOURCE_CONNECTION_CLASS_GPIO and their connection type is CM_RESOURCE_CONNECTION_TYPE_GPIO_IO. It seems like that part is working properly.
In order to send the IOCTL_GPIO_READ_PINS to the controller driver the sample indicates I need to:
- Create an IoTarget with the ParentObject set to the WDFDEVICE that my peripheral driver created. Shown https://github.com/Microsoft/Windows-driver-samples/blob/master/gpio/samples/simdevice/simdevice.c# L704 here.
- Open the IoTarget specifying a RequestString and the desired access levels
- The RequestString is created by using the RESOURCE_HUB_CREATE_PATH_FROM_ID macro. I provide the ConnectionId of the GPIO I want to target. The ConnectionId was provided to my driver during PrepareHardware.
- Create a WdfRequest and WdfMemory object with the data to pass to the IOCTL.
- Format the request for the IOCTL
- Send the IOCTL
However, step 2 above is failing with a STATUS_INVALID_PARAMETER. This step is done at https://github.com/Microsoft/Windows-driver-samples/blob/master/gpio/samples/simdevice/simdevice.c# L741 line 741 of the sample.
Any help in making the IOCTL_GPIO_READ_PINS and IOCTL_GPIO_WRITE_PINS calls to the controller driver would be greatly appreciated.
I've been doing some follow-up testing to make sure I've addressed the issue. It looks like the way I was requesting the ResourceString using the RESOURCE_HUB_CREATE_PATH_FROM_ID was incorrect. It expects me to provide a UNICODE_STRING for the framework to populate. I was doing this improperly. I found 2 WDK samples that illustrate how to do this.
1) This i2c example that shows how to get the ResourceString from the resource hub.
https://github.com/Microsoft/Windows-driver-samples/blob/master/usb/UcmTcpciCxClientSample/I2C.cpp# L192 Windows-driver-samples/I2C.cpp at master · Microsoft/Windows-driver-samples · GitHub
It does it like so:
// Create the device path using the connection ID.
2) This https://github.com/Microsoft/Windows-driver-samples/blob/master/gpio/samples/simdevice/simdevice.c# L741 GPIO example that shows how to get the ResourceString from the resource hub.
I initially started with method 2. That wasn't working so I switched to method 1; because it seems more logical. It turns out I had an issue with my connectionID index first so it didn't matter which method I used. Once I corrected that method 1 wasn't working. Once I reverted to method 2 I was able to get past this issue.