Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/modes: Move named modes parsing to a separate function

The current construction of the named mode parsing doesn't allow to extend
it easily. Let's move it to a separate function so we can add more
parameters and modes.

In order for the tests to still pass, some extra checks are needed, so
it's not a 1:1 move.

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
Tested-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
Link: https://lore.kernel.org/r/20220728-rpi-analog-tv-properties-v9-9-24b168e5bcd5@cerno.tech
Signed-off-by: Maxime Ripard <maxime@cerno.tech>

+58 -12
+58 -12
drivers/gpu/drm/drm_modes.c
··· 1755 1755 "PAL", 1756 1756 }; 1757 1757 1758 + static int drm_mode_parse_cmdline_named_mode(const char *name, 1759 + unsigned int name_end, 1760 + struct drm_cmdline_mode *cmdline_mode) 1761 + { 1762 + unsigned int i; 1763 + 1764 + if (!name_end) 1765 + return 0; 1766 + 1767 + /* If the name starts with a digit, it's not a named mode */ 1768 + if (isdigit(name[0])) 1769 + return 0; 1770 + 1771 + /* 1772 + * If there's an equal sign in the name, the command-line 1773 + * contains only an option and no mode. 1774 + */ 1775 + if (strnchr(name, name_end, '=')) 1776 + return 0; 1777 + 1778 + /* The connection status extras can be set without a mode. */ 1779 + if (name_end == 1 && 1780 + (name[0] == 'd' || name[0] == 'D' || name[0] == 'e')) 1781 + return 0; 1782 + 1783 + /* 1784 + * We're sure we're a named mode at this point, iterate over the 1785 + * list of modes we're aware of. 1786 + */ 1787 + for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) { 1788 + int ret; 1789 + 1790 + ret = str_has_prefix(name, drm_named_modes_whitelist[i]); 1791 + if (ret != name_end) 1792 + continue; 1793 + 1794 + strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]); 1795 + cmdline_mode->specified = true; 1796 + 1797 + return 1; 1798 + } 1799 + 1800 + return -EINVAL; 1801 + } 1802 + 1758 1803 /** 1759 1804 * drm_mode_parse_command_line_for_connector - parse command line modeline for connector 1760 1805 * @mode_option: optional per connector mode option ··· 1836 1791 const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; 1837 1792 const char *options_ptr = NULL; 1838 1793 char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL; 1839 - int i, len, ret; 1794 + int len, ret; 1840 1795 1841 1796 memset(mode, 0, sizeof(*mode)); 1842 1797 mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; ··· 1877 1832 parse_extras = true; 1878 1833 } 1879 1834 1880 - /* First check for a named mode */ 1881 - for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) { 1882 - ret = str_has_prefix(name, drm_named_modes_whitelist[i]); 1883 - if (ret == mode_end) { 1884 - if (refresh_ptr) 1885 - return false; /* named + refresh is invalid */ 1835 + if (!mode_end) 1836 + return false; 1886 1837 1887 - strcpy(mode->name, drm_named_modes_whitelist[i]); 1888 - mode->specified = true; 1889 - break; 1890 - } 1891 - } 1838 + ret = drm_mode_parse_cmdline_named_mode(name, mode_end, mode); 1839 + if (ret < 0) 1840 + return false; 1841 + 1842 + /* 1843 + * Having a mode that starts by a letter (and thus is named) and 1844 + * an at-sign (used to specify a refresh rate) is disallowed. 1845 + */ 1846 + if (ret && refresh_ptr) 1847 + return false; 1892 1848 1893 1849 /* No named mode? Check for a normal mode argument, e.g. 1024x768 */ 1894 1850 if (!mode->specified && isdigit(name[0])) {