Commit | Line | Data |
---|---|---|
4489f161 | 1 | ========================== |
1da177e4 | 2 | The Basic Device Structure |
4489f161 | 3 | ========================== |
1da177e4 | 4 | |
63dc355a | 5 | See the kerneldoc for the struct device. |
1da177e4 LT |
6 | |
7 | ||
8 | Programming Interface | |
9 | ~~~~~~~~~~~~~~~~~~~~~ | |
10 | The bus driver that discovers the device uses this to register the | |
4489f161 | 11 | device with the core:: |
1da177e4 | 12 | |
4489f161 | 13 | int device_register(struct device * dev); |
1da177e4 LT |
14 | |
15 | The bus should initialize the following fields: | |
16 | ||
17 | - parent | |
18 | - name | |
19 | - bus_id | |
20 | - bus | |
21 | ||
22 | A device is removed from the core when its reference count goes to | |
4489f161 | 23 | 0. The reference count can be adjusted using:: |
1da177e4 | 24 | |
4489f161 MCC |
25 | struct device * get_device(struct device * dev); |
26 | void put_device(struct device * dev); | |
1da177e4 LT |
27 | |
28 | get_device() will return a pointer to the struct device passed to it | |
29 | if the reference is not already 0 (if it's in the process of being | |
30 | removed already). | |
31 | ||
4489f161 | 32 | A driver can access the lock in the device structure using:: |
1da177e4 | 33 | |
4489f161 MCC |
34 | void lock_device(struct device * dev); |
35 | void unlock_device(struct device * dev); | |
1da177e4 LT |
36 | |
37 | ||
38 | Attributes | |
39 | ~~~~~~~~~~ | |
4489f161 MCC |
40 | |
41 | :: | |
42 | ||
43 | struct device_attribute { | |
245127db MM |
44 | struct attribute attr; |
45 | ssize_t (*show)(struct device *dev, struct device_attribute *attr, | |
46 | char *buf); | |
47 | ssize_t (*store)(struct device *dev, struct device_attribute *attr, | |
48 | const char *buf, size_t count); | |
4489f161 | 49 | }; |
1da177e4 | 50 | |
d58cb9cc | 51 | Attributes of devices can be exported by a device driver through sysfs. |
1da177e4 LT |
52 | |
53 | Please see Documentation/filesystems/sysfs.txt for more information | |
54 | on how sysfs works. | |
55 | ||
829f4c36 | 56 | As explained in Documentation/kobject.txt, device attributes must be |
d58cb9cc BVA |
57 | created before the KOBJ_ADD uevent is generated. The only way to realize |
58 | that is by defining an attribute group. | |
59 | ||
4489f161 | 60 | Attributes are declared using a macro called DEVICE_ATTR:: |
1da177e4 | 61 | |
4489f161 | 62 | #define DEVICE_ATTR(name,mode,show,store) |
1da177e4 | 63 | |
4489f161 | 64 | Example::: |
1da177e4 | 65 | |
4489f161 MCC |
66 | static DEVICE_ATTR(type, 0444, show_type, NULL); |
67 | static DEVICE_ATTR(power, 0644, show_power, store_power); | |
1da177e4 | 68 | |
d58cb9cc BVA |
69 | This declares two structures of type struct device_attribute with respective |
70 | names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be | |
4489f161 | 71 | organized as follows into a group:: |
1da177e4 | 72 | |
4489f161 | 73 | static struct attribute *dev_attrs[] = { |
d58cb9cc BVA |
74 | &dev_attr_type.attr, |
75 | &dev_attr_power.attr, | |
76 | NULL, | |
4489f161 | 77 | }; |
1da177e4 | 78 | |
4489f161 | 79 | static struct attribute_group dev_attr_group = { |
d58cb9cc | 80 | .attrs = dev_attrs, |
4489f161 | 81 | }; |
d58cb9cc | 82 | |
4489f161 | 83 | static const struct attribute_group *dev_attr_groups[] = { |
d58cb9cc BVA |
84 | &dev_attr_group, |
85 | NULL, | |
4489f161 | 86 | }; |
d58cb9cc BVA |
87 | |
88 | This array of groups can then be associated with a device by setting the | |
4489f161 | 89 | group pointer in struct device before device_register() is invoked:: |
1da177e4 | 90 | |
4489f161 MCC |
91 | dev->groups = dev_attr_groups; |
92 | device_register(dev); | |
1da177e4 | 93 | |
d58cb9cc BVA |
94 | The device_register() function will use the 'groups' pointer to create the |
95 | device attributes and the device_unregister() function will use this pointer | |
96 | to remove the device attributes. | |
1da177e4 | 97 | |
b22813b3 GL |
98 | Word of warning: While the kernel allows device_create_file() and |
99 | device_remove_file() to be called on a device at any time, userspace has | |
100 | strict expectations on when attributes get created. When a new device is | |
101 | registered in the kernel, a uevent is generated to notify userspace (like | |
102 | udev) that a new device is available. If attributes are added after the | |
103 | device is registered, then userspace won't get notified and userspace will | |
104 | not know about the new attributes. | |
105 | ||
106 | This is important for device driver that need to publish additional | |
107 | attributes for a device at driver probe time. If the device driver simply | |
108 | calls device_create_file() on the device structure passed to it, then | |
d58cb9cc | 109 | userspace will never be notified of the new attributes. |