How to show a device in bus and class? - linux-kernel

How show the same struct device in bus and class in sysfs structure? I'm getting an error when doing this. Currently I'm assigning bus and class attributes of struct device before calling device_register. The error message says that a device in /device of the same name already exists.

Related

Linux driver: MFD over PCI

I am writing a driver for a PCI device. The device is a custom development FPGA based device. The FPGA has multiple "devices" on board. I want my driver to create the proper interfaces for those devices.
A certain part of the device will use our own "part". But for I2C busses, I would like to use the already available opencores driver. In the past I had to add the I2C compatible property to the correct "device" in my DTS under my FPGA device (FPGA to CPU was SPI).
Now this has to go over PCI.
The kernel uses my FPGA driver and probes, also created the "own part" as chardev. the I2C opencores drivers ->probe() functions seems not to be called when I create a MFD-cell with the correct compatible property. The cell is added, but never probed.
I use Linux kernel v4.9 on a 64-bit ARM based CPU.
struct x_my_dev {
struct list_head x_my_dev;
struct mfd_cell *mfd_cell;
struct device_node *of_node;
struct property *compat_prop;
struct resource *irq_resource;
struct platform_devive *pdev;
};
...
struct x_my_dev *my_dev;
...
ret = mfd_add_devices(priv->dev, PLATFORM_DEVID_NONE,
my_dev->mfd_cell, 1, NULL, irq_base, NULL)
if (ret) {
dev_err(priv->dev, "Failed to add mfd cell\n");
goto err_mfd_add;
}
...
Already checked if the opencores driver is available in the kernel
The kernel /sys/class/my_fpga/device/I2C_bus/ has only 'driver_override', 'modalias', 'power', 'subsystem' and 'uevent'. Nothing that shows what drivers needs to be used.

The DriverKit problems to develop multiple serial USB device

I am developing a DriverKit driver for a USB device which has multiple serial UARTs connected. Each UART will represent a cu.USBX port on Mac. My driver inherits IOUSBHostDevice class and it matches device ID well. Now, I am going to crate a new class inherits IOUserSerial to implement serial port. However, compiler said no new operator on base class. It seems the base OSObject class prevent to new the subclass as I did in IOKit driver. Since the similar IOUserSerial/IOUserUSBSerial examples are hard to find, I would like to ask if anyone can help me to solve this problem. Any feedback and clue is appreciated. Following are some snippets to show my situation.
My original IOKit port driver inherits IORS232SerialStreamSync.
class KextSerial : public IORS232SerialStreamSync
{
OSDeclareDefaultStructors( KextSerial ) ; // Constructor & Destructor stuff
:
}
My USB driver could create new KextSerials and initiate them as well.
KextSerial * newSerial = new KextSerial;
if( !newSerial->init(0, 0) ){
goto FailExit;
}
However, in my DriverKit port driver inherits IOUserSerial.
class DextSerial : public IOUserSerial
{
:
}
While I try to new the DextSerial as following.
DextSerial * newSerial = new DextSerial;
The compiler said "No matching function for call to 'operator new'"
Maybe I can't do this in DriverKit but I can't find documents from Apple's developing website.
Parallelly I have tried IOUserUSBSerial and OSObject, I got the same error message.
Your question isn't especially clear, but I'll do my best to go through the various options.
An instance of your main driver class is created by the system when your driver matches its provider device.
Creating instances explicitly in code mainly happens for user client objects if you're implementing NewUserClient yourself, or if you want to create client objects to attach below your main driver object instance.
Main driver object
When it comes to creating your main driver instance, this is where I/O Kit matching comes in, and it's all defined in the dext's Info.plist file. This part is very similar to kexts, apart from some changed/new IOKitPersonalities keys:
Key
Value Type
Description (dext)
Description (dext)
IOClass
string
DriverKit kernel-side IOService subclass, e.g. IOUserService, IOUserSCSIParallelInterfaceController, …
The driver's own IOService (or deeper) subclass
IOUserClass
string
Dext-side name of the driver's IOService (or deeper) subclass
N/A
CFBundleIdentifier
string
Bundle identifier of the dext
Bundle identifier of the kext
CFBundleIdentifierKernel
string
Bundle identifier of the kext hosting the DriverKit kernel-side class (IOClass), e.g. com.apple.kpi.iokit, com.apple.iokit.IOSCSIParallelFamily, …
N/A
IOUserServerName
string
Bundle identifier of the dext
N/A
Beyond that, the IOKitPersonalities dictionaries take the same form as for kexts.
So if your driver's main class is called KextSerial, you would put that as the value for IOUserClass.
Subordinate objects:
If you really need to create IOService object instances explicitly, you use IOService::Create(). The reason you can't just use standard C++ syntax is that the object needs to be mirrored in the kernel's view of the I/O Kit registry. So as with the main driver object, you need to specify the kernel and DriverKit side classes to instantiate.
The way Apple expects you to do this is by providing a dictionary property in your driver's IOKit personality, so this becomes a property on your main driver object instance. In the Create call you merely specify the property's name, the dictionary is specified in the Info.plist and looks something like this:
<key>MyDriverSubService</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>MyDriverSubService</string>
</dict>
The keys and values have the same meanings as for the main personality.
My suggestion
My understanding of your situation is the following: you have a USB device which implements more than 1 serial port. How to proceed depends on the layout of the USB device I think.
1 USB Interface per serial port
If your device exposes 1 interface for each serial port it implements in its descriptor table, and their respective endpoints can be driven independently, then I'd directly subclass IOUserUSBSerial for one port, matching any of the interfaces. The system will create an instance of your driver for each port, and your driver just needs to worry about one port at a time.
If your device's interfaces aren't automatically enumerated by the system (e.g. if device class is 0xff), you may need an "umbrella" driver class and IOKit personality which matches the device itself and configures it, prompting the interfaces to be enumerated.
No 1:1 mapping between USB interfaces and serial ports.
If there isn't a 1:1 correspondence between USB interfaces and serial ports, for example just one interface ferrying the traffic from all serial ports, you'll want to have a main driver class which merely subclasses IOService.
This creates child objects, which will be instances of subclasses of IOUserSerial or IOUserUSBSerial. Depending on whether the SerialDriverKit permits multiple instances of these or not in one driver instance, you can either create these using IOService::Create, or you will need to run each port in its own driver instance, communicating with the USB device via an API you've defined on the main driver class. This is achieved by either directly matching your main driver class, or by creating instances of "nub" child objects in the main driver class and then matching those in the per-port personality. (The latter has the advantage of allowing the driver to dynamically enumerate the number of ports; when matching the main driver object directly, you'll need to use match categories to define the number of ports, and to disambiguate which instance is which.)
For example, see this question and answer about how to create a driver for a network adapter with multiple ports, as registering multiple IOUserNetworkEthernet objects from the same instance does not appear to work as you might expect. I do not know if SerialDriverKit has the same limitation, you'll have to try and find out.
Final notes
This may just be a misuse of terminology in your question, but: you do not want to inherit (subclass) from IOUSBHostDevice, you want to match existing instances of it representing the device to drive. (Use it or IOUSBHostInterface as the IOProviderClass.)

What is the purpose of class and class device?

I followed some tutorials that explained how to write Linux kernel modules and I am a bit confused. Even after reading the official "documentation", I have poor understanding of the concepts.
After creating a character device (register_chrdev), I see it is common to use a combination of the following functions:
class_create
class_device_create
device_create
I was not able to understand, what is a class, device and, class device and driver?
Which one of these actually responsible to create an entry under /proc/?
Rather than going into what's a class, or what's a device (I'm no expert in Linux kernel), I will address the question as follows.
After creating the character device, you want to be able to access it from the user space. To do this, you need to add a device node under /dev. You can do this in two ways.
Use mknod to manually add a device node (old)
mknod /dev/<name> c <major> <minor>
OR
Use udev
This is where the class_create and device_create or class_device_create (old) come in.
To notify udev from your kernel module, you first create a virtual device class using
struct class * class_create(owner, name)
Now, the name will appear in /sys/class/<name>.
Then, create a device and register it with sysfs.
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
Now, device name will appear in /sys/devices/virtual/<class name>/<device name> and /dev/<device name>
It's not clear what you are asking about the /proc entry.
After your module is loaded, it will appear in /proc/modules (do a cat /proc/modules to see it). And, after you allocate the device numbers, say with
int register_chrdev_region(dev_t first, unsigned int count, char *name)
, the name will appear in /proc/devices (do a cat /proc/devices to see it).
And, please check the kernel sources for these functions as well, as they provide a good description of what they do in their comments.
The good old LDD3 does not provide these mechanisms, but it's a very good source.

How to handle two SPI devices in linux kernel with single SPI Platform Driver?

I have developed a SPI platform driver for a single SPI device.Which SPI device we are using,that configuration can be given in Device Tree.probe() function of SPI platform driver is called when name matching happens with name give in driver and the same present in DT.
In SPI platform driver module_init() method, we register SPI device structure (struct spi_driver spidev_spi_driver) with function call: spi_register_driver().
Please refer to the (static struct spi_driver spidev_spi_driver) in below link for example.
Link: http://lxr.free-electrons.com/source/drivers/spi/spidev.c#L664
Here Probe() is one important method registered in this call.
When probe function is called, kernel passes pointer of SPI device (e.g struct spi_device *spi) in probe() function which is further utilized in read and write operation with SPI device.
All the above procedure happens only once for a single SPI device.
Now I have query here that if I want to use more than one SPI device present in my micro controller e.g. imx6 then how I will handle this situation?
How will I receive SPI device pointers in this case?
Is the probe function will be called twice (bcoz here only I get SPI device pointers from kernel)?
Do I need to create entries such as done in spidev_dt_ids:
http://lxr.free-electrons.com/source/drivers/spi/spidev.c#L657
I haven't worked on specifically spi device, but I think I might give you some basic idea. The logic is that probe is called whenever there is matching between device->name and device_driver->name. So 2 devices can use same driver but 2 drivers should not be there for same device.
For configuring 2 devices to same driver, the 2 device will be registered on same name and hence same probe will be called. But then in probe you can differentiate. You will have access to the device struct of spi which you can use to set one parameter to distinguish and set the relevant parameters.
One more approach is like using core framework used by i2c in which general functionality functions are made and used by client driver whenever needed.
I hope this helps.

Windows HID Device Name Format

There are various ways to retrieve the Windows "Device Name" of a HID device, GetRawInputDeviceInfo with RIDI_DEVICENAME being one way to do it.
Given the example name:
\?\HID#VID_FEED&PID_DEAD#6&3559c8ea&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
I'm wondering if there is any documentation whatsoever on what is what in this string?
\?\HID#VID_AAAA&PID_BBBB#C&DDDDDD&E&FFFF#{GUID}
So the obvious ones are A(VID), B(PID) and the GUID on the end. What I'm wondering is what EXACTLY are C, D, E and F?
It seems that C and D are unique even if you plug in two of the exact same HID devices which is great for my problem, but I'd feel more comfortable if I could know exactly how this is determined on a per OS basis, or at least that it follows some known format.
I have been googling like a madman trying to figure this out, am I missing something obvious?
Thanks in advance
According to a similar MSDN post, the value represents a unique device instance ID:
the device instance ID is unique and constant for the physical
location the device is plugged into, but it is also opaque and should
not be parsed. that means it can be used for string comparison, but
not for interpretation.
It is actually device interface instance id (symbolic link name). And yes, its unique and persists across system restart. Some details also here.
You can use CM_Get_Device_Interface_Property or SetupDiGetDeviceInterfaceProperty on interface instance id with DEVPKEY_Device_InstanceId to get device instance id (one device can have multiple interfaces).
In your example - you have a HID device. Its device id format is described here.
Info on general USB devices id format is here.
After you have device instance id you can use CM_Get_DevNode_Property or SetupDiGetDeviceProperty with DEVPKEY_NAME to get localized friendly name of a device (which is shown in Device Manager).
To sum up:
\\?\HID#VID_203A&PID_FFFC&MI_01#7&2de99099&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd} - is device interface id (also referred as "device interface path" or "device name" in docs). This is path in virtual device file system.
{378de44c-56ef-11d1-bc8c-00a0c91405dd} - device interface class guid (GUID_DEVINTERFACE_MOUSE in this case. It determines which IOCTLs can be called on this device. IOCTL_MOUSE_QUERY_ATTRIBUTES in this case)
HID\VID_203A&PID_FFFC&MI_01\7&2de99099&0&0000 - is device instance id
NOTE: exact device interface id format is not documented, each device interface can generate file name it want. I don't recommend you to parse it - it could be changed in later Windows version, better aquire device instance id - it is documents at least.

Resources