On Mon, Apr 27, 2020 at 05:53:03PM +0300, Sakari Ailus wrote:
Add a printk modifier %p4cc (for pixel format) for printing V4L2 and DRM pixel formats denoted by fourccs. The fourcc encoding is the same for both so the same implementation can be used.
4cc is more generic than pixel format.
...
+V4L2 and DRM FourCC code (pixel format) +---------------------------------------
+::
- %p4cc
Missed examples.
+Print a FourCC code used by V4L2 or DRM, including format endianness and +its numerical value as hexadecimal.
...
+static noinline_for_stack +char *fourcc_string(char *buf, char *end, const u32 *__fourcc,
struct printf_spec spec, const char *fmt)
+{ +#define FOURCC_HEX_CHAR_STR "(xx)" +#define FOURCC_BIG_ENDIAN_STR " big-endian" +#define FOURCC_LITTLE_ENDIAN_STR " little-endian" +#define FOURCC_HEX_NUMBER " (0x01234567)"
Where are #undef:s?
+#define FOURCC_STRING_MAX \
- FOURCC_HEX_CHAR_STR FOURCC_HEX_CHAR_STR FOURCC_HEX_CHAR_STR \
- FOURCC_HEX_CHAR_STR FOURCC_LITTLE_ENDIAN_STR FOURCC_HEX_NUMBER
- struct printf_spec my_spec = {
.type = FORMAT_TYPE_UINT,
.field_width = 2,
.flags = SMALL,
.base = 16,
.precision = -1,
- };
Seems like close enough to bus_spec.
- char __s[sizeof(FOURCC_STRING_MAX)];
- char *s = __s;
- unsigned int i;
- /*
* The 31st bit defines the endianness of the data, so save its printing
* for later.
*/
- u32 fourcc = *__fourcc & ~BIT(31);
- int ret;
- if (check_pointer(&buf, end, __fourcc, spec))
return buf;
- if (fmt[1] != 'c' || fmt[2] != 'c')
return error_string(buf, end, "(%p4?)", spec);
- for (i = 0; i < sizeof(fourcc); i++, fourcc >>= 8) {
unsigned char c = fourcc;
/* Weed out spaces */
if (c == ' ')
continue;
/* Print non-control characters as-is */
if (c > ' ') {
*s = c;
s++;
continue;
}
if (WARN_ON_ONCE(sizeof(__s) <
(s - __s) + sizeof(FOURCC_HEX_CHAR_STR)))
Why WARN?!
break;
*s = '(';
s++;
s = number(s, s + 2, c, my_spec);
*s = ')';
s++;
- }
- ret = strscpy(s, *__fourcc & BIT(31) ? FOURCC_BIG_ENDIAN_STR
: FOURCC_LITTLE_ENDIAN_STR,
sizeof(__s) - (s - __s));
- if (!WARN_ON_ONCE(ret < 0))
Ditto.
s += ret;
- if (!WARN_ON_ONCE(sizeof(__s) <
(s - __s) + sizeof(FOURCC_HEX_NUMBER))) {
Ditto.
*s = ' ';
s++;
*s = '(';
s++;
/* subtract parentheses and the space from the size */
special_hex_number(s, s + sizeof(FOURCC_HEX_NUMBER) - 3,
*__fourcc, sizeof(u32));
s += sizeof(u32) * 2 + 2 /* 0x */;
*s = ')';
s++;
*s = '\0';
- }
- return string(buf, end, __s, spec);
This looks overengineered. Why everyone will need so long strings to be printed?
+}