| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 |  | 
 | 2 | Device Interfaces | 
 | 3 |  | 
 | 4 | Introduction | 
 | 5 | ~~~~~~~~~~~~ | 
 | 6 |  | 
 | 7 | Device interfaces are the logical interfaces of device classes that correlate | 
 | 8 | directly to userspace interfaces, like device nodes.  | 
 | 9 |     | 
 | 10 | Each device class may have multiple interfaces through which you can  | 
 | 11 | access the same device. An input device may support the mouse interface,  | 
 | 12 | the 'evdev' interface, and the touchscreen interface. A SCSI disk would  | 
 | 13 | support the disk interface, the SCSI generic interface, and possibly a raw  | 
 | 14 | device interface.  | 
 | 15 |  | 
 | 16 | Device interfaces are registered with the class they belong to. As devices | 
 | 17 | are added to the class, they are added to each interface registered with | 
 | 18 | the class. The interface is responsible for determining whether the device | 
 | 19 | supports the interface or not.  | 
 | 20 |  | 
 | 21 |  | 
 | 22 | Programming Interface | 
 | 23 | ~~~~~~~~~~~~~~~~~~~~~ | 
 | 24 |  | 
 | 25 | struct device_interface { | 
 | 26 | 	char			* name; | 
 | 27 | 	rwlock_t		lock; | 
 | 28 | 	u32			devnum; | 
 | 29 | 	struct device_class	* devclass; | 
 | 30 |  | 
 | 31 | 	struct list_head	node; | 
 | 32 | 	struct driver_dir_entry	dir; | 
 | 33 |  | 
 | 34 | 	int (*add_device)(struct device *); | 
 | 35 | 	int (*add_device)(struct intf_data *); | 
 | 36 | }; | 
 | 37 |  | 
 | 38 | int interface_register(struct device_interface *); | 
 | 39 | void interface_unregister(struct device_interface *); | 
 | 40 |  | 
 | 41 |  | 
 | 42 | An interface must specify the device class it belongs to. It is added | 
 | 43 | to that class's list of interfaces on registration. | 
 | 44 |  | 
 | 45 |  | 
 | 46 | Interfaces can be added to a device class at any time. Whenever it is | 
 | 47 | added, each device in the class is passed to the interface's | 
 | 48 | add_device callback. When an interface is removed, each device is | 
 | 49 | removed from the interface. | 
 | 50 |  | 
 | 51 |  | 
 | 52 | Devices | 
 | 53 | ~~~~~~~ | 
 | 54 | Once a device is added to a device class, it is added to each | 
 | 55 | interface that is registered with the device class. The class | 
 | 56 | is expected to place a class-specific data structure in  | 
 | 57 | struct device::class_data. The interface can use that (along with | 
 | 58 | other fields of struct device) to determine whether or not the driver | 
 | 59 | and/or device support that particular interface. | 
 | 60 |  | 
 | 61 |  | 
 | 62 | Data | 
 | 63 | ~~~~ | 
 | 64 |  | 
 | 65 | struct intf_data { | 
 | 66 | 	struct list_head	node; | 
 | 67 | 	struct device_interface	* intf; | 
 | 68 | 	struct device 		* dev; | 
 | 69 | 	u32			intf_num; | 
 | 70 | }; | 
 | 71 |  | 
 | 72 | int interface_add_data(struct interface_data *); | 
 | 73 |  | 
 | 74 | The interface is responsible for allocating and initializing a struct  | 
 | 75 | intf_data and calling interface_add_data() to add it to the device's list | 
 | 76 | of interfaces it belongs to. This list will be iterated over when the device | 
 | 77 | is removed from the class (instead of all possible interfaces for a class). | 
 | 78 | This structure should probably be embedded in whatever per-device data  | 
 | 79 | structure the interface is allocating anyway. | 
 | 80 |     | 
 | 81 | Devices are enumerated within the interface. This happens in interface_add_data() | 
 | 82 | and the enumerated value is stored in the struct intf_data for that device.  | 
 | 83 |  | 
 | 84 | sysfs | 
 | 85 | ~~~~~ | 
 | 86 | Each interface is given a directory in the directory of the device | 
 | 87 | class it belongs to: | 
 | 88 |  | 
 | 89 | Interfaces get a directory in the class's directory as well: | 
 | 90 |  | 
 | 91 |    class/ | 
 | 92 |    `-- input | 
 | 93 |        |-- devices | 
 | 94 |        |-- drivers | 
 | 95 |        |-- mouse | 
 | 96 |        `-- evdev | 
 | 97 |  | 
 | 98 | When a device is added to the interface, a symlink is created that points  | 
 | 99 | to the device's directory in the physical hierarchy: | 
 | 100 |  | 
 | 101 |    class/ | 
 | 102 |    `-- input | 
 | 103 |        |-- devices | 
 | 104 |        |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ | 
 | 105 |        |-- drivers | 
 | 106 |        |   `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ | 
 | 107 |        |-- mouse | 
 | 108 |        |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ | 
 | 109 |        `-- evdev | 
 | 110 |            `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ | 
 | 111 |  | 
 | 112 |  | 
 | 113 | Future Plans | 
 | 114 | ~~~~~~~~~~~~ | 
 | 115 | A device interface is correlated directly with a userspace interface | 
 | 116 | for a device, specifically a device node. For instance, a SCSI disk | 
 | 117 | exposes at least two interfaces to userspace: the standard SCSI disk | 
 | 118 | interface and the SCSI generic interface. It might also export a raw | 
 | 119 | device interface.  | 
 | 120 |  | 
 | 121 | Many interfaces have a major number associated with them and each | 
 | 122 | device gets a minor number. Or, multiple interfaces might share one | 
 | 123 | major number, and each will receive a range of minor numbers (like in | 
 | 124 | the case of input devices). | 
 | 125 |  | 
 | 126 | These major and minor numbers could be stored in the interface | 
 | 127 | structure. Major and minor allocations could happen when the interface | 
 | 128 | is registered with the class, or via a helper function.  | 
 | 129 |  |