@@ -51,64 +51,20 @@ static size_t calculate_box_addr(size_t box, size_t len, u8 quirks)
5151 return offset_of_group + offset_in_group ;
5252}
5353
54- /**
55- * pack - Pack u64 number into bitfield of buffer.
56- *
57- * @pbuf: Pointer to a buffer holding the packed value.
58- * @uval: CPU-readable unpacked value to pack.
59- * @startbit: The index (in logical notation, compensated for quirks) where
60- * the packed value starts within pbuf. Must be larger than, or
61- * equal to, endbit.
62- * @endbit: The index (in logical notation, compensated for quirks) where
63- * the packed value ends within pbuf. Must be smaller than, or equal
64- * to, startbit.
65- * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf.
66- * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and
67- * QUIRK_MSB_ON_THE_RIGHT.
68- *
69- * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming
70- * correct usage, return code may be discarded. The @pbuf memory will
71- * be modified on success.
72- */
73- int pack (void * pbuf , u64 uval , size_t startbit , size_t endbit , size_t pbuflen ,
74- u8 quirks )
54+ static void __pack (void * pbuf , u64 uval , size_t startbit , size_t endbit ,
55+ size_t pbuflen , u8 quirks )
7556{
7657 /* Logical byte indices corresponding to the
7758 * start and end of the field.
7859 */
79- int plogical_first_u8 , plogical_last_u8 , box ;
80- /* width of the field to access in the pbuf */
81- u64 value_width ;
82-
83- /* startbit is expected to be larger than endbit, and both are
84- * expected to be within the logically addressable range of the buffer.
85- */
86- if (unlikely (startbit < endbit || startbit >= BITS_PER_BYTE * pbuflen ))
87- /* Invalid function call */
88- return - EINVAL ;
89-
90- value_width = startbit - endbit + 1 ;
91- if (unlikely (value_width > 64 ))
92- return - ERANGE ;
93-
94- /* Check if "uval" fits in "value_width" bits.
95- * If value_width is 64, the check will fail, but any
96- * 64-bit uval will surely fit.
97- */
98- if (unlikely (value_width < 64 && uval >= (1ull << value_width )))
99- /* Cannot store "uval" inside "value_width" bits.
100- * Truncating "uval" is most certainly not desirable,
101- * so simply erroring out is appropriate.
102- */
103- return - ERANGE ;
60+ int plogical_first_u8 = startbit / BITS_PER_BYTE ;
61+ int plogical_last_u8 = endbit / BITS_PER_BYTE ;
62+ int box ;
10463
10564 /* Iterate through an idealistic view of the pbuf as an u64 with
10665 * no quirks, u8 by u8 (aligned at u8 boundaries), from high to low
10766 * logical bit significance. "box" denotes the current logical u8.
10867 */
109- plogical_first_u8 = startbit / BITS_PER_BYTE ;
110- plogical_last_u8 = endbit / BITS_PER_BYTE ;
111-
11268 for (box = plogical_first_u8 ; box >= plogical_last_u8 ; box -- ) {
11369 /* Bit indices into the currently accessed 8-bit box */
11470 size_t box_start_bit , box_end_bit , box_addr ;
@@ -163,15 +119,13 @@ int pack(void *pbuf, u64 uval, size_t startbit, size_t endbit, size_t pbuflen,
163119 ((u8 * )pbuf )[box_addr ] &= ~box_mask ;
164120 ((u8 * )pbuf )[box_addr ] |= pval ;
165121 }
166- return 0 ;
167122}
168- EXPORT_SYMBOL (pack );
169123
170124/**
171- * unpack - Unpack u64 number from packed buffer.
125+ * pack - Pack u64 number into bitfield of buffer.
172126 *
173127 * @pbuf: Pointer to a buffer holding the packed value.
174- * @uval: Pointer to an u64 holding the unpacked value.
128+ * @uval: CPU-readable unpacked value to pack .
175129 * @startbit: The index (in logical notation, compensated for quirks) where
176130 * the packed value starts within pbuf. Must be larger than, or
177131 * equal to, endbit.
@@ -183,16 +137,12 @@ EXPORT_SYMBOL(pack);
183137 * QUIRK_MSB_ON_THE_RIGHT.
184138 *
185139 * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming
186- * correct usage, return code may be discarded. The @uval will be
187- * modified on success.
140+ * correct usage, return code may be discarded. The @pbuf memory will
141+ * be modified on success.
188142 */
189- int unpack ( const void * pbuf , u64 * uval , size_t startbit , size_t endbit ,
190- size_t pbuflen , u8 quirks )
143+ int pack ( void * pbuf , u64 uval , size_t startbit , size_t endbit , size_t pbuflen ,
144+ u8 quirks )
191145{
192- /* Logical byte indices corresponding to the
193- * start and end of the field.
194- */
195- int plogical_first_u8 , plogical_last_u8 , box ;
196146 /* width of the field to access in the pbuf */
197147 u64 value_width ;
198148
@@ -207,16 +157,40 @@ int unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit,
207157 if (unlikely (value_width > 64 ))
208158 return - ERANGE ;
209159
160+ /* Check if "uval" fits in "value_width" bits.
161+ * If value_width is 64, the check will fail, but any
162+ * 64-bit uval will surely fit.
163+ */
164+ if (value_width < 64 && uval >= (1ull << value_width ))
165+ /* Cannot store "uval" inside "value_width" bits.
166+ * Truncating "uval" is most certainly not desirable,
167+ * so simply erroring out is appropriate.
168+ */
169+ return - ERANGE ;
170+
171+ __pack (pbuf , uval , startbit , endbit , pbuflen , quirks );
172+
173+ return 0 ;
174+ }
175+ EXPORT_SYMBOL (pack );
176+
177+ static void __unpack (const void * pbuf , u64 * uval , size_t startbit , size_t endbit ,
178+ size_t pbuflen , u8 quirks )
179+ {
180+ /* Logical byte indices corresponding to the
181+ * start and end of the field.
182+ */
183+ int plogical_first_u8 = startbit / BITS_PER_BYTE ;
184+ int plogical_last_u8 = endbit / BITS_PER_BYTE ;
185+ int box ;
186+
210187 /* Initialize parameter */
211188 * uval = 0 ;
212189
213190 /* Iterate through an idealistic view of the pbuf as an u64 with
214191 * no quirks, u8 by u8 (aligned at u8 boundaries), from high to low
215192 * logical bit significance. "box" denotes the current logical u8.
216193 */
217- plogical_first_u8 = startbit / BITS_PER_BYTE ;
218- plogical_last_u8 = endbit / BITS_PER_BYTE ;
219-
220194 for (box = plogical_first_u8 ; box >= plogical_last_u8 ; box -- ) {
221195 /* Bit indices into the currently accessed 8-bit box */
222196 size_t box_start_bit , box_end_bit , box_addr ;
@@ -271,6 +245,46 @@ int unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit,
271245 * uval &= ~proj_mask ;
272246 * uval |= pval ;
273247 }
248+ }
249+
250+ /**
251+ * unpack - Unpack u64 number from packed buffer.
252+ *
253+ * @pbuf: Pointer to a buffer holding the packed value.
254+ * @uval: Pointer to an u64 holding the unpacked value.
255+ * @startbit: The index (in logical notation, compensated for quirks) where
256+ * the packed value starts within pbuf. Must be larger than, or
257+ * equal to, endbit.
258+ * @endbit: The index (in logical notation, compensated for quirks) where
259+ * the packed value ends within pbuf. Must be smaller than, or equal
260+ * to, startbit.
261+ * @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf.
262+ * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and
263+ * QUIRK_MSB_ON_THE_RIGHT.
264+ *
265+ * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming
266+ * correct usage, return code may be discarded. The @uval will be
267+ * modified on success.
268+ */
269+ int unpack (const void * pbuf , u64 * uval , size_t startbit , size_t endbit ,
270+ size_t pbuflen , u8 quirks )
271+ {
272+ /* width of the field to access in the pbuf */
273+ u64 value_width ;
274+
275+ /* startbit is expected to be larger than endbit, and both are
276+ * expected to be within the logically addressable range of the buffer.
277+ */
278+ if (startbit < endbit || startbit >= BITS_PER_BYTE * pbuflen )
279+ /* Invalid function call */
280+ return - EINVAL ;
281+
282+ value_width = startbit - endbit + 1 ;
283+ if (value_width > 64 )
284+ return - ERANGE ;
285+
286+ __unpack (pbuf , uval , startbit , endbit , pbuflen , quirks );
287+
274288 return 0 ;
275289}
276290EXPORT_SYMBOL (unpack );
0 commit comments