finish of mode add/remove, just have attach/detach modes
authorDave Airlie <airlied@redhat.com>
Mon, 3 Dec 2007 03:42:32 +0000 (13:42 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 3 Dec 2007 05:30:05 +0000 (15:30 +1000)
libdrm/xf86drmMode.c
libdrm/xf86drmMode.h
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_drv.c
linux-core/intel_fb.c
shared-core/drm.h
tests/mode/modetest.c

index 8b70138..cf59673 100644 (file)
@@ -372,38 +372,22 @@ err_allocs:
        return r;
 }
 
-#if 0
-uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *mode_info)
+int drmModeAttachMode(int fd, uint32_t output_id, struct drm_mode_modeinfo *mode_info)
 {
-       if (ioctl(fd, DRM_IOCTL_MODE_ADDMODE, mode_info))
-               return 0;
-       
-       return mode_info->id;
-}
-
-int drmModeRmMode(int fd, uint32_t mode_id)
-{
-       return ioctl(fd, DRM_IOCTL_MODE_RMMODE, &mode_id);
-}
-#endif
-
-int drmModeAttachMode(int fd, uint32_t output_id, uint32_t mode_id)
-{
-
        struct drm_mode_mode_cmd res;
 
+       memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
        res.output_id = output_id;
-       res.mode_id = mode_id;
 
        return ioctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
 }
 
-int drmModeDetachMode(int fd, uint32_t output_id, uint32_t mode_id)
+int drmModeDetachMode(int fd, uint32_t output_id, struct drm_mode_modeinfo *mode_info)
 {
        struct drm_mode_mode_cmd res;
 
+       memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
        res.output_id = output_id;
-       res.mode_id = mode_id;
 
        return ioctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
 }
index 0777c59..a1d717f 100644 (file)
@@ -199,26 +199,15 @@ extern drmModeOutputPtr drmModeGetOutput(int fd,
                uint32_t outputId);
 
 /**
- * Adds a new mode from the given mode info.
- * Name must be unique.
- */
-extern uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *modeInfo);
-
-/**
- * Removes a mode created with AddMode, must be unused.
- */
-extern int drmModeRmMode(int fd, uint32_t modeId);
-
-/**
  * Attaches the given mode to an output.
  */
-extern int drmModeAttachMode(int fd, uint32_t outputId, uint32_t modeId);
+extern int drmModeAttachMode(int fd, uint32_t outputId, struct drm_mode_modeinfo *mode_info);
 
 /**
  * Detaches a mode from the output
  * must be unused, by the given mode.
  */
-extern int drmModeDetachMode(int fd, uint32_t outputId, uint32_t modeId);
+extern int drmModeDetachMode(int fd, uint32_t outputId, struct drm_mode_modeinfo *mode_info);
 
 extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
 extern void drmModeFreeProperty(drmModePropertyPtr ptr);
index 4426833..26aa520 100644 (file)
@@ -579,6 +579,7 @@ struct drm_output *drm_output_create(struct drm_device *dev,
                strncpy(output->name, name, DRM_OUTPUT_LEN);
        output->name[DRM_OUTPUT_LEN - 1] = 0;
        output->subpixel_order = SubPixelUnknown;
+       INIT_LIST_HEAD(&output->user_modes);
        INIT_LIST_HEAD(&output->probed_modes);
        INIT_LIST_HEAD(&output->modes);
        /* randr_output? */
@@ -620,6 +621,9 @@ void drm_output_destroy(struct drm_output *output)
        list_for_each_entry_safe(mode, t, &output->modes, head)
                drm_mode_remove(output, mode);
 
+       list_for_each_entry_safe(mode, t, &output->user_modes, head)
+               drm_mode_remove(output, mode);
+
        mutex_lock(&dev->mode_config.mutex);
        drm_idr_put(dev, output->id);
        list_del(&output->head);
@@ -718,7 +722,6 @@ void drm_mode_config_init(struct drm_device *dev)
        INIT_LIST_HEAD(&dev->mode_config.crtc_list);
        INIT_LIST_HEAD(&dev->mode_config.output_list);
        INIT_LIST_HEAD(&dev->mode_config.property_list);
-       INIT_LIST_HEAD(&dev->mode_config.usermode_list);
        idr_init(&dev->mode_config.crtc_idr);
 }
 EXPORT_SYMBOL(drm_mode_config_init);
@@ -950,7 +953,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
        struct drm_output *output, *ot;
        struct drm_crtc *crtc, *ct;
        struct drm_framebuffer *fb, *fbt;
-       struct drm_display_mode *mode, *mt;
        struct drm_property *property, *pt;
 
        list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
@@ -961,10 +963,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
                drm_property_destroy(dev, property);
        }
 
-       list_for_each_entry_safe(mode, mt, &dev->mode_config.usermode_list, head) {
-               drm_mode_destroy(dev, mode);
-       }
-
        list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
                if (fb->bo->type != drm_bo_type_kernel)
                        drm_framebuffer_destroy(fb);
@@ -1324,10 +1322,6 @@ int drm_mode_getoutput(struct drm_device *dev,
        list_for_each_entry(mode, &output->modes, head)
                mode_count++;
        
-       for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++)
-               if (output->user_mode_ids[i] != 0)
-                       mode_count++;
-
        for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
                if (output->property_ids[i] != 0) {
                        props_count++;
@@ -1365,20 +1359,6 @@ int drm_mode_getoutput(struct drm_device *dev,
                        copied++;
                        
                }
-               for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
-                       if (!output->user_mode_ids[i])
-                               continue;
-                       mode = idr_find(&dev->mode_config.crtc_idr, output->user_mode_ids[i]);
-                       if (mode && (mode->mode_id == output->user_mode_ids[i])) {
-                               drm_crtc_convert_to_umode(&u_mode, mode);
-                               if (copy_to_user(out_resp->modes + copied,
-                                                &u_mode, sizeof(u_mode))) {
-                                       ret = -EFAULT;
-                                       goto out;
-                               }
-                               copied++;
-                       }
-               }
        }
        out_resp->count_modes = mode_count;
 
@@ -1710,49 +1690,14 @@ void drm_fb_release(struct file *filp)
 /*
  *
  */
-void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode)
-{
-       user_mode->type |= DRM_MODE_TYPE_USERDEF;
-
-       user_mode->output_count = 0;
-       list_add(&user_mode->head, &dev->mode_config.usermode_list);
-}
-EXPORT_SYMBOL(drm_mode_addmode);
-
-int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode)
-{
-       struct drm_display_mode *t;
-       int ret = -EINVAL;
-       list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
-               if (t == mode) {
-                       list_del(&mode->head);
-                       drm_mode_destroy(dev, mode);
-                       ret = 0;
-                       break;
-               }
-       }
-       return ret;
-}
-EXPORT_SYMBOL(drm_mode_rmmode);
 
 static int drm_mode_attachmode(struct drm_device *dev,
                               struct drm_output *output,
                               struct drm_display_mode *mode)
 {
        int ret = 0;
-       int i;
-
-       for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
-               if (output->user_mode_ids[i] == 0) {
-                       output->user_mode_ids[i] = mode->mode_id;
-                       mode->output_count++;
-                       break;
-               }
-       }
-
-       if (i == DRM_OUTPUT_MAX_UMODES)
-               ret = -ENOSPC;
 
+       list_add_tail(&mode->head, &output->user_modes);
        return ret;
 }
 
@@ -1760,11 +1705,22 @@ int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
                             struct drm_display_mode *mode)
 {
        struct drm_output *output;
-
+       int ret = 0;
+       struct drm_display_mode *dup_mode;
+       int need_dup = 0;
        list_for_each_entry(output, &dev->mode_config.output_list, head) {
-               if (output->crtc == crtc)
-                       drm_mode_attachmode(dev, output, mode);
+               if (output->crtc == crtc) {
+                       if (need_dup)
+                               dup_mode = drm_mode_duplicate(dev, mode);
+                       else
+                               dup_mode = mode;
+                       ret = drm_mode_attachmode(dev, output, dup_mode); 
+                       if (ret)
+                               return ret;
+                       need_dup = 1;
+               }
        }
+       return 0;
 }
 EXPORT_SYMBOL(drm_mode_attachmode_crtc);
 
@@ -1773,13 +1729,15 @@ static int drm_mode_detachmode(struct drm_device *dev,
                               struct drm_display_mode *mode)
 {
        int found = 0;
-       int ret = 0, i;
+       int ret = 0;
+       struct drm_display_mode *match_mode, *t;
 
-       for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
-               if (output->user_mode_ids[i] == mode->mode_id) {
-                       output->user_mode_ids[i] = 0;
-                       mode->output_count--;
+       list_for_each_entry_safe(match_mode, t, &output->user_modes, head) {
+               if (drm_mode_equal(match_mode, mode)) {
+                       list_del(&match_mode->head);
+                       drm_mode_destroy(dev, match_mode);
                        found = 1;
+                       break;
                }
        }
 
@@ -1801,86 +1759,6 @@ int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mo
 EXPORT_SYMBOL(drm_mode_detachmode_crtc);
 
 /**
- * drm_fb_addmode - adds a user defined mode
- * @inode: inode from the ioctl
- * @filp: file * from the ioctl
- * @cmd: cmd from ioctl
- * @arg: arg from ioctl
- *
- * Adds a user specified mode to the kernel.
- *
- * Called by the user via ioctl.
- *
- * RETURNS:
- * writes new mode id into arg.
- * Zero on success, errno on failure.
- */
-int drm_mode_addmode_ioctl(struct drm_device *dev,
-                          void *data, struct drm_file *file_priv)
-{
-       struct drm_mode_modeinfo *new_mode = data;
-       struct drm_display_mode *user_mode;
-       int ret = 0;
-
-       mutex_lock(&dev->mode_config.mutex);
-       user_mode = drm_mode_create(dev);
-       if (!user_mode) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       drm_crtc_convert_umode(user_mode, new_mode);
-
-       drm_mode_addmode(dev, user_mode);
-
-out:
-       mutex_unlock(&dev->mode_config.mutex);
-       return ret;
-}
-
-/**
- * drm_fb_rmmode - removes a user defined mode
- * @inode: inode from the ioctl
- * @filp: file * from the ioctl
- * @cmd: cmd from ioctl
- * @arg: arg from ioctl
- *
- * Remove the user defined mode specified by the user.
- *
- * Called by the user via ioctl
- *
- * RETURNS:
- * Zero on success, errno on failure.
- */
-int drm_mode_rmmode_ioctl(struct drm_device *dev,
-                         void *data, struct drm_file *file_priv)
-{
-       uint32_t *id = data;
-       struct drm_display_mode *mode;
-       int ret = -EINVAL;
-
-       mutex_lock(&dev->mode_config.mutex);    
-       mode = idr_find(&dev->mode_config.crtc_idr, *id);
-       if (!mode || (*id != mode->mode_id)) {
-               goto out;
-       }
-
-       if (!(mode->type & DRM_MODE_TYPE_USERDEF)) {
-               goto out;
-       }
-
-       if (mode->output_count) {
-               goto out;
-       }
-
-       ret = drm_mode_rmmode(dev, mode);
-
-out:
-       mutex_unlock(&dev->mode_config.mutex);
-       return ret;
-}
-
-/**
  * drm_fb_attachmode - Attach a user mode to an output
  * @inode: inode from the ioctl
  * @filp: file * from the ioctl
@@ -1899,21 +1777,24 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
        struct drm_mode_mode_cmd *mode_cmd = data;
        struct drm_output *output;
        struct drm_display_mode *mode;
+       struct drm_mode_modeinfo *umode = &mode_cmd->mode;
        int ret = 0;
 
        mutex_lock(&dev->mode_config.mutex);
 
-       mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd->mode_id);
-       if (!mode || (mode->mode_id != mode_cmd->mode_id)) {
+       output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
+       if (!output || (output->id != mode_cmd->output_id)) {
                ret = -EINVAL;
                goto out;
        }
 
-       output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
-       if (!output || (output->id != mode_cmd->output_id)) {
-               ret = -EINVAL;
+       mode = drm_mode_create(dev);
+       if (!mode) {
+               ret = -ENOMEM;
                goto out;
        }
+       
+       drm_crtc_convert_umode(mode, umode);
 
        ret = drm_mode_attachmode(dev, output, mode);
 out:
@@ -1939,25 +1820,20 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
 {
        struct drm_mode_mode_cmd *mode_cmd = data;
        struct drm_output *output;
-       struct drm_display_mode *mode;
+       struct drm_display_mode mode;
+       struct drm_mode_modeinfo *umode = &mode_cmd->mode;
        int ret = 0;
 
        mutex_lock(&dev->mode_config.mutex);
 
-       mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd->mode_id);
-       if (!mode || (mode->mode_id != mode_cmd->mode_id)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
        output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
        if (!output || (output->id != mode_cmd->output_id)) {
                ret = -EINVAL;
                goto out;
        }
-
-
-       ret = drm_mode_detachmode(dev, output, mode);
+       
+       drm_crtc_convert_umode(&mode, umode);
+       ret = drm_mode_detachmode(dev, output, &mode);
 out:          
        mutex_unlock(&dev->mode_config.mutex);
        return ret;
index 011903c..90d6104 100644 (file)
@@ -448,7 +448,7 @@ struct drm_output {
        const struct drm_output_funcs *funcs;
        void *driver_private;
 
-       u32 user_mode_ids[DRM_OUTPUT_MAX_UMODES];
+       struct list_head user_modes;
 
        u32 property_ids[DRM_OUTPUT_MAX_PROPERTY];
        u32 property_values[DRM_OUTPUT_MAX_PROPERTY];
@@ -484,8 +484,6 @@ struct drm_mode_config {
        int num_crtc;
        struct list_head crtc_list;
 
-       struct list_head usermode_list;
-
        struct list_head property_list;
 
        int min_width, min_height;
@@ -518,9 +516,6 @@ extern void drm_mode_set_name(struct drm_display_mode *mode);
 extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
 extern void drm_disable_unused_functions(struct drm_device *dev);
 
-extern void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode);
-extern int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode);
-
 /* for us by fb module */
 extern int drm_mode_attachmode_crtc(struct drm_device *dev,
                                    struct drm_crtc *crtc,
index b3e00e8..6a3e704 100644 (file)
@@ -124,8 +124,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
+
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY),
index 5f43f29..a8c9188 100644 (file)
@@ -281,10 +281,8 @@ static int intelfb_set_par(struct fb_info *info)
        }
        
        if (!found) {
-               drm_mode_addmode(dev, drm_mode);
                if (par->fb_mode) {
                        drm_mode_detachmode_crtc(dev, par->fb_mode);
-                       drm_mode_rmmode(dev, par->fb_mode);
                }
        
                par->fb_mode = drm_mode;
index 5c24e0a..f4f75cf 100644 (file)
@@ -1008,7 +1008,7 @@ struct drm_mode_fb_cmd {
 
 struct drm_mode_mode_cmd {
        unsigned int output_id;
-       unsigned int mode_id;
+       struct drm_mode_modeinfo mode;
 };
 
 /**
@@ -1111,8 +1111,6 @@ struct drm_mode_mode_cmd {
 #define DRM_IOCTL_MODE_RMFB             DRM_IOWR(0xA5, unsigned int)
 #define DRM_IOCTL_MODE_GETFB            DRM_IOWR(0xA6, struct drm_mode_fb_cmd)
 
-#define DRM_IOCTL_MODE_ADDMODE         DRM_IOWR(0xA7, struct drm_mode_modeinfo)
-#define DRM_IOCTL_MODE_RMMODE          DRM_IOWR(0xA8, unsigned int)
 #define DRM_IOCTL_MODE_ATTACHMODE      DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
 #define DRM_IOCTL_MODE_DETACHMODE      DRM_IOWR(0xAA, struct drm_mode_mode_cmd)
 
index 2871fde..1d5002b 100644 (file)
@@ -201,45 +201,30 @@ int testMode(int fd, drmModeResPtr res)
        int ret = 0;
        int error = 0;
 
-#if 0
        printf("Test: adding mode to output %i\n", output);
 
        /* printMode(&mode); */
 
-       printf("\tAdding mode\n");
-       newMode = drmModeAddMode(fd, &mode);
-       if (!newMode)
-               goto err;
-
        printf("\tAttaching mode %i to output %i\n", newMode, output);
 
-       ret = drmModeAttachMode(fd, output, newMode);
+       ret = drmModeAttachMode(fd, output, &mode);
 
        if (ret)
                goto err_mode;
 
        printf("\tDetaching mode %i from output %i\n", newMode, output);
-       ret = drmModeDetachMode(fd, output, newMode);
+       ret = drmModeDetachMode(fd, output, &mode);
 
        if (ret)
                goto err_mode;
-
-       printf("\tRemoveing new mode %i\n", newMode);
-       ret = drmModeRmMode(fd, newMode);
-       if (ret)
-               goto err;
-
        return 0;
 
 err_mode:
-       error = drmModeRmMode(fd, newMode);
 
-err:
        printf("\tFailed\n");
 
        if (error)
                printf("\tFailed to delete mode %i\n", newMode);
-#endif
        return 1;
 }