summaryrefslogtreecommitdiff
path: root/linux-core/drm_crtc.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-06-02 16:45:44 +1000
committerDave Airlie <airlied@redhat.com>2008-06-02 16:45:44 +1000
commit149b17311ad5f117e8f53a7a8cc032e369b95ed2 (patch)
treef3e42a300471992c34d308de63243932f4101190 /linux-core/drm_crtc.c
parent50d3e5bd020d0b6877a5fef441408f16e31121cd (diff)
drm: initial mode object groups.
This creates a default group attached to the legacy drm minor nodes. It covers all the objects in the set. make set resources only return objects for this set. Need to fix up other functions to only work on objects in their allowed set.
Diffstat (limited to 'linux-core/drm_crtc.c')
-rw-r--r--linux-core/drm_crtc.c154
1 files changed, 119 insertions, 35 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 79dc137e..784c2f74 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -585,6 +585,45 @@ void drm_mode_config_init(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_mode_config_init);
+int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
+{
+ uint32_t total_objects = 0;
+
+ total_objects += dev->mode_config.num_crtc;
+ total_objects += dev->mode_config.num_connector;
+ total_objects += dev->mode_config.num_encoder;
+
+ group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
+ if (!group->id_list)
+ return -ENOMEM;
+
+ group->num_crtcs = 0;
+ group->num_connectors = 0;
+ group->num_encoders = 0;
+ return 0;
+}
+
+int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group)
+{
+ struct drm_crtc *crtc;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+
+ if (drm_mode_group_init(dev, group))
+ return -ENOMEM;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ group->id_list[group->num_crtcs++] = crtc->base.id;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ group->id_list[group->num_crtcs + group->num_encoders++] = encoder->base.id;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ group->id_list[group->num_crtcs + group->num_encoders + group->num_connectors++] = connector->base.id;
+
+ return 0;
+}
+
/**
* drm_get_buffer_object - find the buffer object for a given handle
* @dev: DRM device
@@ -786,25 +825,37 @@ int drm_mode_getresources(struct drm_device *dev,
int crtc_count = 0;
int fb_count = 0;
int encoder_count = 0;
- int copied = 0;
+ int copied = 0, i;
uint32_t __user *fb_id;
uint32_t __user *crtc_id;
uint32_t __user *connector_id;
uint32_t __user *encoder_id;
+ struct drm_mode_group *mode_group;
mutex_lock(&dev->mode_config.mutex);
+ /* for the non-control nodes we need to limit the list of resources by IDs in the
+ group list for this node */
list_for_each(lh, &file_priv->fbs)
fb_count++;
- list_for_each(lh, &dev->mode_config.crtc_list)
- crtc_count++;
+ mode_group = &file_priv->master->minor->mode_group;
+ if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
+
+ list_for_each(lh, &dev->mode_config.crtc_list)
+ crtc_count++;
- list_for_each(lh, &dev->mode_config.connector_list)
- connector_count++;
+ list_for_each(lh, &dev->mode_config.connector_list)
+ connector_count++;
- list_for_each(lh, &dev->mode_config.encoder_list)
- encoder_count++;
+ list_for_each(lh, &dev->mode_config.encoder_list)
+ encoder_count++;
+ } else {
+
+ crtc_count = mode_group->num_crtcs;
+ connector_count = mode_group->num_connectors;
+ encoder_count = mode_group->num_encoders;
+ }
card_res->max_height = dev->mode_config.max_height;
card_res->min_height = dev->mode_config.min_height;
@@ -830,49 +881,82 @@ int drm_mode_getresources(struct drm_device *dev,
if (card_res->count_crtcs >= crtc_count) {
copied = 0;
crtc_id = (uint32_t *)(unsigned long)card_res->crtc_id_ptr;
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
- DRM_DEBUG("CRTC ID is %d\n", crtc->base.id);
- if (put_user(crtc->base.id, crtc_id + copied)) {
- ret = -EFAULT;
- goto out;
+ if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ DRM_DEBUG("CRTC ID is %d\n", crtc->base.id);
+ if (put_user(crtc->base.id, crtc_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+ } else {
+ for (i = 0; i < mode_group->num_crtcs; i++) {
+ if (put_user(mode_group->id_list[i], crtc_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
}
- copied++;
}
}
card_res->count_crtcs = crtc_count;
+ /* Encoders */
+ if (card_res->count_encoders >= encoder_count) {
+ copied = 0;
+ encoder_id = (uint32_t *)(unsigned long)card_res->encoder_id_ptr;
+ if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ head) {
+ DRM_DEBUG("ENCODER ID is %d\n", encoder->base.id);
+ if (put_user(encoder->base.id, encoder_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+ } else {
+ for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
+ if (put_user(mode_group->id_list[i], encoder_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+
+ }
+ }
+ card_res->count_encoders = encoder_count;
/* Connectors */
if (card_res->count_connectors >= connector_count) {
copied = 0;
connector_id = (uint32_t *)(unsigned long)card_res->connector_id_ptr;
- list_for_each_entry(connector, &dev->mode_config.connector_list,
- head) {
- DRM_DEBUG("CONNECTOR ID is %d\n", connector->base.id);
- if (put_user(connector->base.id, connector_id + copied)) {
- ret = -EFAULT;
- goto out;
+ if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ head) {
+ DRM_DEBUG("CONNECTOR ID is %d\n", connector->base.id);
+ if (put_user(connector->base.id, connector_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+ } else {
+ int start = mode_group->num_crtcs + mode_group->num_encoders;
+ for (i = start; i < start + mode_group->num_connectors; i++) {
+ if (put_user(mode_group->id_list[i], connector_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
}
- copied++;
}
}
card_res->count_connectors = connector_count;
+
- /* Encoders */
- if (card_res->count_encoders >= encoder_count) {
- copied = 0;
- encoder_id = (uint32_t *)(unsigned long)card_res->encoder_id_ptr;
- list_for_each_entry(encoder, &dev->mode_config.encoder_list,
- head) {
- DRM_DEBUG("ENCODER ID is %d\n", encoder->base.id);
- if (put_user(encoder->base.id, encoder_id + copied)) {
- ret = -EFAULT;
- goto out;
- }
- copied++;
- }
- }
- card_res->count_encoders = encoder_count;
DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
card_res->count_connectors, card_res->count_encoders);