Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 |