Hi Andy,
On Mon, Feb 08, 2021 at 10:43:30PM +0200, Andy Shevchenko wrote:
On Mon, Feb 8, 2021 at 10:11 PM Sakari Ailus sakari.ailus@linux.intel.com 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.
Thank you for an update with the examples how current users will be converted. Below review is based on the users I had seen so far and assumptions made in this code. I see that it's tagged by maintainers, but I can't help to comment again on this. In any case the decision is up to them.
...
+V4L2 and DRM FourCC code (pixel format) +---------------------------------------
+::
%p4cc
+Print a FourCC code used by V4L2 or DRM, including format endianness and +its numerical value as hexadecimal.
+Passed by reference.
+Examples::
%p4cc BG12 little-endian (0x32314742)
This misses examples of the (strange) escaping cases and wiped whitespaces to make sure everybody understands that 'D 12' will be the same as 'D1 2' (side note: which I disagree on, perhaps something should be added into documentation why).
The spaces are expected to be at the end only. I can add such example if you like. There are no fourcc codes with spaces in the middle in neither V4L2 nor DRM, and I don't think the expectation is to have them either.
...
+static noinline_for_stack +char *fourcc_string(char *buf, char *end, const u32 *fourcc,
struct printf_spec spec, const char *fmt)
+{
char output[sizeof("(xx)(xx)(xx)(xx) little-endian (0x01234567)")];
Do we have any evidence / document / standard that the above format is what people would find good? From existing practices (I consider other printings elsewhere and users in this series) I find '(xx)' form for hex numbers is weird. The standard practice is to use \xHH (without parentheses).
Earlier in the review it was proposed that special handling of codes below 32 should be added, which I did. Using the parentheses is apparently an existing practice elsewhere.
Note that neither DRM nor V4L2 currently has such fourcc codes currently.
char *p = output;
unsigned int i;
u32 val;
if (fmt[1] != 'c' || fmt[2] != 'c')
return error_string(buf, end, "(%p4?)", spec);
if (check_pointer(&buf, end, fourcc, spec))
return buf;
val = *fourcc & ~BIT(31);
for (i = 0; i < sizeof(*fourcc); i++) {
unsigned char c = val >> (i * 8);
...
/* Weed out spaces */
if (c == ' ')
continue;
None of the existing users does that. Why?
The existing instances of printing fourcc codes in V4L2 are scattered around with priority on implementation simplicity. As we have a single simplementation here, I'm not really worried about that.
/* Print non-control ASCII characters as-is */
if (isascii(c) && isprint(c)) {
*p++ = c;
continue;
}
*p++ = '(';
p = hex_byte_pack(p, c);
*p++ = ')';
}
strcpy(p, *fourcc & BIT(31) ? " big-endian" : " little-endian");
p += strlen(p);
*p++ = ' ';
*p++ = '(';
p = special_hex_number(p, output + sizeof(output) - 2, *fourcc,
sizeof(u32));
This is perfectly one line (in this file we have even longer lines).
Sure, you can do that, and I can then review your patch and point to the coding style documentation. :-)
*p++ = ')';
*p = '\0';
return string(buf, end, output, spec);
+}