diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 98 |
1 files changed, 47 insertions, 51 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 2d7bedf28647..50f498231dc4 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -419,6 +419,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers_property = prop; + return 0; } @@ -446,11 +453,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_crtc *crtc; struct drm_encoder *encoder; int ret = 0; - int connector_count = 0; - int crtc_count = 0; int fb_count = 0; - int encoder_count = 0; int copied = 0; + int count = 0; uint32_t __user *fb_id; uint32_t __user *crtc_id; uint32_t __user *connector_id; @@ -484,69 +489,60 @@ int drm_mode_getresources(struct drm_device *dev, void *data, card_res->count_fbs = fb_count; mutex_unlock(&file_priv->fbs_lock); - /* mode_config.mutex protects the connector list against e.g. DP MST - * connector hot-adding. CRTC/Plane lists are invariant. */ - mutex_lock(&dev->mode_config.mutex); - drm_for_each_crtc(crtc, dev) - crtc_count++; - - drm_for_each_connector(connector, dev) - connector_count++; - - drm_for_each_encoder(encoder, dev) - encoder_count++; - card_res->max_height = dev->mode_config.max_height; card_res->min_height = dev->mode_config.min_height; card_res->max_width = dev->mode_config.max_width; card_res->min_width = dev->mode_config.min_width; /* CRTCs */ - if (card_res->count_crtcs >= crtc_count) { - copied = 0; - crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; - drm_for_each_crtc(crtc, dev) { - if (put_user(crtc->base.id, crtc_id + copied)) { - ret = -EFAULT; - goto out; + crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr); + mutex_lock(&dev->mode_config.mutex); + drm_for_each_crtc(crtc, dev) { + if (drm_lease_held(file_priv, crtc->base.id)) { + if (count < card_res->count_crtcs && + put_user(crtc->base.id, crtc_id + count)) { + mutex_unlock(&dev->mode_config.mutex); + return -EFAULT; } - copied++; + count++; } } - card_res->count_crtcs = crtc_count; + mutex_unlock(&dev->mode_config.mutex); + card_res->count_crtcs = count; /* Encoders */ - if (card_res->count_encoders >= encoder_count) { - copied = 0; - encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; - drm_for_each_encoder(encoder, dev) { - if (put_user(encoder->base.id, encoder_id + - copied)) { - ret = -EFAULT; - goto out; - } - copied++; + count = 0; + encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr); + mutex_lock(&dev->mode_config.mutex); + drm_for_each_encoder(encoder, dev) { + if (count < card_res->count_encoders && + put_user(encoder->base.id, encoder_id + count)) { + mutex_unlock(&dev->mode_config.mutex); + return -EFAULT; } + count++; } - card_res->count_encoders = encoder_count; + mutex_unlock(&dev->mode_config.mutex); + card_res->count_encoders = count; + /* Connectors */ - if (card_res->count_connectors >= connector_count) { - copied = 0; - connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; - drm_for_each_connector(connector, dev) { - if (put_user(connector->base.id, - connector_id + copied)) { - ret = -EFAULT; - goto out; + count = 0; + connector_id = u64_to_user_ptr(card_res->connector_id_ptr); + mutex_lock(&dev->mode_config.mutex); + drm_for_each_connector(connector, dev) { + if (drm_lease_held(file_priv, connector->base.id)) { + if (count < card_res->count_connectors && + put_user(connector->base.id, connector_id + count)) { + mutex_unlock(&dev->mode_config.mutex); + return -EFAULT; } - copied++; + count++; } } - card_res->count_connectors = connector_count; - -out: mutex_unlock(&dev->mode_config.mutex); + card_res->count_connectors = count; + return ret; } @@ -572,7 +568,7 @@ int drm_mode_getcrtc(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - crtc = drm_crtc_find(dev, crtc_resp->crtc_id); + crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id); if (!crtc) return -ENOENT; @@ -743,7 +739,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, return -ERANGE; drm_modeset_lock_all(dev); - crtc = drm_crtc_find(dev, crtc_req->crtc_id); + crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id); if (!crtc) { DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); ret = -ENOENT; @@ -764,7 +760,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, /* Make refcounting symmetric with the lookup path. */ drm_framebuffer_reference(fb); } else { - fb = drm_framebuffer_lookup(dev, crtc_req->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id); if (!fb) { DRM_DEBUG_KMS("Unknown FB ID%d\n", crtc_req->fb_id); @@ -848,7 +844,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, goto out; } - connector = drm_connector_lookup(dev, out_id); + connector = drm_connector_lookup(dev, file_priv, out_id); if (!connector) { DRM_DEBUG_KMS("Connector id %d unknown\n", out_id); |