drm/modes: parse_cmdline: Stop parsing extras after bpp / refresh at ', '
authorHans de Goede <hdegoede@redhat.com>
Mon, 18 Nov 2019 15:51:24 +0000 (16:51 +0100)
committerHans de Goede <hdegoede@redhat.com>
Mon, 16 Dec 2019 11:13:17 +0000 (12:13 +0100)
Before this commit it was impossible to add an extra mode argument after
a bpp or refresh specifier, combined with an option, e.g.
video=HDMI-1:720x480-24e,rotate=180 would not work, either the "e" to
force enable would need to be dropped or the ",rotate=180", otherwise
the mode_option would not be accepted.

This commit fixes this by fixing the length calculation if extras_ptr
is set to stop the extra parsing at the start of the options (stop at the
',' options_ptr points to).

Acked-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191118155134.30468-3-hdegoede@redhat.com
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/selftests/drm_cmdline_selftests.h
drivers/gpu/drm/selftests/test-drm_cmdline_parser.c

index 654d4b6..a8aa795 100644 (file)
@@ -1721,7 +1721,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
        const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
        const char *options_ptr = NULL;
        char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
-       int ret;
+       int i, len, ret;
 
 #ifdef CONFIG_FB
        if (!mode_option)
@@ -1841,9 +1841,11 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
        else if (refresh_ptr)
                extra_ptr = refresh_end_ptr;
 
-       if (extra_ptr &&
-           extra_ptr != options_ptr) {
-               int len = strlen(name) - (extra_ptr - name);
+       if (extra_ptr) {
+               if (options_ptr)
+                       len = options_ptr - extra_ptr;
+               else
+                       len = strlen(extra_ptr);
 
                ret = drm_mode_parse_cmdline_extra(extra_ptr, len, false,
                                                   connector, mode);
index 6d61a0e..ca1fc7a 100644 (file)
@@ -60,3 +60,4 @@ cmdline_test(drm_cmdline_test_vmirror)
 cmdline_test(drm_cmdline_test_margin_options)
 cmdline_test(drm_cmdline_test_multiple_options)
 cmdline_test(drm_cmdline_test_invalid_option)
+cmdline_test(drm_cmdline_test_bpp_extra_and_option)
index 013de9d..5b8dea9 100644 (file)
@@ -992,6 +992,32 @@ static int drm_cmdline_test_invalid_option(void *ignored)
        return 0;
 }
 
+static int drm_cmdline_test_bpp_extra_and_option(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24e,rotate=180",
+                                                          &no_connector,
+                                                          &mode));
+       FAIL_ON(!mode.specified);
+       FAIL_ON(mode.xres != 720);
+       FAIL_ON(mode.yres != 480);
+       FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180);
+
+       FAIL_ON(mode.refresh_specified);
+
+       FAIL_ON(!mode.bpp_specified);
+       FAIL_ON(mode.bpp != 24);
+
+       FAIL_ON(mode.rb);
+       FAIL_ON(mode.cvt);
+       FAIL_ON(mode.interlace);
+       FAIL_ON(mode.margins);
+       FAIL_ON(mode.force != DRM_FORCE_ON);
+
+       return 0;
+}
+
 #include "drm_selftest.c"
 
 static int __init test_drm_cmdline_init(void)