@@ -151,16 +151,195 @@ the more significant 4-byte word.
151
151
We always think of our offsets as if there were no quirk, and we translate
152
152
them afterwards, before accessing the memory region.
153
153
154
+ Note on buffer lengths not multiple of 4
155
+ ----------------------------------------
156
+
157
+ To deal with memory layout quirks where groups of 4 bytes are laid out "little
158
+ endian" relative to each other, but "big endian" within the group itself, the
159
+ concept of groups of 4 bytes is intrinsic to the packing API (not to be
160
+ confused with the memory access, which is performed byte by byte, though).
161
+
162
+ With buffer lengths not multiple of 4, this means one group will be incomplete.
163
+ Depending on the quirks, this may lead to discontinuities in the bit fields
164
+ accessible through the buffer. The packing API assumes discontinuities were not
165
+ the intention of the memory layout, so it avoids them by effectively logically
166
+ shortening the most significant group of 4 octets to the number of octets
167
+ actually available.
168
+
169
+ Example with a 31 byte sized buffer given below. Physical buffer offsets are
170
+ implicit, and increase from left to right within a group, and from top to
171
+ bottom within a column.
172
+
173
+ No quirks:
174
+
175
+ ::
176
+
177
+ 31 29 28 | Group 7 (most significant)
178
+ 27 26 25 24 | Group 6
179
+ 23 22 21 20 | Group 5
180
+ 19 18 17 16 | Group 4
181
+ 15 14 13 12 | Group 3
182
+ 11 10 9 8 | Group 2
183
+ 7 6 5 4 | Group 1
184
+ 3 2 1 0 | Group 0 (least significant)
185
+
186
+ QUIRK_LSW32_IS_FIRST:
187
+
188
+ ::
189
+
190
+ 3 2 1 0 | Group 0 (least significant)
191
+ 7 6 5 4 | Group 1
192
+ 11 10 9 8 | Group 2
193
+ 15 14 13 12 | Group 3
194
+ 19 18 17 16 | Group 4
195
+ 23 22 21 20 | Group 5
196
+ 27 26 25 24 | Group 6
197
+ 30 29 28 | Group 7 (most significant)
198
+
199
+ QUIRK_LITTLE_ENDIAN:
200
+
201
+ ::
202
+
203
+ 30 28 29 | Group 7 (most significant)
204
+ 24 25 26 27 | Group 6
205
+ 20 21 22 23 | Group 5
206
+ 16 17 18 19 | Group 4
207
+ 12 13 14 15 | Group 3
208
+ 8 9 10 11 | Group 2
209
+ 4 5 6 7 | Group 1
210
+ 0 1 2 3 | Group 0 (least significant)
211
+
212
+ QUIRK_LITTLE_ENDIAN | QUIRK_LSW32_IS_FIRST:
213
+
214
+ ::
215
+
216
+ 0 1 2 3 | Group 0 (least significant)
217
+ 4 5 6 7 | Group 1
218
+ 8 9 10 11 | Group 2
219
+ 12 13 14 15 | Group 3
220
+ 16 17 18 19 | Group 4
221
+ 20 21 22 23 | Group 5
222
+ 24 25 26 27 | Group 6
223
+ 28 29 30 | Group 7 (most significant)
224
+
154
225
Intended use
155
226
------------
156
227
157
228
Drivers that opt to use this API first need to identify which of the above 3
158
229
quirk combinations (for a total of 8) match what the hardware documentation
159
- describes. Then they should wrap the packing() function, creating a new
160
- xxx_packing() that calls it using the proper QUIRK_* one-hot bits set.
230
+ describes.
231
+
232
+ There are 3 supported usage patterns, detailed below.
233
+
234
+ packing()
235
+ ^^^^^^^^^
236
+
237
+ This API function is deprecated.
161
238
162
239
The packing() function returns an int-encoded error code, which protects the
163
240
programmer against incorrect API use. The errors are not expected to occur
164
- durring runtime, therefore it is reasonable for xxx_packing() to return void
165
- and simply swallow those errors. Optionally it can dump stack or print the
166
- error description.
241
+ during runtime, therefore it is reasonable to wrap packing() into a custom
242
+ function which returns void and swallows those errors. Optionally it can
243
+ dump stack or print the error description.
244
+
245
+ .. code-block :: c
246
+
247
+ void my_packing(void *buf, u64 *val, int startbit, int endbit,
248
+ size_t len, enum packing_op op)
249
+ {
250
+ int err;
251
+
252
+ /* Adjust quirks accordingly */
253
+ err = packing(buf, val, startbit, endbit, len, op, QUIRK_LSW32_IS_FIRST);
254
+ if (likely(!err))
255
+ return;
256
+
257
+ if (err == -EINVAL) {
258
+ pr_err("Start bit (%d) expected to be larger than end (%d)\n",
259
+ startbit, endbit);
260
+ } else if (err == -ERANGE) {
261
+ if ((startbit - endbit + 1) > 64)
262
+ pr_err("Field %d-%d too large for 64 bits!\n",
263
+ startbit, endbit);
264
+ else
265
+ pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
266
+ *val, startbit, endbit);
267
+ }
268
+ dump_stack();
269
+ }
270
+
271
+ pack() and unpack()
272
+ ^^^^^^^^^^^^^^^^^^^
273
+
274
+ These are const-correct variants of packing(), and eliminate the last "enum
275
+ packing_op op" argument.
276
+
277
+ Calling pack(...) is equivalent, and preferred, to calling packing(..., PACK).
278
+
279
+ Calling unpack(...) is equivalent, and preferred, to calling packing(..., UNPACK).
280
+
281
+ pack_fields() and unpack_fields()
282
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283
+
284
+ The library exposes optimized functions for the scenario where there are many
285
+ fields represented in a buffer, and it encourages consumer drivers to avoid
286
+ repetitive calls to pack() and unpack() for each field, but instead use
287
+ pack_fields() and unpack_fields(), which reduces the code footprint.
288
+
289
+ These APIs use field definitions in arrays of ``struct packed_field_u8 `` or
290
+ ``struct packed_field_u16 ``, allowing consumer drivers to minimize the size
291
+ of these arrays according to their custom requirements.
292
+
293
+ The pack_fields() and unpack_fields() API functions are actually macros which
294
+ automatically select the appropriate function at compile time, based on the
295
+ type of the fields array passed in.
296
+
297
+ An additional benefit over pack() and unpack() is that sanity checks on the
298
+ field definitions are handled at compile time with ``BUILD_BUG_ON `` rather
299
+ than only when the offending code is executed. These functions return void and
300
+ wrapping them to handle unexpected errors is not necessary.
301
+
302
+ It is recommended, but not required, that you wrap your packed buffer into a
303
+ structured type with a fixed size. This generally makes it easier for the
304
+ compiler to enforce that the correct size buffer is used.
305
+
306
+ Here is an example of how to use the fields APIs:
307
+
308
+ .. code-block :: c
309
+
310
+ /* Ordering inside the unpacked structure is flexible and can be different
311
+ * from the packed buffer. Here, it is optimized to reduce padding.
312
+ */
313
+ struct data {
314
+ u64 field3;
315
+ u32 field4;
316
+ u16 field1;
317
+ u8 field2;
318
+ };
319
+
320
+ #define SIZE 13
321
+
322
+ typdef struct __packed { u8 buf[SIZE]; } packed_buf_t;
323
+
324
+ static const struct packed_field_u8 fields[] = {
325
+ PACKED_FIELD(100, 90, struct data, field1),
326
+ PACKED_FIELD(90, 87, struct data, field2),
327
+ PACKED_FIELD(86, 30, struct data, field3),
328
+ PACKED_FIELD(29, 0, struct data, field4),
329
+ };
330
+
331
+ void unpack_your_data(const packed_buf_t *buf, struct data *unpacked)
332
+ {
333
+ BUILD_BUG_ON(sizeof(*buf) != SIZE;
334
+
335
+ unpack_fields(buf, sizeof(*buf), unpacked, fields,
336
+ QUIRK_LITTLE_ENDIAN);
337
+ }
338
+
339
+ void pack_your_data(const struct data *unpacked, packed_buf_t *buf)
340
+ {
341
+ BUILD_BUG_ON(sizeof(*buf) != SIZE;
342
+
343
+ pack_fields(buf, sizeof(*buf), unpacked, fields,
344
+ QUIRK_LITTLE_ENDIAN);
345
+ }
0 commit comments