I'm writing method to get pci device, given vendor id, device id programmatically (just like pci_get_device from Linux kernel).
For that I need to get device object configuration. I read from here for the same: http://msdn.microsoft.com/en-us/library/windows/hardware/ff558707(v=vs.85).aspx
Now to test this, I made fake driver - service installation framework, which will install my I/O device driver and in that from DriverEntry I can test this PCI functionality.
But OS crashes with irql_not_less_or_equal, at
irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> &ioStatusBlock);
Can anyone tell me what's wrong with that, (I'm calling this from Driver Entry, and passing current installing driver's deviceObject.)
You don't have a valid PDO in DriverEntry(). DriverEntry roughly corresponds to main() in user space application and is called first thing after driver load into memory. DriverEntry main purpose is to register the driver with the OS and its code is independent of actual device(s). You can have a PDO only after the OS has called your initialization callback (after it has recognized your device) - and the callback will be called after DriverEntry completion (actually, the callback should be provided to the OS as part of the driver registration inside the DriverEntry()).
Related
I'm working on an embedded Linux device (based on an NXP i.MX8 mini SoC) and it needs to support microphone audio input using the NXP "micfil" driver (sound/soc/fsl/fsl_micfil.c).
As a part of initializing the microphone, we have added code (to the driver's fsl_micfil_probe function) to set a GPIO line necessary to enable the microphone (by calling devm_gpiod_get_optional)
Our current Linux BSP (based on Yocto's "sumo" release) works great with this patch.
When upgrading to a newer BSP (based on Yocto's "hardknott" release), we find that the GPIO setup call fails. It appears to be happening because the driver's probe function is called before the GPIO subsystem is available. I think we can hack around this by making the GPIO call from some other driver callback (e.g. after an application opens the device), but I would prefer to simply defer this driver's probe operation until after GPIO is available.
Is there a way to do this? To tell Linux that this driver should not be probed until after GPIO starts up? Or maybe have the probe function explicitly call the GPIO startup function?
Or is there a better solution that I haven't thought of yet?
The device driver's probe function can return -EPROBE_DEFER (after any necessary clean-up) to indicate that a resource it requires is not available yet. The driver core will then add the device to a "deferred probe" list and try to call the probe function after a successful probe of some other device.
See the documentation for further information, and heed the warning about not returning -EPROBE_DEFER if any child devices have been created by the probe function.
devm_gpiod_get_optional and similar devm_gpiod_get_ and gpiod_get_ functions that return a struct gpio_desc * value will return ERR_PTR(-EPROBE_DEFER) if the requested GPIO is not yet available. (This is different to the GPIO not being found, which will result in the _optional variants returning NULL and the non-_optional variants returning ERR_PTR(-ENOENT).) The caller can propogate the -EPROBE_DEFER error to its own caller, but again the warning about not returning -EPROBE_DEFER if any child devices have been created should be heeded.
My Laptop has following SuperIO device in the SSDT Table:
DefinitionBlock ("", "SSDT", 1, "VENDORx", "TABLEx", 0x00001000)
{
Device (\_SB.PC00.LPCB.SIO0)
{
Name (_HID, EisaId ("PNP0A05") /* Generic Container Device */)
Name (_UID, "SD28301")
}
This ID claimed by the ACPI container driver but I see in /sys/bus/container/* that there is no driver associated with this device.
I wanted to write a platform driver to attach with this device. I have the following in my driver code:
static const struct acpi_device_id sio_device_ids[] = {
{ "PNP0A05", 0},
{ "", 0}
};
MODULE_DEVICE_TABLE(acpi, sio_device_ids);
Upon calling platform_driver_register(), my driver does not get bound to the SIO device. To see if kernel is even trying to match the acpi_device_id entries, I changed PNP0A05 in my kernel code to MHF1234 (custom _HID). Then I inserted an SSDT with a device that had _HID same as acpi_device_id in kernel driver like this: Name (_HID, EisaId ("MHF1234"). Now, upon inserting my driver, the probe function got called so my driver matched with the ACPI device.
Question: How do I match my driver with PNP0A05 device? I see that the ACPI container driver already detected and added this to /sys but there is no driver bound to it. Any hints to debug would be appreciated.
The device is being created by the code under drivers/acpi/container.c. However, it's purely ACPI device for now. The platform devices for ACPI ones are created by acpi_create_platform_device() which is supposed to be called by acpi_bus_attach() (via acpi_default_enumeration() because it's not enumerated by parent). However, container_device_attach() on success returns positive number, i.e. 1, and acpi_bus_attach() skips platform device creation due to the conditional. That's why it's not being represented as platform device and hence may not be enumerated via platform bus.
Besides that, ACPI specification tells us the following: PNP0A05 Generic Container Device. A device whose settings are totally controlled by its ACPI resource information, and otherwise needs no device or bus-specific driver support. This was originally known as Generic ISA Bus Device. This ID should only be used for containers that do not produce resources for consumption by child devices. Any system resources claimed by a PNP0A05 device’s _CRS object must be consumed by the container itself.
I am a newbie to linux kernel. While interfacing with the external device, I made the required changes in bsp file. The bsp file device name and platform_driver name should match in order to invoke probe(). I have heard that probe will check whether h/w exists and probe() will create device file (/dev/rtc1) for a new external device. I am not sure about the functionality of the probe(). Can someone explain me how device file is created in this context?Thank you in advance!
probe() is a callback function that gets called, irrespective of h/w presence, when the bus_match_driver() routine returns success. The probe function is called when a device is installed that the driver-core thinks it should handle; the probe function should perform checks on the information passed to it about the device and decide whether the driver is really appropriate for that device. A device file is created either manually by mknod or automatically by udev and is not directly related to probe function. The book https://lwn.net/Kernel/LDD3/ (highly recommended) has all the details regarding creating a device node.
If a USB device driver is loaded, and at some time the device plugs in, then which part of the kernel will create struct device and register it?
When the driver is loaded, the system calls the function, which you assigned in module_init. You will want to call there usb_register(struct usb_driver skel_driver), where skel_driver is a struct with pointers to methods servicing the device, like the probe method.
The probe method is the one which is called, when a new usb device is introduced in to the system. In this place you can fill your struct (usb_skel) with what you will need in the future, initiate a char device or whatever you do, when the device is introduced.
The system mostly won't create anything by itself, it has to have most of the structs prepared and filled with device specific data.
Please see usb-skeleton in lxr for reference and learn to use it, besides read writing usb drivers from LDD.
Cheers
I need to retrieve the "Physical Device Object name" of a disk device from a user mode application on Windows, as seen in Device Manager.
I have a solution now that involves a kernel driver that gets loaded and interrogated through IOCTLs. Once in kernel land, I have no trouble getting to that name. If possible, I would like to avoid using a kernel module.
Any ideas?
You can get this using the Setup API functions. Specifically I believe you can get this via SetupDiGetDeviceRegistryProperty and SPDRP_PHYSICAL_DEVICE_OBJECT_NAME.