diff options
author | David S. Miller <davem@davemloft.net> | 2019-09-15 08:17:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-15 08:17:27 -0400 |
commit | aa2eaa8c272a3211dec07ce9c6c863a7e355c10e (patch) | |
tree | 8454a23d36b2ff36133c276ee0ba80eabc00850e /drivers/gpu/drm/drm_modes.c | |
parent | a3d3c74da49c65fc63a937fa559186b0e16adca3 (diff) | |
parent | 1609d7604b847a9820e63393d1a3b6cac7286d40 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Minor overlapping changes in the btusb and ixgbe drivers.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b0369e690f36..c814bcef18a4 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -1454,6 +1454,7 @@ static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, | |||
1454 | } | 1454 | } |
1455 | 1455 | ||
1456 | static int drm_mode_parse_cmdline_extra(const char *str, int length, | 1456 | static int drm_mode_parse_cmdline_extra(const char *str, int length, |
1457 | bool freestanding, | ||
1457 | const struct drm_connector *connector, | 1458 | const struct drm_connector *connector, |
1458 | struct drm_cmdline_mode *mode) | 1459 | struct drm_cmdline_mode *mode) |
1459 | { | 1460 | { |
@@ -1462,9 +1463,15 @@ static int drm_mode_parse_cmdline_extra(const char *str, int length, | |||
1462 | for (i = 0; i < length; i++) { | 1463 | for (i = 0; i < length; i++) { |
1463 | switch (str[i]) { | 1464 | switch (str[i]) { |
1464 | case 'i': | 1465 | case 'i': |
1466 | if (freestanding) | ||
1467 | return -EINVAL; | ||
1468 | |||
1465 | mode->interlace = true; | 1469 | mode->interlace = true; |
1466 | break; | 1470 | break; |
1467 | case 'm': | 1471 | case 'm': |
1472 | if (freestanding) | ||
1473 | return -EINVAL; | ||
1474 | |||
1468 | mode->margins = true; | 1475 | mode->margins = true; |
1469 | break; | 1476 | break; |
1470 | case 'D': | 1477 | case 'D': |
@@ -1542,6 +1549,7 @@ static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, | |||
1542 | if (extras) { | 1549 | if (extras) { |
1543 | int ret = drm_mode_parse_cmdline_extra(end_ptr + i, | 1550 | int ret = drm_mode_parse_cmdline_extra(end_ptr + i, |
1544 | 1, | 1551 | 1, |
1552 | false, | ||
1545 | connector, | 1553 | connector, |
1546 | mode); | 1554 | mode); |
1547 | if (ret) | 1555 | if (ret) |
@@ -1669,6 +1677,22 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len, | |||
1669 | return 0; | 1677 | return 0; |
1670 | } | 1678 | } |
1671 | 1679 | ||
1680 | static const char * const drm_named_modes_whitelist[] = { | ||
1681 | "NTSC", | ||
1682 | "PAL", | ||
1683 | }; | ||
1684 | |||
1685 | static bool drm_named_mode_is_in_whitelist(const char *mode, unsigned int size) | ||
1686 | { | ||
1687 | int i; | ||
1688 | |||
1689 | for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) | ||
1690 | if (!strncmp(mode, drm_named_modes_whitelist[i], size)) | ||
1691 | return true; | ||
1692 | |||
1693 | return false; | ||
1694 | } | ||
1695 | |||
1672 | /** | 1696 | /** |
1673 | * drm_mode_parse_command_line_for_connector - parse command line modeline for connector | 1697 | * drm_mode_parse_command_line_for_connector - parse command line modeline for connector |
1674 | * @mode_option: optional per connector mode option | 1698 | * @mode_option: optional per connector mode option |
@@ -1725,16 +1749,30 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1725 | * bunch of things: | 1749 | * bunch of things: |
1726 | * - We need to make sure that the first character (which | 1750 | * - We need to make sure that the first character (which |
1727 | * would be our resolution in X) is a digit. | 1751 | * would be our resolution in X) is a digit. |
1728 | * - However, if the X resolution is missing, then we end up | 1752 | * - If not, then it's either a named mode or a force on/off. |
1729 | * with something like x<yres>, with our first character | 1753 | * To distinguish between the two, we need to run the |
1730 | * being an alpha-numerical character, which would be | 1754 | * extra parsing function, and if not, then we consider it |
1731 | * considered a named mode. | 1755 | * a named mode. |
1732 | * | 1756 | * |
1733 | * If this isn't enough, we should add more heuristics here, | 1757 | * If this isn't enough, we should add more heuristics here, |
1734 | * and matching unit-tests. | 1758 | * and matching unit-tests. |
1735 | */ | 1759 | */ |
1736 | if (!isdigit(name[0]) && name[0] != 'x') | 1760 | if (!isdigit(name[0]) && name[0] != 'x') { |
1761 | unsigned int namelen = strlen(name); | ||
1762 | |||
1763 | /* | ||
1764 | * Only the force on/off options can be in that case, | ||
1765 | * and they all take a single character. | ||
1766 | */ | ||
1767 | if (namelen == 1) { | ||
1768 | ret = drm_mode_parse_cmdline_extra(name, namelen, true, | ||
1769 | connector, mode); | ||
1770 | if (!ret) | ||
1771 | return true; | ||
1772 | } | ||
1773 | |||
1737 | named_mode = true; | 1774 | named_mode = true; |
1775 | } | ||
1738 | 1776 | ||
1739 | /* Try to locate the bpp and refresh specifiers, if any */ | 1777 | /* Try to locate the bpp and refresh specifiers, if any */ |
1740 | bpp_ptr = strchr(name, '-'); | 1778 | bpp_ptr = strchr(name, '-'); |
@@ -1772,6 +1810,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1772 | if (named_mode) { | 1810 | if (named_mode) { |
1773 | if (mode_end + 1 > DRM_DISPLAY_MODE_LEN) | 1811 | if (mode_end + 1 > DRM_DISPLAY_MODE_LEN) |
1774 | return false; | 1812 | return false; |
1813 | |||
1814 | if (!drm_named_mode_is_in_whitelist(name, mode_end)) | ||
1815 | return false; | ||
1816 | |||
1775 | strscpy(mode->name, name, mode_end + 1); | 1817 | strscpy(mode->name, name, mode_end + 1); |
1776 | } else { | 1818 | } else { |
1777 | ret = drm_mode_parse_cmdline_res_mode(name, mode_end, | 1819 | ret = drm_mode_parse_cmdline_res_mode(name, mode_end, |
@@ -1811,7 +1853,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1811 | extra_ptr != options_ptr) { | 1853 | extra_ptr != options_ptr) { |
1812 | int len = strlen(name) - (extra_ptr - name); | 1854 | int len = strlen(name) - (extra_ptr - name); |
1813 | 1855 | ||
1814 | ret = drm_mode_parse_cmdline_extra(extra_ptr, len, | 1856 | ret = drm_mode_parse_cmdline_extra(extra_ptr, len, false, |
1815 | connector, mode); | 1857 | connector, mode); |
1816 | if (ret) | 1858 | if (ret) |
1817 | return false; | 1859 | return false; |