diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/driver-model/class.txt |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'Documentation/driver-model/class.txt')
-rw-r--r-- | Documentation/driver-model/class.txt | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/Documentation/driver-model/class.txt b/Documentation/driver-model/class.txt new file mode 100644 index 000000000000..2d1d893a5e5d --- /dev/null +++ b/Documentation/driver-model/class.txt | |||
@@ -0,0 +1,162 @@ | |||
1 | |||
2 | Device Classes | ||
3 | |||
4 | |||
5 | Introduction | ||
6 | ~~~~~~~~~~~~ | ||
7 | A device class describes a type of device, like an audio or network | ||
8 | device. The following device classes have been identified: | ||
9 | |||
10 | <Insert List of Device Classes Here> | ||
11 | |||
12 | |||
13 | Each device class defines a set of semantics and a programming interface | ||
14 | that devices of that class adhere to. Device drivers are the | ||
15 | implemention of that programming interface for a particular device on | ||
16 | a particular bus. | ||
17 | |||
18 | Device classes are agnostic with respect to what bus a device resides | ||
19 | on. | ||
20 | |||
21 | |||
22 | Programming Interface | ||
23 | ~~~~~~~~~~~~~~~~~~~~~ | ||
24 | The device class structure looks like: | ||
25 | |||
26 | |||
27 | typedef int (*devclass_add)(struct device *); | ||
28 | typedef void (*devclass_remove)(struct device *); | ||
29 | |||
30 | struct device_class { | ||
31 | char * name; | ||
32 | rwlock_t lock; | ||
33 | u32 devnum; | ||
34 | struct list_head node; | ||
35 | |||
36 | struct list_head drivers; | ||
37 | struct list_head intf_list; | ||
38 | |||
39 | struct driver_dir_entry dir; | ||
40 | struct driver_dir_entry device_dir; | ||
41 | struct driver_dir_entry driver_dir; | ||
42 | |||
43 | devclass_add add_device; | ||
44 | devclass_remove remove_device; | ||
45 | }; | ||
46 | |||
47 | A typical device class definition would look like: | ||
48 | |||
49 | struct device_class input_devclass = { | ||
50 | .name = "input", | ||
51 | .add_device = input_add_device, | ||
52 | .remove_device = input_remove_device, | ||
53 | }; | ||
54 | |||
55 | Each device class structure should be exported in a header file so it | ||
56 | can be used by drivers, extensions and interfaces. | ||
57 | |||
58 | Device classes are registered and unregistered with the core using: | ||
59 | |||
60 | int devclass_register(struct device_class * cls); | ||
61 | void devclass_unregister(struct device_class * cls); | ||
62 | |||
63 | |||
64 | Devices | ||
65 | ~~~~~~~ | ||
66 | As devices are bound to drivers, they are added to the device class | ||
67 | that the driver belongs to. Before the driver model core, this would | ||
68 | typically happen during the driver's probe() callback, once the device | ||
69 | has been initialized. It now happens after the probe() callback | ||
70 | finishes from the core. | ||
71 | |||
72 | The device is enumerated in the class. Each time a device is added to | ||
73 | the class, the class's devnum field is incremented and assigned to the | ||
74 | device. The field is never decremented, so if the device is removed | ||
75 | from the class and re-added, it will receive a different enumerated | ||
76 | value. | ||
77 | |||
78 | The class is allowed to create a class-specific structure for the | ||
79 | device and store it in the device's class_data pointer. | ||
80 | |||
81 | There is no list of devices in the device class. Each driver has a | ||
82 | list of devices that it supports. The device class has a list of | ||
83 | drivers of that particular class. To access all of the devices in the | ||
84 | class, iterate over the device lists of each driver in the class. | ||
85 | |||
86 | |||
87 | Device Drivers | ||
88 | ~~~~~~~~~~~~~~ | ||
89 | Device drivers are added to device classes when they are registered | ||
90 | with the core. A driver specifies the class it belongs to by setting | ||
91 | the struct device_driver::devclass field. | ||
92 | |||
93 | |||
94 | sysfs directory structure | ||
95 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
96 | There is a top-level sysfs directory named 'class'. | ||
97 | |||
98 | Each class gets a directory in the class directory, along with two | ||
99 | default subdirectories: | ||
100 | |||
101 | class/ | ||
102 | `-- input | ||
103 | |-- devices | ||
104 | `-- drivers | ||
105 | |||
106 | |||
107 | Drivers registered with the class get a symlink in the drivers/ directory | ||
108 | that points to the driver's directory (under its bus directory): | ||
109 | |||
110 | class/ | ||
111 | `-- input | ||
112 | |-- devices | ||
113 | `-- drivers | ||
114 | `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ | ||
115 | |||
116 | |||
117 | Each device gets a symlink in the devices/ directory that points to the | ||
118 | device's directory in the physical hierarchy: | ||
119 | |||
120 | class/ | ||
121 | `-- input | ||
122 | |-- devices | ||
123 | | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ | ||
124 | `-- drivers | ||
125 | |||
126 | |||
127 | Exporting Attributes | ||
128 | ~~~~~~~~~~~~~~~~~~~~ | ||
129 | struct devclass_attribute { | ||
130 | struct attribute attr; | ||
131 | ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off); | ||
132 | ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off); | ||
133 | }; | ||
134 | |||
135 | Class drivers can export attributes using the DEVCLASS_ATTR macro that works | ||
136 | similarly to the DEVICE_ATTR macro for devices. For example, a definition | ||
137 | like this: | ||
138 | |||
139 | static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); | ||
140 | |||
141 | is equivalent to declaring: | ||
142 | |||
143 | static devclass_attribute devclass_attr_debug; | ||
144 | |||
145 | The bus driver can add and remove the attribute from the class's | ||
146 | sysfs directory using: | ||
147 | |||
148 | int devclass_create_file(struct device_class *, struct devclass_attribute *); | ||
149 | void devclass_remove_file(struct device_class *, struct devclass_attribute *); | ||
150 | |||
151 | In the example above, the file will be named 'debug' in placed in the | ||
152 | class's directory in sysfs. | ||
153 | |||
154 | |||
155 | Interfaces | ||
156 | ~~~~~~~~~~ | ||
157 | There may exist multiple mechanisms for accessing the same device of a | ||
158 | particular class type. Device interfaces describe these mechanisms. | ||
159 | |||
160 | When a device is added to a device class, the core attempts to add it | ||
161 | to every interface that is registered with the device class. | ||
162 | |||