1ddi_device_acc_attr(9S) Data Structures for Drivers ddi_device_acc_attr(9S)
2
3
4
6 ddi_device_acc_attr - data access attributes structure
7
9 #include <sys/ddi.h>
10 #include <sys/sunddi.h>
11
12
14 Solaris DDI specific (Solaris DDI)
15
17 The ddi_device_acc_attr structure describes the data access character‐
18 istics and requirements of the device.
19
21 ushort_t devacc_attr_version;
22 uchar_t devacc_attr_endian_flags;
23 uchar_t devacc_attr_dataorder;
24 uchar_t devacc_attr_access;
25
26
27
28 The devacc_attr_version member identifies the version number of this
29 structure. The current version number is DDI_DEVICE_ATTR_V0.
30
31
32 The devacc_attr_endian_flags member describes the endian characteris‐
33 tics of the device. Specify one of the following values:
34
35 DDI_NEVERSWAP_ACC Data access with no byte swapping
36
37
38 DDI_STRUCTURE_BE_ACC Structural data access in big-endian format
39
40
41 DDI_STRUCTURE_LE_ACC Structural data access in little endian format
42
43
44
45 DDI_STRUCTURE_BE_ACC and DDI_STRUCTURE_LE_ACC describe the endian char‐
46 acteristics of the device as big-endian or little-endian, respectively.
47 Although most of the devices have the same endian characteristics as
48 their buses, examples of devices that have opposite endian characteris‐
49 tics of the buses do exist. When DDI_STRUCTURE_BE_ACC or DDI_STRUC‐
50 TURE_LE_ACC is set, byte swapping is automatically performed by the
51 system if the host machine and the device data formats have opposite
52 endian characteristics. The implementation can take advantage of hard‐
53 ware platform byte swapping capabilities.
54
55
56 When you specify DDI_NEVERSWAP_ACC, byte swapping is not invoked in the
57 data access functions.
58
59
60 The devacc_attr_dataorder member describes the order in which the CPU
61 references data. Specify one of the following values.
62
63 DDI_STRICTORDER_ACC Data references must be issued by a CPU in
64 program order. Strict ordering is the
65 default behavior.
66
67
68 DDI_UNORDERED_OK_ACC The CPU can reorder the data references.
69 This includes all kinds of reordering. For
70 example, a load followed by a store might be
71 replaced by a store followed by a load.
72
73
74 DDI_MERGING_OK_ACC The CPU can merge individual stores to con‐
75 secutive locations. For example, the CPU can
76 turn two consecutive byte stores into one
77 half-word store. It can also batch individ‐
78 ual loads. For example, the CPU might turn
79 two consecutive byte loads into one half-
80 word load. DDI_MERGING_OK_ACC also implies
81 reordering.
82
83
84 DDI_LOADCACHING_OK_ACC The CPU can cache the data it fetches and
85 reuse it until another store occurs. The
86 default behavior is to fetch new data on
87 every load. DDI_LOADCACHING_OK_ACC also
88 implies merging and reordering.
89
90
91 DDI_STORECACHING_OK_ACC The CPU can keep the data in the cache and
92 push it to the device, perhaps with other
93 data, at a later time. The default behavior
94 is to push the data right away. DDI_STORE‐
95 CACHING_OK_ACC also implies load caching,
96 merging, and reordering.
97
98
99
100 These values are advisory, not mandatory. For example, data can be
101 ordered without being merged, or cached, even though a driver requests
102 unordered, merged, and cached together.
103
104
105 The values defined for devacc_attr_access are:
106
107 DDI_DEFAULT_ACC If an I/O fault occurs, the system will take the
108 default action, which might be to panic.
109
110
111 DDI_FLAGERR_ACC Using this value indicates that the driver is hard‐
112 ened: able to cope with the incorrect results of
113 I/O operations that might result from an I/O fault.
114 The value also indicates that the driver will use
115 ddi_fm_acc_err_get(9F) to check access handles for
116 faults on a regular basis.
117
118 If possible, the system should not panic on such an
119 I/O fault, but should instead mark the I/O handle
120 through which the access was made as having
121 faulted.
122
123 This value is advisory: it tells the system that
124 the driver can continue in the face of I/O faults.
125 The value does not guarantee that the system will
126 not panic, as that depends on the nature of the
127 fault and the capabilities of the system. It is
128 quite legitimate for an implementation to ignore
129 this flag and panic anyway.
130
131
132 DDI_CAUTIOUS_ACC This value indicates that an I/O fault is antici‐
133 pated and should be handled as gracefully as possi‐
134 ble. For example, the framework should not print a
135 console message.
136
137 This value should be used when it is not certain
138 that a device is physically present: for example,
139 when probing. As such, it provides an alternative
140 within the DDI access framework to the existing
141 peek/poke functions, which don't use access handles
142 and cannot be integrated easily into a more general
143 I/O fault handling framework.
144
145 In order to guarantee safe recovery from an I/O
146 fault, it might be necessary to acquire exclusive
147 access to the parent bus, for example, or to syn‐
148 chronize across processors on an MP machine. "Cau‐
149 tious" access can be quite expensive and is only
150 recommended for initial probing and possibly for
151 additional fault-recovery code.
152
153
155 The following examples illustrate the use of device register address
156 mapping setup functions and different data access functions.
157
158 Example 1 Using ddi_device_acc_attr() in >ddi_regs_map_setup(9F)
159
160
161 This example demonstrates the use of the ddi_device_acc_attr() struc‐
162 ture in ddi_regs_map_setup(9F). It also shows the use of ddi_getw(9F)
163 and ddi_putw(9F) functions in accessing the register contents.
164
165
166 dev_info_t *dip;
167 uint_t rnumber;
168 ushort_t *dev_addr;
169 offset_t offset;
170 offset_t len;
171 ushort_t dev_command;
172 ddi_device_acc_attr_t dev_attr;
173 ddi_acc_handle_t handle;
174
175 ...
176
177 /*
178 * setup the device attribute structure for little endian,
179 * strict ordering and 16-bit word access.
180 */
181 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
182 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
183 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
184
185 /*
186 * set up the device registers address mapping
187 */
188 ddi_regs_map_setup(dip, rnumber, (caddr_t *)&dev_addr, offset, len,
189 &dev_attr, &handle);
190
191 /* read a 16-bit word command register from the device */
192 dev_command = ddi_getw(handle, dev_addr);
193
194 dev_command |= DEV_INTR_ENABLE;
195 /* store a new value back to the device command register */
196 ddi_putw(handle, dev_addr, dev_command);
197
198
199 Example 2 Accessing a Device with Different Apertures
200
201
202 The following example illustrates the steps used to access a device
203 with different apertures. Several apertures are assumed to be grouped
204 under one single "reg" entry. For example, the sample device has four
205 different apertures, each 32 Kbyte in size. The apertures represent
206 YUV little-endian, YUV big-endian, RGB little-endian, and RGB big-
207 endian. This sample device uses entry 1 of the "reg" property list for
208 this purpose. The size of the address space is 128 Kbyte with each 32
209 Kbyte range as a separate aperture. In the register mapping setup func‐
210 tion, the sample driver uses the offset and len parameters to specify
211 one of the apertures.
212
213
214 ulong_t *dev_addr;
215 ddi_device_acc_attr_t dev_attr;
216 ddi_acc_handle_t handle;
217 uchar_t buf[256];
218
219 ...
220
221 /*
222 * setup the device attribute structure for never swap,
223 * unordered and 32-bit word access.
224 */
225 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
226 dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
227 dev_attr.devacc_attr_dataorder = DDI_UNORDERED_OK_ACC;
228
229 /*
230 * map in the RGB big-endian aperture
231 * while running in a big endian machine
232 * - offset 96K and len 32K
233 */
234 ddi_regs_map_setup(dip, 1, (caddr_t *)&dev_addr, 96*1024, 32*1024,
235 &dev_attr, &handle);
236
237 /*
238 * Write to the screen buffer
239 * first 1K bytes words, each size 4 bytes
240 */
241 ddi_rep_putl(handle, buf, dev_addr, 256, DDI_DEV_AUTOINCR);
242
243
244 Example 3 Functions That Call Out the Data Word Size
245
246
247 The following example illustrates the use of the functions that explic‐
248 itly call out the data word size to override the data size in the
249 device attribute structure.
250
251
252 struct device_blk {
253 ushort_t d_command; /* command register */
254 ushort_t d_status; /* status register */
255 ulong d_data; /* data register */
256 } *dev_blkp;
257 dev_info_t *dip;
258 caddr_t dev_addr;
259 ddi_device_acc_attr_t dev_attr;
260 ddi_acc_handle_t handle;
261 uchar_t buf[256];
262
263 ...
264
265 /*
266 * setup the device attribute structure for never swap,
267 * strict ordering and 32-bit word access.
268 */
269 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
270 dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
271 dev_attr.devacc_attr_dataorder= DDI_STRICTORDER_ACC;
272
273 ddi_regs_map_setup(dip, 1, (caddr_t *)&dev_blkp, 0, 0,
274 &dev_attr, &handle);
275
276 /* write command to the 16-bit command register */
277 ddi_putw(handle, &dev_blkp->d_command, START_XFER);
278
279 /* Read the 16-bit status register */
280 status = ddi_getw(handle, &dev_blkp->d_status);
281
282 if (status & DATA_READY)
283 /* Read 1K bytes off the 32-bit data register */
284 ddi_rep_getl(handle, buf, &dev_blkp->d_data,
285 256, DDI_DEV_NO_AUTOINCR);
286
287
289 See attributes(5) for descriptions of the following attributes:
290
291
292
293
294 ┌─────────────────────────────┬─────────────────────────────┐
295 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
296 ├─────────────────────────────┼─────────────────────────────┤
297 │Interface Stability │Committed │
298 └─────────────────────────────┴─────────────────────────────┘
299
301 attributes(5), ddi_fm_acc_err_get(9F), ddi_getw(9F), ddi_putw(9F),
302 ddi_regs_map_setup(9F)
303
304
305 Writing Device Drivers
306
307
308
309SunOS 5.11 13 May 2007 ddi_device_acc_attr(9S)