|
@@ -1,129 +0,0 @@
|
|
-
|
|
|
|
-Device Interfaces
|
|
|
|
-
|
|
|
|
-Introduction
|
|
|
|
-~~~~~~~~~~~~
|
|
|
|
-
|
|
|
|
-Device interfaces are the logical interfaces of device classes that correlate
|
|
|
|
-directly to userspace interfaces, like device nodes.
|
|
|
|
-
|
|
|
|
-Each device class may have multiple interfaces through which you can
|
|
|
|
-access the same device. An input device may support the mouse interface,
|
|
|
|
-the 'evdev' interface, and the touchscreen interface. A SCSI disk would
|
|
|
|
-support the disk interface, the SCSI generic interface, and possibly a raw
|
|
|
|
-device interface.
|
|
|
|
-
|
|
|
|
-Device interfaces are registered with the class they belong to. As devices
|
|
|
|
-are added to the class, they are added to each interface registered with
|
|
|
|
-the class. The interface is responsible for determining whether the device
|
|
|
|
-supports the interface or not.
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Programming Interface
|
|
|
|
-~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
-
|
|
|
|
-struct device_interface {
|
|
|
|
- char * name;
|
|
|
|
- rwlock_t lock;
|
|
|
|
- u32 devnum;
|
|
|
|
- struct device_class * devclass;
|
|
|
|
-
|
|
|
|
- struct list_head node;
|
|
|
|
- struct driver_dir_entry dir;
|
|
|
|
-
|
|
|
|
- int (*add_device)(struct device *);
|
|
|
|
- int (*add_device)(struct intf_data *);
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-int interface_register(struct device_interface *);
|
|
|
|
-void interface_unregister(struct device_interface *);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-An interface must specify the device class it belongs to. It is added
|
|
|
|
-to that class's list of interfaces on registration.
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Interfaces can be added to a device class at any time. Whenever it is
|
|
|
|
-added, each device in the class is passed to the interface's
|
|
|
|
-add_device callback. When an interface is removed, each device is
|
|
|
|
-removed from the interface.
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Devices
|
|
|
|
-~~~~~~~
|
|
|
|
-Once a device is added to a device class, it is added to each
|
|
|
|
-interface that is registered with the device class. The class
|
|
|
|
-is expected to place a class-specific data structure in
|
|
|
|
-struct device::class_data. The interface can use that (along with
|
|
|
|
-other fields of struct device) to determine whether or not the driver
|
|
|
|
-and/or device support that particular interface.
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Data
|
|
|
|
-~~~~
|
|
|
|
-
|
|
|
|
-struct intf_data {
|
|
|
|
- struct list_head node;
|
|
|
|
- struct device_interface * intf;
|
|
|
|
- struct device * dev;
|
|
|
|
- u32 intf_num;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-int interface_add_data(struct interface_data *);
|
|
|
|
-
|
|
|
|
-The interface is responsible for allocating and initializing a struct
|
|
|
|
-intf_data and calling interface_add_data() to add it to the device's list
|
|
|
|
-of interfaces it belongs to. This list will be iterated over when the device
|
|
|
|
-is removed from the class (instead of all possible interfaces for a class).
|
|
|
|
-This structure should probably be embedded in whatever per-device data
|
|
|
|
-structure the interface is allocating anyway.
|
|
|
|
-
|
|
|
|
-Devices are enumerated within the interface. This happens in interface_add_data()
|
|
|
|
-and the enumerated value is stored in the struct intf_data for that device.
|
|
|
|
-
|
|
|
|
-sysfs
|
|
|
|
-~~~~~
|
|
|
|
-Each interface is given a directory in the directory of the device
|
|
|
|
-class it belongs to:
|
|
|
|
-
|
|
|
|
-Interfaces get a directory in the class's directory as well:
|
|
|
|
-
|
|
|
|
- class/
|
|
|
|
- `-- input
|
|
|
|
- |-- devices
|
|
|
|
- |-- drivers
|
|
|
|
- |-- mouse
|
|
|
|
- `-- evdev
|
|
|
|
-
|
|
|
|
-When a device is added to the interface, a symlink is created that points
|
|
|
|
-to the device's directory in the physical hierarchy:
|
|
|
|
-
|
|
|
|
- class/
|
|
|
|
- `-- input
|
|
|
|
- |-- devices
|
|
|
|
- | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
|
|
|
|
- |-- drivers
|
|
|
|
- | `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/
|
|
|
|
- |-- mouse
|
|
|
|
- | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
|
|
|
|
- `-- evdev
|
|
|
|
- `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Future Plans
|
|
|
|
-~~~~~~~~~~~~
|
|
|
|
-A device interface is correlated directly with a userspace interface
|
|
|
|
-for a device, specifically a device node. For instance, a SCSI disk
|
|
|
|
-exposes at least two interfaces to userspace: the standard SCSI disk
|
|
|
|
-interface and the SCSI generic interface. It might also export a raw
|
|
|
|
-device interface.
|
|
|
|
-
|
|
|
|
-Many interfaces have a major number associated with them and each
|
|
|
|
-device gets a minor number. Or, multiple interfaces might share one
|
|
|
|
-major number, and each will receive a range of minor numbers (like in
|
|
|
|
-the case of input devices).
|
|
|
|
-
|
|
|
|
-These major and minor numbers could be stored in the interface
|
|
|
|
-structure. Major and minor allocations could happen when the interface
|
|
|
|
-is registered with the class, or via a helper function.
|
|
|
|
-
|
|
|