aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2016-08-29 04:27:55 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-08-29 09:37:34 -0400
commit59e71ee746a37fe077b73cecf189de1d27efd6eb (patch)
tree4c31aab686d6d4c3cca5410b8a6d5b42ead9c840 /drivers/gpu/drm/drm_crtc.c
parentec5e304747241823435b160d3eabf1295c06d2e3 (diff)
drm: Extract drm_property.[hc]
This just contains the base property classes and all the code to handle blobs. I think for any kind of standardized/shared properties it's better to have separate files - this is fairly big already as-is. v2: resurrect misplaced hunk (Daniel Stone) Cc: Daniel Stone <daniel@fooishbar.org> Reviewed-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20160829082757.17913-7-daniel.vetter@ffwll.ch
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c926
1 files changed, 0 insertions, 926 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9ff58e6b51c4..b95c48acfa5b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1671,932 +1671,6 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev,
1671 return drm_mode_cursor_common(dev, req, file_priv); 1671 return drm_mode_cursor_common(dev, req, file_priv);
1672} 1672}
1673 1673
1674static bool drm_property_type_valid(struct drm_property *property)
1675{
1676 if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
1677 return !(property->flags & DRM_MODE_PROP_LEGACY_TYPE);
1678 return !!(property->flags & DRM_MODE_PROP_LEGACY_TYPE);
1679}
1680
1681/**
1682 * drm_property_create - create a new property type
1683 * @dev: drm device
1684 * @flags: flags specifying the property type
1685 * @name: name of the property
1686 * @num_values: number of pre-defined values
1687 *
1688 * This creates a new generic drm property which can then be attached to a drm
1689 * object with drm_object_attach_property. The returned property object must be
1690 * freed with drm_property_destroy.
1691 *
1692 * Note that the DRM core keeps a per-device list of properties and that, if
1693 * drm_mode_config_cleanup() is called, it will destroy all properties created
1694 * by the driver.
1695 *
1696 * Returns:
1697 * A pointer to the newly created property on success, NULL on failure.
1698 */
1699struct drm_property *drm_property_create(struct drm_device *dev, int flags,
1700 const char *name, int num_values)
1701{
1702 struct drm_property *property = NULL;
1703 int ret;
1704
1705 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
1706 if (!property)
1707 return NULL;
1708
1709 property->dev = dev;
1710
1711 if (num_values) {
1712 property->values = kcalloc(num_values, sizeof(uint64_t),
1713 GFP_KERNEL);
1714 if (!property->values)
1715 goto fail;
1716 }
1717
1718 ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
1719 if (ret)
1720 goto fail;
1721
1722 property->flags = flags;
1723 property->num_values = num_values;
1724 INIT_LIST_HEAD(&property->enum_list);
1725
1726 if (name) {
1727 strncpy(property->name, name, DRM_PROP_NAME_LEN);
1728 property->name[DRM_PROP_NAME_LEN-1] = '\0';
1729 }
1730
1731 list_add_tail(&property->head, &dev->mode_config.property_list);
1732
1733 WARN_ON(!drm_property_type_valid(property));
1734
1735 return property;
1736fail:
1737 kfree(property->values);
1738 kfree(property);
1739 return NULL;
1740}
1741EXPORT_SYMBOL(drm_property_create);
1742
1743/**
1744 * drm_property_create_enum - create a new enumeration property type
1745 * @dev: drm device
1746 * @flags: flags specifying the property type
1747 * @name: name of the property
1748 * @props: enumeration lists with property values
1749 * @num_values: number of pre-defined values
1750 *
1751 * This creates a new generic drm property which can then be attached to a drm
1752 * object with drm_object_attach_property. The returned property object must be
1753 * freed with drm_property_destroy.
1754 *
1755 * Userspace is only allowed to set one of the predefined values for enumeration
1756 * properties.
1757 *
1758 * Returns:
1759 * A pointer to the newly created property on success, NULL on failure.
1760 */
1761struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
1762 const char *name,
1763 const struct drm_prop_enum_list *props,
1764 int num_values)
1765{
1766 struct drm_property *property;
1767 int i, ret;
1768
1769 flags |= DRM_MODE_PROP_ENUM;
1770
1771 property = drm_property_create(dev, flags, name, num_values);
1772 if (!property)
1773 return NULL;
1774
1775 for (i = 0; i < num_values; i++) {
1776 ret = drm_property_add_enum(property, i,
1777 props[i].type,
1778 props[i].name);
1779 if (ret) {
1780 drm_property_destroy(dev, property);
1781 return NULL;
1782 }
1783 }
1784
1785 return property;
1786}
1787EXPORT_SYMBOL(drm_property_create_enum);
1788
1789/**
1790 * drm_property_create_bitmask - create a new bitmask property type
1791 * @dev: drm device
1792 * @flags: flags specifying the property type
1793 * @name: name of the property
1794 * @props: enumeration lists with property bitflags
1795 * @num_props: size of the @props array
1796 * @supported_bits: bitmask of all supported enumeration values
1797 *
1798 * This creates a new bitmask drm property which can then be attached to a drm
1799 * object with drm_object_attach_property. The returned property object must be
1800 * freed with drm_property_destroy.
1801 *
1802 * Compared to plain enumeration properties userspace is allowed to set any
1803 * or'ed together combination of the predefined property bitflag values
1804 *
1805 * Returns:
1806 * A pointer to the newly created property on success, NULL on failure.
1807 */
1808struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
1809 int flags, const char *name,
1810 const struct drm_prop_enum_list *props,
1811 int num_props,
1812 uint64_t supported_bits)
1813{
1814 struct drm_property *property;
1815 int i, ret, index = 0;
1816 int num_values = hweight64(supported_bits);
1817
1818 flags |= DRM_MODE_PROP_BITMASK;
1819
1820 property = drm_property_create(dev, flags, name, num_values);
1821 if (!property)
1822 return NULL;
1823 for (i = 0; i < num_props; i++) {
1824 if (!(supported_bits & (1ULL << props[i].type)))
1825 continue;
1826
1827 if (WARN_ON(index >= num_values)) {
1828 drm_property_destroy(dev, property);
1829 return NULL;
1830 }
1831
1832 ret = drm_property_add_enum(property, index++,
1833 props[i].type,
1834 props[i].name);
1835 if (ret) {
1836 drm_property_destroy(dev, property);
1837 return NULL;
1838 }
1839 }
1840
1841 return property;
1842}
1843EXPORT_SYMBOL(drm_property_create_bitmask);
1844
1845static struct drm_property *property_create_range(struct drm_device *dev,
1846 int flags, const char *name,
1847 uint64_t min, uint64_t max)
1848{
1849 struct drm_property *property;
1850
1851 property = drm_property_create(dev, flags, name, 2);
1852 if (!property)
1853 return NULL;
1854
1855 property->values[0] = min;
1856 property->values[1] = max;
1857
1858 return property;
1859}
1860
1861/**
1862 * drm_property_create_range - create a new unsigned ranged property type
1863 * @dev: drm device
1864 * @flags: flags specifying the property type
1865 * @name: name of the property
1866 * @min: minimum value of the property
1867 * @max: maximum value of the property
1868 *
1869 * This creates a new generic drm property which can then be attached to a drm
1870 * object with drm_object_attach_property. The returned property object must be
1871 * freed with drm_property_destroy.
1872 *
1873 * Userspace is allowed to set any unsigned integer value in the (min, max)
1874 * range inclusive.
1875 *
1876 * Returns:
1877 * A pointer to the newly created property on success, NULL on failure.
1878 */
1879struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
1880 const char *name,
1881 uint64_t min, uint64_t max)
1882{
1883 return property_create_range(dev, DRM_MODE_PROP_RANGE | flags,
1884 name, min, max);
1885}
1886EXPORT_SYMBOL(drm_property_create_range);
1887
1888/**
1889 * drm_property_create_signed_range - create a new signed ranged property type
1890 * @dev: drm device
1891 * @flags: flags specifying the property type
1892 * @name: name of the property
1893 * @min: minimum value of the property
1894 * @max: maximum value of the property
1895 *
1896 * This creates a new generic drm property which can then be attached to a drm
1897 * object with drm_object_attach_property. The returned property object must be
1898 * freed with drm_property_destroy.
1899 *
1900 * Userspace is allowed to set any signed integer value in the (min, max)
1901 * range inclusive.
1902 *
1903 * Returns:
1904 * A pointer to the newly created property on success, NULL on failure.
1905 */
1906struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
1907 int flags, const char *name,
1908 int64_t min, int64_t max)
1909{
1910 return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags,
1911 name, I642U64(min), I642U64(max));
1912}
1913EXPORT_SYMBOL(drm_property_create_signed_range);
1914
1915/**
1916 * drm_property_create_object - create a new object property type
1917 * @dev: drm device
1918 * @flags: flags specifying the property type
1919 * @name: name of the property
1920 * @type: object type from DRM_MODE_OBJECT_* defines
1921 *
1922 * This creates a new generic drm property which can then be attached to a drm
1923 * object with drm_object_attach_property. The returned property object must be
1924 * freed with drm_property_destroy.
1925 *
1926 * Userspace is only allowed to set this to any property value of the given
1927 * @type. Only useful for atomic properties, which is enforced.
1928 *
1929 * Returns:
1930 * A pointer to the newly created property on success, NULL on failure.
1931 */
1932struct drm_property *drm_property_create_object(struct drm_device *dev,
1933 int flags, const char *name, uint32_t type)
1934{
1935 struct drm_property *property;
1936
1937 flags |= DRM_MODE_PROP_OBJECT;
1938
1939 if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC)))
1940 return NULL;
1941
1942 property = drm_property_create(dev, flags, name, 1);
1943 if (!property)
1944 return NULL;
1945
1946 property->values[0] = type;
1947
1948 return property;
1949}
1950EXPORT_SYMBOL(drm_property_create_object);
1951
1952/**
1953 * drm_property_create_bool - create a new boolean property type
1954 * @dev: drm device
1955 * @flags: flags specifying the property type
1956 * @name: name of the property
1957 *
1958 * This creates a new generic drm property which can then be attached to a drm
1959 * object with drm_object_attach_property. The returned property object must be
1960 * freed with drm_property_destroy.
1961 *
1962 * This is implemented as a ranged property with only {0, 1} as valid values.
1963 *
1964 * Returns:
1965 * A pointer to the newly created property on success, NULL on failure.
1966 */
1967struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
1968 const char *name)
1969{
1970 return drm_property_create_range(dev, flags, name, 0, 1);
1971}
1972EXPORT_SYMBOL(drm_property_create_bool);
1973
1974/**
1975 * drm_property_add_enum - add a possible value to an enumeration property
1976 * @property: enumeration property to change
1977 * @index: index of the new enumeration
1978 * @value: value of the new enumeration
1979 * @name: symbolic name of the new enumeration
1980 *
1981 * This functions adds enumerations to a property.
1982 *
1983 * It's use is deprecated, drivers should use one of the more specific helpers
1984 * to directly create the property with all enumerations already attached.
1985 *
1986 * Returns:
1987 * Zero on success, error code on failure.
1988 */
1989int drm_property_add_enum(struct drm_property *property, int index,
1990 uint64_t value, const char *name)
1991{
1992 struct drm_property_enum *prop_enum;
1993
1994 if (!(drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
1995 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)))
1996 return -EINVAL;
1997
1998 /*
1999 * Bitmask enum properties have the additional constraint of values
2000 * from 0 to 63
2001 */
2002 if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK) &&
2003 (value > 63))
2004 return -EINVAL;
2005
2006 if (!list_empty(&property->enum_list)) {
2007 list_for_each_entry(prop_enum, &property->enum_list, head) {
2008 if (prop_enum->value == value) {
2009 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2010 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2011 return 0;
2012 }
2013 }
2014 }
2015
2016 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
2017 if (!prop_enum)
2018 return -ENOMEM;
2019
2020 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2021 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2022 prop_enum->value = value;
2023
2024 property->values[index] = value;
2025 list_add_tail(&prop_enum->head, &property->enum_list);
2026 return 0;
2027}
2028EXPORT_SYMBOL(drm_property_add_enum);
2029
2030/**
2031 * drm_property_destroy - destroy a drm property
2032 * @dev: drm device
2033 * @property: property to destry
2034 *
2035 * This function frees a property including any attached resources like
2036 * enumeration values.
2037 */
2038void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2039{
2040 struct drm_property_enum *prop_enum, *pt;
2041
2042 list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) {
2043 list_del(&prop_enum->head);
2044 kfree(prop_enum);
2045 }
2046
2047 if (property->num_values)
2048 kfree(property->values);
2049 drm_mode_object_unregister(dev, &property->base);
2050 list_del(&property->head);
2051 kfree(property);
2052}
2053EXPORT_SYMBOL(drm_property_destroy);
2054
2055/**
2056 * drm_mode_getproperty_ioctl - get the property metadata
2057 * @dev: DRM device
2058 * @data: ioctl data
2059 * @file_priv: DRM file info
2060 *
2061 * This function retrieves the metadata for a given property, like the different
2062 * possible values for an enum property or the limits for a range property.
2063 *
2064 * Blob properties are special
2065 *
2066 * Called by the user via ioctl.
2067 *
2068 * Returns:
2069 * Zero on success, negative errno on failure.
2070 */
2071int drm_mode_getproperty_ioctl(struct drm_device *dev,
2072 void *data, struct drm_file *file_priv)
2073{
2074 struct drm_mode_get_property *out_resp = data;
2075 struct drm_property *property;
2076 int enum_count = 0;
2077 int value_count = 0;
2078 int ret = 0, i;
2079 int copied;
2080 struct drm_property_enum *prop_enum;
2081 struct drm_mode_property_enum __user *enum_ptr;
2082 uint64_t __user *values_ptr;
2083
2084 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2085 return -EINVAL;
2086
2087 drm_modeset_lock_all(dev);
2088 property = drm_property_find(dev, out_resp->prop_id);
2089 if (!property) {
2090 ret = -ENOENT;
2091 goto done;
2092 }
2093
2094 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
2095 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
2096 list_for_each_entry(prop_enum, &property->enum_list, head)
2097 enum_count++;
2098 }
2099
2100 value_count = property->num_values;
2101
2102 strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2103 out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2104 out_resp->flags = property->flags;
2105
2106 if ((out_resp->count_values >= value_count) && value_count) {
2107 values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
2108 for (i = 0; i < value_count; i++) {
2109 if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2110 ret = -EFAULT;
2111 goto done;
2112 }
2113 }
2114 }
2115 out_resp->count_values = value_count;
2116
2117 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
2118 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
2119 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2120 copied = 0;
2121 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
2122 list_for_each_entry(prop_enum, &property->enum_list, head) {
2123
2124 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2125 ret = -EFAULT;
2126 goto done;
2127 }
2128
2129 if (copy_to_user(&enum_ptr[copied].name,
2130 &prop_enum->name, DRM_PROP_NAME_LEN)) {
2131 ret = -EFAULT;
2132 goto done;
2133 }
2134 copied++;
2135 }
2136 }
2137 out_resp->count_enum_blobs = enum_count;
2138 }
2139
2140 /*
2141 * NOTE: The idea seems to have been to use this to read all the blob
2142 * property values. But nothing ever added them to the corresponding
2143 * list, userspace always used the special-purpose get_blob ioctl to
2144 * read the value for a blob property. It also doesn't make a lot of
2145 * sense to return values here when everything else is just metadata for
2146 * the property itself.
2147 */
2148 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
2149 out_resp->count_enum_blobs = 0;
2150done:
2151 drm_modeset_unlock_all(dev);
2152 return ret;
2153}
2154
2155static void drm_property_free_blob(struct kref *kref)
2156{
2157 struct drm_property_blob *blob =
2158 container_of(kref, struct drm_property_blob, base.refcount);
2159
2160 mutex_lock(&blob->dev->mode_config.blob_lock);
2161 list_del(&blob->head_global);
2162 mutex_unlock(&blob->dev->mode_config.blob_lock);
2163
2164 drm_mode_object_unregister(blob->dev, &blob->base);
2165
2166 kfree(blob);
2167}
2168
2169/**
2170 * drm_property_create_blob - Create new blob property
2171 *
2172 * Creates a new blob property for a specified DRM device, optionally
2173 * copying data.
2174 *
2175 * @dev: DRM device to create property for
2176 * @length: Length to allocate for blob data
2177 * @data: If specified, copies data into blob
2178 *
2179 * Returns:
2180 * New blob property with a single reference on success, or an ERR_PTR
2181 * value on failure.
2182 */
2183struct drm_property_blob *
2184drm_property_create_blob(struct drm_device *dev, size_t length,
2185 const void *data)
2186{
2187 struct drm_property_blob *blob;
2188 int ret;
2189
2190 if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
2191 return ERR_PTR(-EINVAL);
2192
2193 blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2194 if (!blob)
2195 return ERR_PTR(-ENOMEM);
2196
2197 /* This must be explicitly initialised, so we can safely call list_del
2198 * on it in the removal handler, even if it isn't in a file list. */
2199 INIT_LIST_HEAD(&blob->head_file);
2200 blob->length = length;
2201 blob->dev = dev;
2202
2203 if (data)
2204 memcpy(blob->data, data, length);
2205
2206 ret = drm_mode_object_get_reg(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
2207 true, drm_property_free_blob);
2208 if (ret) {
2209 kfree(blob);
2210 return ERR_PTR(-EINVAL);
2211 }
2212
2213 mutex_lock(&dev->mode_config.blob_lock);
2214 list_add_tail(&blob->head_global,
2215 &dev->mode_config.property_blob_list);
2216 mutex_unlock(&dev->mode_config.blob_lock);
2217
2218 return blob;
2219}
2220EXPORT_SYMBOL(drm_property_create_blob);
2221
2222/**
2223 * drm_property_unreference_blob - Unreference a blob property
2224 *
2225 * Drop a reference on a blob property. May free the object.
2226 *
2227 * @blob: Pointer to blob property
2228 */
2229void drm_property_unreference_blob(struct drm_property_blob *blob)
2230{
2231 if (!blob)
2232 return;
2233
2234 drm_mode_object_unreference(&blob->base);
2235}
2236EXPORT_SYMBOL(drm_property_unreference_blob);
2237
2238/**
2239 * drm_property_destroy_user_blobs - destroy all blobs created by this client
2240 * @dev: DRM device
2241 * @file_priv: destroy all blobs owned by this file handle
2242 */
2243void drm_property_destroy_user_blobs(struct drm_device *dev,
2244 struct drm_file *file_priv)
2245{
2246 struct drm_property_blob *blob, *bt;
2247
2248 /*
2249 * When the file gets released that means no one else can access the
2250 * blob list any more, so no need to grab dev->blob_lock.
2251 */
2252 list_for_each_entry_safe(blob, bt, &file_priv->blobs, head_file) {
2253 list_del_init(&blob->head_file);
2254 drm_property_unreference_blob(blob);
2255 }
2256}
2257
2258/**
2259 * drm_property_reference_blob - Take a reference on an existing property
2260 *
2261 * Take a new reference on an existing blob property.
2262 *
2263 * @blob: Pointer to blob property
2264 */
2265struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
2266{
2267 drm_mode_object_reference(&blob->base);
2268 return blob;
2269}
2270EXPORT_SYMBOL(drm_property_reference_blob);
2271
2272/**
2273 * drm_property_lookup_blob - look up a blob property and take a reference
2274 * @dev: drm device
2275 * @id: id of the blob property
2276 *
2277 * If successful, this takes an additional reference to the blob property.
2278 * callers need to make sure to eventually unreference the returned property
2279 * again, using @drm_property_unreference_blob.
2280 */
2281struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
2282 uint32_t id)
2283{
2284 struct drm_mode_object *obj;
2285 struct drm_property_blob *blob = NULL;
2286
2287 obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB);
2288 if (obj)
2289 blob = obj_to_blob(obj);
2290 return blob;
2291}
2292EXPORT_SYMBOL(drm_property_lookup_blob);
2293
2294/**
2295 * drm_property_replace_global_blob - atomically replace existing blob property
2296 * @dev: drm device
2297 * @replace: location of blob property pointer to be replaced
2298 * @length: length of data for new blob, or 0 for no data
2299 * @data: content for new blob, or NULL for no data
2300 * @obj_holds_id: optional object for property holding blob ID
2301 * @prop_holds_id: optional property holding blob ID
2302 * @return 0 on success or error on failure
2303 *
2304 * This function will atomically replace a global property in the blob list,
2305 * optionally updating a property which holds the ID of that property. It is
2306 * guaranteed to be atomic: no caller will be allowed to see intermediate
2307 * results, and either the entire operation will succeed and clean up the
2308 * previous property, or it will fail and the state will be unchanged.
2309 *
2310 * If length is 0 or data is NULL, no new blob will be created, and the holding
2311 * property, if specified, will be set to 0.
2312 *
2313 * Access to the replace pointer is assumed to be protected by the caller, e.g.
2314 * by holding the relevant modesetting object lock for its parent.
2315 *
2316 * For example, a drm_connector has a 'PATH' property, which contains the ID
2317 * of a blob property with the value of the MST path information. Calling this
2318 * function with replace pointing to the connector's path_blob_ptr, length and
2319 * data set for the new path information, obj_holds_id set to the connector's
2320 * base object, and prop_holds_id set to the path property name, will perform
2321 * a completely atomic update. The access to path_blob_ptr is protected by the
2322 * caller holding a lock on the connector.
2323 */
2324int drm_property_replace_global_blob(struct drm_device *dev,
2325 struct drm_property_blob **replace,
2326 size_t length,
2327 const void *data,
2328 struct drm_mode_object *obj_holds_id,
2329 struct drm_property *prop_holds_id)
2330{
2331 struct drm_property_blob *new_blob = NULL;
2332 struct drm_property_blob *old_blob = NULL;
2333 int ret;
2334
2335 WARN_ON(replace == NULL);
2336
2337 old_blob = *replace;
2338
2339 if (length && data) {
2340 new_blob = drm_property_create_blob(dev, length, data);
2341 if (IS_ERR(new_blob))
2342 return PTR_ERR(new_blob);
2343 }
2344
2345 /* This does not need to be synchronised with blob_lock, as the
2346 * get_properties ioctl locks all modesetting objects, and
2347 * obj_holds_id must be locked before calling here, so we cannot
2348 * have its value out of sync with the list membership modified
2349 * below under blob_lock. */
2350 if (obj_holds_id) {
2351 ret = drm_object_property_set_value(obj_holds_id,
2352 prop_holds_id,
2353 new_blob ?
2354 new_blob->base.id : 0);
2355 if (ret != 0)
2356 goto err_created;
2357 }
2358
2359 drm_property_unreference_blob(old_blob);
2360 *replace = new_blob;
2361
2362 return 0;
2363
2364err_created:
2365 drm_property_unreference_blob(new_blob);
2366 return ret;
2367}
2368EXPORT_SYMBOL(drm_property_replace_global_blob);
2369
2370/**
2371 * drm_mode_getblob_ioctl - get the contents of a blob property value
2372 * @dev: DRM device
2373 * @data: ioctl data
2374 * @file_priv: DRM file info
2375 *
2376 * This function retrieves the contents of a blob property. The value stored in
2377 * an object's blob property is just a normal modeset object id.
2378 *
2379 * Called by the user via ioctl.
2380 *
2381 * Returns:
2382 * Zero on success, negative errno on failure.
2383 */
2384int drm_mode_getblob_ioctl(struct drm_device *dev,
2385 void *data, struct drm_file *file_priv)
2386{
2387 struct drm_mode_get_blob *out_resp = data;
2388 struct drm_property_blob *blob;
2389 int ret = 0;
2390 void __user *blob_ptr;
2391
2392 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2393 return -EINVAL;
2394
2395 blob = drm_property_lookup_blob(dev, out_resp->blob_id);
2396 if (!blob)
2397 return -ENOENT;
2398
2399 if (out_resp->length == blob->length) {
2400 blob_ptr = (void __user *)(unsigned long)out_resp->data;
2401 if (copy_to_user(blob_ptr, blob->data, blob->length)) {
2402 ret = -EFAULT;
2403 goto unref;
2404 }
2405 }
2406 out_resp->length = blob->length;
2407unref:
2408 drm_property_unreference_blob(blob);
2409
2410 return ret;
2411}
2412
2413/**
2414 * drm_mode_createblob_ioctl - create a new blob property
2415 * @dev: DRM device
2416 * @data: ioctl data
2417 * @file_priv: DRM file info
2418 *
2419 * This function creates a new blob property with user-defined values. In order
2420 * to give us sensible validation and checking when creating, rather than at
2421 * every potential use, we also require a type to be provided upfront.
2422 *
2423 * Called by the user via ioctl.
2424 *
2425 * Returns:
2426 * Zero on success, negative errno on failure.
2427 */
2428int drm_mode_createblob_ioctl(struct drm_device *dev,
2429 void *data, struct drm_file *file_priv)
2430{
2431 struct drm_mode_create_blob *out_resp = data;
2432 struct drm_property_blob *blob;
2433 void __user *blob_ptr;
2434 int ret = 0;
2435
2436 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2437 return -EINVAL;
2438
2439 blob = drm_property_create_blob(dev, out_resp->length, NULL);
2440 if (IS_ERR(blob))
2441 return PTR_ERR(blob);
2442
2443 blob_ptr = (void __user *)(unsigned long)out_resp->data;
2444 if (copy_from_user(blob->data, blob_ptr, out_resp->length)) {
2445 ret = -EFAULT;
2446 goto out_blob;
2447 }
2448
2449 /* Dropping the lock between create_blob and our access here is safe
2450 * as only the same file_priv can remove the blob; at this point, it is
2451 * not associated with any file_priv. */
2452 mutex_lock(&dev->mode_config.blob_lock);
2453 out_resp->blob_id = blob->base.id;
2454 list_add_tail(&blob->head_file, &file_priv->blobs);
2455 mutex_unlock(&dev->mode_config.blob_lock);
2456
2457 return 0;
2458
2459out_blob:
2460 drm_property_unreference_blob(blob);
2461 return ret;
2462}
2463
2464/**
2465 * drm_mode_destroyblob_ioctl - destroy a user blob property
2466 * @dev: DRM device
2467 * @data: ioctl data
2468 * @file_priv: DRM file info
2469 *
2470 * Destroy an existing user-defined blob property.
2471 *
2472 * Called by the user via ioctl.
2473 *
2474 * Returns:
2475 * Zero on success, negative errno on failure.
2476 */
2477int drm_mode_destroyblob_ioctl(struct drm_device *dev,
2478 void *data, struct drm_file *file_priv)
2479{
2480 struct drm_mode_destroy_blob *out_resp = data;
2481 struct drm_property_blob *blob = NULL, *bt;
2482 bool found = false;
2483 int ret = 0;
2484
2485 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2486 return -EINVAL;
2487
2488 blob = drm_property_lookup_blob(dev, out_resp->blob_id);
2489 if (!blob)
2490 return -ENOENT;
2491
2492 mutex_lock(&dev->mode_config.blob_lock);
2493 /* Ensure the property was actually created by this user. */
2494 list_for_each_entry(bt, &file_priv->blobs, head_file) {
2495 if (bt == blob) {
2496 found = true;
2497 break;
2498 }
2499 }
2500
2501 if (!found) {
2502 ret = -EPERM;
2503 goto err;
2504 }
2505
2506 /* We must drop head_file here, because we may not be the last
2507 * reference on the blob. */
2508 list_del_init(&blob->head_file);
2509 mutex_unlock(&dev->mode_config.blob_lock);
2510
2511 /* One reference from lookup, and one from the filp. */
2512 drm_property_unreference_blob(blob);
2513 drm_property_unreference_blob(blob);
2514
2515 return 0;
2516
2517err:
2518 mutex_unlock(&dev->mode_config.blob_lock);
2519 drm_property_unreference_blob(blob);
2520
2521 return ret;
2522}
2523
2524/* Some properties could refer to dynamic refcnt'd objects, or things that
2525 * need special locking to handle lifetime issues (ie. to ensure the prop
2526 * value doesn't become invalid part way through the property update due to
2527 * race). The value returned by reference via 'obj' should be passed back
2528 * to drm_property_change_valid_put() after the property is set (and the
2529 * object to which the property is attached has a chance to take it's own
2530 * reference).
2531 */
2532bool drm_property_change_valid_get(struct drm_property *property,
2533 uint64_t value, struct drm_mode_object **ref)
2534{
2535 int i;
2536
2537 if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2538 return false;
2539
2540 *ref = NULL;
2541
2542 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
2543 if (value < property->values[0] || value > property->values[1])
2544 return false;
2545 return true;
2546 } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) {
2547 int64_t svalue = U642I64(value);
2548
2549 if (svalue < U642I64(property->values[0]) ||
2550 svalue > U642I64(property->values[1]))
2551 return false;
2552 return true;
2553 } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
2554 uint64_t valid_mask = 0;
2555
2556 for (i = 0; i < property->num_values; i++)
2557 valid_mask |= (1ULL << property->values[i]);
2558 return !(value & ~valid_mask);
2559 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
2560 struct drm_property_blob *blob;
2561
2562 if (value == 0)
2563 return true;
2564
2565 blob = drm_property_lookup_blob(property->dev, value);
2566 if (blob) {
2567 *ref = &blob->base;
2568 return true;
2569 } else {
2570 return false;
2571 }
2572 } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
2573 /* a zero value for an object property translates to null: */
2574 if (value == 0)
2575 return true;
2576
2577 *ref = __drm_mode_object_find(property->dev, value,
2578 property->values[0]);
2579 return *ref != NULL;
2580 }
2581
2582 for (i = 0; i < property->num_values; i++)
2583 if (property->values[i] == value)
2584 return true;
2585 return false;
2586}
2587
2588void drm_property_change_valid_put(struct drm_property *property,
2589 struct drm_mode_object *ref)
2590{
2591 if (!ref)
2592 return;
2593
2594 if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
2595 drm_mode_object_unreference(ref);
2596 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
2597 drm_property_unreference_blob(obj_to_blob(ref));
2598}
2599
2600int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, 1674int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
2601 struct drm_property *property, 1675 struct drm_property *property,
2602 uint64_t value) 1676 uint64_t value)