Root/
1 | |
2 | Bus Types |
3 | |
4 | Definition |
5 | ~~~~~~~~~~ |
6 | |
7 | struct bus_type { |
8 | char * name; |
9 | |
10 | struct subsystem subsys; |
11 | struct kset drivers; |
12 | struct kset devices; |
13 | |
14 | struct bus_attribute * bus_attrs; |
15 | struct device_attribute * dev_attrs; |
16 | struct driver_attribute * drv_attrs; |
17 | |
18 | int (*match)(struct device * dev, struct device_driver * drv); |
19 | int (*hotplug) (struct device *dev, char **envp, |
20 | int num_envp, char *buffer, int buffer_size); |
21 | int (*suspend)(struct device * dev, pm_message_t state); |
22 | int (*resume)(struct device * dev); |
23 | }; |
24 | |
25 | int bus_register(struct bus_type * bus); |
26 | |
27 | |
28 | Declaration |
29 | ~~~~~~~~~~~ |
30 | |
31 | Each bus type in the kernel (PCI, USB, etc) should declare one static |
32 | object of this type. They must initialize the name field, and may |
33 | optionally initialize the match callback. |
34 | |
35 | struct bus_type pci_bus_type = { |
36 | .name = "pci", |
37 | .match = pci_bus_match, |
38 | }; |
39 | |
40 | The structure should be exported to drivers in a header file: |
41 | |
42 | extern struct bus_type pci_bus_type; |
43 | |
44 | |
45 | Registration |
46 | ~~~~~~~~~~~~ |
47 | |
48 | When a bus driver is initialized, it calls bus_register. This |
49 | initializes the rest of the fields in the bus object and inserts it |
50 | into a global list of bus types. Once the bus object is registered, |
51 | the fields in it are usable by the bus driver. |
52 | |
53 | |
54 | Callbacks |
55 | ~~~~~~~~~ |
56 | |
57 | match(): Attaching Drivers to Devices |
58 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
59 | |
60 | The format of device ID structures and the semantics for comparing |
61 | them are inherently bus-specific. Drivers typically declare an array |
62 | of device IDs of devices they support that reside in a bus-specific |
63 | driver structure. |
64 | |
65 | The purpose of the match callback is provide the bus an opportunity to |
66 | determine if a particular driver supports a particular device by |
67 | comparing the device IDs the driver supports with the device ID of a |
68 | particular device, without sacrificing bus-specific functionality or |
69 | type-safety. |
70 | |
71 | When a driver is registered with the bus, the bus's list of devices is |
72 | iterated over, and the match callback is called for each device that |
73 | does not have a driver associated with it. |
74 | |
75 | |
76 | |
77 | Device and Driver Lists |
78 | ~~~~~~~~~~~~~~~~~~~~~~~ |
79 | |
80 | The lists of devices and drivers are intended to replace the local |
81 | lists that many buses keep. They are lists of struct devices and |
82 | struct device_drivers, respectively. Bus drivers are free to use the |
83 | lists as they please, but conversion to the bus-specific type may be |
84 | necessary. |
85 | |
86 | The LDM core provides helper functions for iterating over each list. |
87 | |
88 | int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, |
89 | int (*fn)(struct device *, void *)); |
90 | |
91 | int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, |
92 | void * data, int (*fn)(struct device_driver *, void *)); |
93 | |
94 | These helpers iterate over the respective list, and call the callback |
95 | for each device or driver in the list. All list accesses are |
96 | synchronized by taking the bus's lock (read currently). The reference |
97 | count on each object in the list is incremented before the callback is |
98 | called; it is decremented after the next object has been obtained. The |
99 | lock is not held when calling the callback. |
100 | |
101 | |
102 | sysfs |
103 | ~~~~~~~~ |
104 | There is a top-level directory named 'bus'. |
105 | |
106 | Each bus gets a directory in the bus directory, along with two default |
107 | directories: |
108 | |
109 | /sys/bus/pci/ |
110 | |-- devices |
111 | `-- drivers |
112 | |
113 | Drivers registered with the bus get a directory in the bus's drivers |
114 | directory: |
115 | |
116 | /sys/bus/pci/ |
117 | |-- devices |
118 | `-- drivers |
119 | |-- Intel ICH |
120 | |-- Intel ICH Joystick |
121 | |-- agpgart |
122 | `-- e100 |
123 | |
124 | Each device that is discovered on a bus of that type gets a symlink in |
125 | the bus's devices directory to the device's directory in the physical |
126 | hierarchy: |
127 | |
128 | /sys/bus/pci/ |
129 | |-- devices |
130 | | |-- 00:00.0 -> ../../../root/pci0/00:00.0 |
131 | | |-- 00:01.0 -> ../../../root/pci0/00:01.0 |
132 | | `-- 00:02.0 -> ../../../root/pci0/00:02.0 |
133 | `-- drivers |
134 | |
135 | |
136 | Exporting Attributes |
137 | ~~~~~~~~~~~~~~~~~~~~ |
138 | struct bus_attribute { |
139 | struct attribute attr; |
140 | ssize_t (*show)(struct bus_type *, char * buf); |
141 | ssize_t (*store)(struct bus_type *, const char * buf, size_t count); |
142 | }; |
143 | |
144 | Bus drivers can export attributes using the BUS_ATTR macro that works |
145 | similarly to the DEVICE_ATTR macro for devices. For example, a definition |
146 | like this: |
147 | |
148 | static BUS_ATTR(debug,0644,show_debug,store_debug); |
149 | |
150 | is equivalent to declaring: |
151 | |
152 | static bus_attribute bus_attr_debug; |
153 | |
154 | This can then be used to add and remove the attribute from the bus's |
155 | sysfs directory using: |
156 | |
157 | int bus_create_file(struct bus_type *, struct bus_attribute *); |
158 | void bus_remove_file(struct bus_type *, struct bus_attribute *); |
159 | |
160 | |
161 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9