summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_crtc.c365
1 files changed, 164 insertions, 201 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index ed5f1dfa..fcddc7d9 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -433,24 +433,31 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
* on the DPLL.
*/
crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
+
list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == crtc) {
- dev_warn(&output->dev->pdev->dev, "%s: set mode %s\n",
- output->name, mode->name);
- output->funcs->mode_set(output, mode, adjusted_mode);
- }
+
+ if (output->crtc != crtc)
+ continue;
+
+ DRM_INFO("%s: set mode %s\n", output->name, mode->name);
+
+ output->funcs->mode_set(output, mode, adjusted_mode);
}
/* Now, enable the clocks, plane, pipe, and outputs that we set up. */
crtc->funcs->commit(crtc);
+
list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == crtc) {
- output->funcs->commit(output);
+
+ if (output->crtc != crtc)
+ continue;
+
+ output->funcs->commit(output);
+
#if 0 // TODO def RANDR_12_INTERFACE
- if (output->randr_output)
- RRPostPendingProperties (output->randr_output);
+ if (output->randr_output)
+ RRPostPendingProperties (output->randr_output);
#endif
- }
}
/* XXX free adjustedmode */
@@ -762,7 +769,7 @@ out_err:
*/
static void drm_pick_crtcs (struct drm_device *dev)
{
- int c, o;
+ int c, o, assigned;
struct drm_output *output, *output_equal;
struct drm_crtc *crtc;
struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
@@ -802,11 +809,26 @@ static void drm_pick_crtcs (struct drm_device *dev)
c = -1;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ assigned = 0;
+
c++;
if ((output->possible_crtcs & (1 << c)) == 0)
continue;
-#if 0 /* should we try and clone ?? - code not tested - FIXME */
+ list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
+ if (output->id == output_equal->id)
+ continue;
+
+ /* Find out if crtc has been assigned before */
+ if (output_equal->crtc == crtc)
+ assigned = 1;
+ }
+
+#if 1 /* continue for now */
+ if (assigned)
+ continue;
+#endif
+
o = -1;
list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
o++;
@@ -816,7 +838,9 @@ static void drm_pick_crtcs (struct drm_device *dev)
list_for_each_entry(modes, &output->modes, head) {
list_for_each_entry(modes_equal, &output_equal->modes, head) {
if (drm_mode_equal (modes, modes_equal)) {
- if ((output->possible_clones & (1 << o))) {
+ if ((output->possible_clones & output_equal->possible_clones) && (output_equal->crtc == crtc)) {
+ printk("Cloning %s (0x%lx) to %s (0x%lx)\n",output->name,output->possible_clones,output_equal->name,output_equal->possible_clones);
+ assigned = 0;
goto clone;
}
}
@@ -825,7 +849,10 @@ static void drm_pick_crtcs (struct drm_device *dev)
}
clone:
-#endif
+ /* crtc has been assigned skip it */
+ if (assigned)
+ continue;
+
/* Found a CRTC to attach to, do it ! */
output->crtc = crtc;
output->crtc->desired_mode = des_mode;
@@ -856,6 +883,7 @@ clone:
bool drm_initial_config(struct drm_device *dev, bool can_grow)
{
struct drm_output *output;
+ struct drm_crtc *crtc;
int ret = false;
mutex_lock(&dev->mode_config.mutex);
@@ -864,14 +892,31 @@ bool drm_initial_config(struct drm_device *dev, bool can_grow)
drm_pick_crtcs(dev);
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+
+ /* can't setup the crtc if there's no assigned mode */
+ if (!crtc->desired_mode)
+ continue;
+
+ /* Now setup the fbdev for attached crtcs */
+ dev->driver->fb_probe(dev, crtc);
+ }
+
+ /* This is a little screwy, as we've already walked the outputs
+ * above, but it's a little bit of magic too. There's the potential
+ * for things not to get setup above if an existing device gets
+ * re-assigned thus confusing the hardware. By walking the outputs
+ * this fixes up their crtc's.
+ */
list_for_each_entry(output, &dev->mode_config.output_list, head) {
- /* can't setup the output if there's no assigned crtc or mode */
+ /* can't setup the output if there's no assigned mode */
if (!output->crtc || !output->crtc->desired_mode)
continue;
- dev->driver->fb_probe(dev, output->crtc);
+ drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0);
}
+
drm_disable_unused_functions(dev);
mutex_unlock(&dev->mode_config.mutex);
@@ -1088,8 +1133,7 @@ void drm_crtc_convert_umode(struct drm_display_mode *out, struct drm_mode_modein
int drm_mode_getresources(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_card_res __user *argp = (void __user *)data;
- struct drm_mode_card_res card_res;
+ struct drm_mode_card_res *card_res = data;
struct list_head *lh;
struct drm_framebuffer *fb;
struct drm_output *output;
@@ -1122,12 +1166,7 @@ int drm_mode_getresources(struct drm_device *dev,
list_for_each(lh, &dev->mode_config.usermode_list)
mode_count++;
- if (copy_from_user(&card_res, argp, sizeof(card_res))) {
- ret = -EFAULT;
- goto out_unlock;
- }
-
- if (card_res.count_modes == 0) {
+ if (card_res->count_modes == 0) {
DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height);
drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height);
mode_count = 0;
@@ -1141,78 +1180,58 @@ int drm_mode_getresources(struct drm_device *dev,
/* handle this in 4 parts */
/* FBs */
- if (card_res.count_fbs >= fb_count) {
+ if (card_res->count_fbs >= fb_count) {
copied = 0;
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
- if (put_user(fb->id, &card_res.fb_id[copied++])) {
- ret = -EFAULT;
- goto done;
- }
+ card_res->fb_id[copied++] = fb->id;
}
}
- card_res.count_fbs = fb_count;
+ card_res->count_fbs = fb_count;
/* CRTCs */
- if (card_res.count_crtcs >= crtc_count) {
+ if (card_res->count_crtcs >= crtc_count) {
copied = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
DRM_DEBUG("CRTC ID is %d\n", crtc->id);
- if (put_user(crtc->id, &card_res.crtc_id[copied++])) {
- ret = -EFAULT;
- goto done;
- }
+ card_res->crtc_id[copied++] = crtc->id;
}
}
- card_res.count_crtcs = crtc_count;
+ card_res->count_crtcs = crtc_count;
/* Outputs */
- if (card_res.count_outputs >= output_count) {
+ if (card_res->count_outputs >= output_count) {
copied = 0;
list_for_each_entry(output, &dev->mode_config.output_list,
head) {
DRM_DEBUG("OUTPUT ID is %d\n", output->id);
- if (put_user(output->id, &card_res.output_id[copied++])) {
- ret = -EFAULT;
- goto done;
- }
+ card_res->output_id[copied++] = output->id;
}
}
- card_res.count_outputs = output_count;
+ card_res->count_outputs = output_count;
/* Modes */
- if (card_res.count_modes >= mode_count) {
+ if (card_res->count_modes >= mode_count) {
copied = 0;
list_for_each_entry(output, &dev->mode_config.output_list,
head) {
list_for_each_entry(mode, &output->modes, head) {
drm_crtc_convert_to_umode(&u_mode, mode);
- if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
- ret = -EFAULT;
- goto done;
- }
+ card_res->modes[copied++] = u_mode;
}
}
/* add in user modes */
list_for_each_entry(mode, &dev->mode_config.usermode_list, head) {
drm_crtc_convert_to_umode(&u_mode, mode);
- if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
- ret = -EFAULT;
- goto done;
- }
+ card_res->modes[copied++] = u_mode;
}
}
- card_res.count_modes = mode_count;
+ card_res->count_modes = mode_count;
-done:
- DRM_DEBUG("Counted %d %d %d\n", card_res.count_crtcs,
- card_res.count_outputs,
- card_res.count_modes);
+ DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
+ card_res->count_outputs,
+ card_res->count_modes);
- if (copy_to_user(argp, &card_res, sizeof(card_res)))
- ret = -EFAULT;
-
-out_unlock:
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
@@ -1237,43 +1256,36 @@ out_unlock:
int drm_mode_getcrtc(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_crtc __user *argp = (void __user *)data;
- struct drm_mode_crtc crtc_resp;
+ struct drm_mode_crtc *crtc_resp = data;
struct drm_crtc *crtc;
struct drm_output *output;
int ocount;
int ret = 0;
- if (copy_from_user(&crtc_resp, argp, sizeof(crtc_resp)))
- return -EFAULT;
-
mutex_lock(&dev->mode_config.mutex);
- crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp.crtc_id);
- if (!crtc || (crtc->id != crtc_resp.crtc_id)) {
+ crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp->crtc_id);
+ if (!crtc || (crtc->id != crtc_resp->crtc_id)) {
ret = -EINVAL;
goto out;
}
- crtc_resp.x = crtc->x;
- crtc_resp.y = crtc->y;
- crtc_resp.fb_id = 1;
+ crtc_resp->x = crtc->x;
+ crtc_resp->y = crtc->y;
+ crtc_resp->fb_id = 1;
- crtc_resp.outputs = 0;
+ crtc_resp->outputs = 0;
if (crtc->enabled) {
- crtc_resp.mode = crtc->mode.mode_id;
+ crtc_resp->mode = crtc->mode.mode_id;
ocount = 0;
list_for_each_entry(output, &dev->mode_config.output_list, head) {
if (output->crtc == crtc)
- crtc_resp.outputs |= 1 << (ocount++);
+ crtc_resp->outputs |= 1 << (ocount++);
}
} else {
- crtc_resp.mode = 0;
+ crtc_resp->mode = 0;
}
- if (copy_to_user(argp, &crtc_resp, sizeof(crtc_resp)))
- ret = -EFAULT;
-
out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -1299,8 +1311,7 @@ out:
int drm_mode_getoutput(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_get_output __user *argp = (void __user *)data;
- struct drm_mode_get_output out_resp;
+ struct drm_mode_get_output *out_resp = data;
struct drm_output *output;
struct drm_display_mode *mode;
int mode_count = 0;
@@ -1308,16 +1319,13 @@ int drm_mode_getoutput(struct drm_device *dev,
int copied = 0;
int i;
- if (copy_from_user(&out_resp, argp, sizeof(out_resp)))
- return -EFAULT;
-
- DRM_DEBUG("output id %d:\n", out_resp.output);
+ DRM_DEBUG("output id %d:\n", out_resp->output);
mutex_lock(&dev->mode_config.mutex);
- output= idr_find(&dev->mode_config.crtc_idr, out_resp.output);
- if (!output || (output->id != out_resp.output)) {
+ output= idr_find(&dev->mode_config.crtc_idr, out_resp->output);
+ if (!output || (output->id != out_resp->output)) {
ret = -EINVAL;
- goto out_unlock;
+ goto done;
}
list_for_each_entry(mode, &output->modes, head)
@@ -1327,42 +1335,32 @@ int drm_mode_getoutput(struct drm_device *dev,
if (output->user_mode_ids[i] != 0)
mode_count++;
- strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN);
- out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0;
+ strncpy(out_resp->name, output->name, DRM_OUTPUT_NAME_LEN);
+ out_resp->name[DRM_OUTPUT_NAME_LEN-1] = 0;
- out_resp.mm_width = output->mm_width;
- out_resp.mm_height = output->mm_height;
- out_resp.subpixel = output->subpixel_order;
- out_resp.connection = output->status;
+ out_resp->mm_width = output->mm_width;
+ out_resp->mm_height = output->mm_height;
+ out_resp->subpixel = output->subpixel_order;
+ out_resp->connection = output->status;
if (output->crtc)
- out_resp.crtc = output->crtc->id;
+ out_resp->crtc = output->crtc->id;
else
- out_resp.crtc = 0;
+ out_resp->crtc = 0;
- if ((out_resp.count_modes >= mode_count) && mode_count) {
+ if ((out_resp->count_modes >= mode_count) && mode_count) {
copied = 0;
list_for_each_entry(mode, &output->modes, head) {
- if (put_user(mode->mode_id, &out_resp.modes[copied++])) {
- ret = -EFAULT;
- goto done;
- }
+ out_resp->modes[copied++] = mode->mode_id;
}
for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
if (output->user_mode_ids[i] != 0)
- if (put_user(output->user_mode_ids[i], &out_resp.modes[copied++])) {
- ret = -EFAULT;
- goto done;
- }
+ out_resp->modes[copied++] = output->user_mode_ids[i];
}
}
- out_resp.count_modes = mode_count;
+ out_resp->count_modes = mode_count;
done:
- if (copy_to_user(argp, &out_resp, sizeof(out_resp)))
- ret = -EFAULT;
-
-out_unlock:
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
@@ -1387,8 +1385,7 @@ out_unlock:
int drm_mode_setcrtc(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_crtc __user *argp = (void __user *)data;
- struct drm_mode_crtc crtc_req;
+ struct drm_mode_crtc *crtc_req = data;
struct drm_crtc *crtc;
struct drm_output **output_set = NULL, *output;
struct drm_display_mode *mode;
@@ -1396,29 +1393,26 @@ int drm_mode_setcrtc(struct drm_device *dev,
int ret = 0;
int i;
- if (copy_from_user(&crtc_req, argp, sizeof(crtc_req)))
- return -EFAULT;
-
mutex_lock(&dev->mode_config.mutex);
- crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id);
- if (!crtc || (crtc->id != crtc_req.crtc_id)) {
- DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id);
+ crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req->crtc_id);
+ if (!crtc || (crtc->id != crtc_req->crtc_id)) {
+ DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
ret = -EINVAL;
goto out;
}
- if (crtc_req.mode) {
+ if (crtc_req->mode) {
/* if we have a mode we need a framebuffer */
- if (crtc_req.fb_id) {
- fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id);
- if (!fb || (fb->id != crtc_req.fb_id)) {
- DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id);
+ if (crtc_req->fb_id) {
+ fb = idr_find(&dev->mode_config.crtc_idr, crtc_req->fb_id);
+ if (!fb || (fb->id != crtc_req->fb_id)) {
+ DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
ret = -EINVAL;
goto out;
}
}
- mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode);
- if (!mode || (mode->mode_id != crtc_req.mode)) {
+ mode = idr_find(&dev->mode_config.crtc_idr, crtc_req->mode);
+ if (!mode || (mode->mode_id != crtc_req->mode)) {
struct drm_output *output;
list_for_each_entry(output,
@@ -1431,36 +1425,36 @@ int drm_mode_setcrtc(struct drm_device *dev,
}
}
- DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req.mode, mode);
+ DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req->mode, mode);
ret = -EINVAL;
goto out;
}
} else
mode = NULL;
- if (crtc_req.count_outputs == 0 && mode) {
+ if (crtc_req->count_outputs == 0 && mode) {
DRM_DEBUG("Count outputs is 0 but mode set\n");
ret = -EINVAL;
goto out;
}
- if (crtc_req.count_outputs > 0 && !mode && !fb) {
- DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);
+ if (crtc_req->count_outputs > 0 && !mode && !fb) {
+ DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req->count_outputs);
ret = -EINVAL;
goto out;
}
- if (crtc_req.count_outputs > 0) {
+ if (crtc_req->count_outputs > 0) {
u32 out_id;
- output_set = kmalloc(crtc_req.count_outputs *
+ output_set = kmalloc(crtc_req->count_outputs *
sizeof(struct drm_output *), GFP_KERNEL);
if (!output_set) {
ret = -ENOMEM;
goto out;
}
- for (i = 0; i < crtc_req.count_outputs; i++) {
- if (get_user(out_id, &crtc_req.set_outputs[i])) {
+ for (i = 0; i < crtc_req->count_outputs; i++) {
+ if (get_user(out_id, &crtc_req->set_outputs[i])) {
ret = -EFAULT;
goto out;
}
@@ -1476,7 +1470,7 @@ int drm_mode_setcrtc(struct drm_device *dev,
}
}
- ret = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);
+ ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb);
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -1503,29 +1497,25 @@ out:
int drm_mode_addfb(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_fb_cmd __user *argp = (void __user *)data;
- struct drm_mode_fb_cmd r;
+ struct drm_mode_fb_cmd *r = data;
struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb;
struct drm_buffer_object *bo;
struct drm_crtc *crtc;
int ret = 0;
- if (copy_from_user(&r, argp, sizeof(r)))
- return -EFAULT;
-
- if ((config->min_width > r.width) || (r.width > config->max_width)) {
+ if ((config->min_width > r->width) || (r->width > config->max_width)) {
DRM_ERROR("mode new framebuffer width not within limits\n");
return -EINVAL;
}
- if ((config->min_height > r.height) || (r.height > config->max_height)) {
+ if ((config->min_height > r->height) || (r->height > config->max_height)) {
DRM_ERROR("mode new framebuffer height not within limits\n");
return -EINVAL;
}
mutex_lock(&dev->mode_config.mutex);
/* TODO check limits are okay */
- ret = drm_get_buffer_object(dev, &bo, r.handle);
+ ret = drm_get_buffer_object(dev, &bo, r->handle);
if (ret || !bo) {
ret = -EINVAL;
goto out;
@@ -1540,23 +1530,18 @@ int drm_mode_addfb(struct drm_device *dev,
goto out;
}
- fb->width = r.width;
- fb->height = r.height;
- fb->pitch = r.pitch;
- fb->bits_per_pixel = r.bpp;
- fb->depth = r.depth;
+ fb->width = r->width;
+ fb->height = r->height;
+ fb->pitch = r->pitch;
+ fb->bits_per_pixel = r->bpp;
+ fb->depth = r->depth;
fb->offset = bo->offset;
fb->bo = bo;
- r.buffer_id = fb->id;
+ r->buffer_id = fb->id;
list_add(&fb->filp_head, &file_priv->fbs);
- if (copy_to_user(argp, &r, sizeof(r))) {
- ret = -EFAULT;
- goto out;
- }
-
/* FIXME: bind the fb to the right crtc */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
crtc->fb = fb;
@@ -1589,13 +1574,12 @@ int drm_mode_rmfb(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_framebuffer *fb = 0;
- uint32_t id = data;
+ uint32_t *id = data;
int ret = 0;
- mutex_lock(&dev->mode_config.mutex);
- fb = idr_find(&dev->mode_config.crtc_idr, id);
+ fb = idr_find(&dev->mode_config.crtc_idr, *id);
/* TODO check that we realy get a framebuffer back. */
- if (!fb || (id != fb->id)) {
+ if (!fb || (*id != fb->id)) {
DRM_ERROR("mode invalid framebuffer id\n");
ret = -EINVAL;
goto out;
@@ -1635,31 +1619,24 @@ out:
int drm_mode_getfb(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_fb_cmd __user *argp = (void __user *)data;
- struct drm_mode_fb_cmd r;
+ struct drm_mode_fb_cmd *r = data;
struct drm_framebuffer *fb;
int ret = 0;
- if (copy_from_user(&r, argp, sizeof(r)))
- return -EFAULT;
-
mutex_lock(&dev->mode_config.mutex);
- fb = idr_find(&dev->mode_config.crtc_idr, r.buffer_id);
- if (!fb || (r.buffer_id != fb->id)) {
+ fb = idr_find(&dev->mode_config.crtc_idr, r->buffer_id);
+ if (!fb || (r->buffer_id != fb->id)) {
DRM_ERROR("invalid framebuffer id\n");
ret = -EINVAL;
goto out;
}
- r.height = fb->height;
- r.width = fb->width;
- r.depth = fb->depth;
- r.bpp = fb->bits_per_pixel;
- r.handle = fb->bo->base.hash.key;
- r.pitch = fb->pitch;
-
- if (copy_to_user(argp, &r, sizeof(r)))
- ret = -EFAULT;
+ r->height = fb->height;
+ r->width = fb->width;
+ r->depth = fb->depth;
+ r->bpp = fb->bits_per_pixel;
+ r->handle = fb->bo->base.hash.key;
+ r->pitch = fb->pitch;
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -1713,14 +1690,10 @@ void drm_fb_release(struct file *filp)
int drm_mode_addmode(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_modeinfo __user *argp = (void __user *)data;
- struct drm_mode_modeinfo new_mode;
+ struct drm_mode_modeinfo *new_mode = data;
struct drm_display_mode *user_mode;
int ret = 0;
- if (copy_from_user(&new_mode, argp, sizeof(new_mode)))
- return -EFAULT;
-
mutex_lock(&dev->mode_config.mutex);
user_mode = drm_mode_create(dev);
if (!user_mode) {
@@ -1728,16 +1701,14 @@ int drm_mode_addmode(struct drm_device *dev,
goto out;
}
- drm_crtc_convert_umode(user_mode, &new_mode);
+ drm_crtc_convert_umode(user_mode, new_mode);
user_mode->type |= DRM_MODE_TYPE_USERDEF;
user_mode->output_count = 0;
list_add(&user_mode->head, &dev->mode_config.usermode_list);
- new_mode.id = user_mode->mode_id;
- if (copy_to_user(argp, &new_mode, sizeof(new_mode)))
- ret = -EFAULT;
+ new_mode->id = user_mode->mode_id;
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -1761,13 +1732,13 @@ out:
int drm_mode_rmmode(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- uint32_t id = (uint32_t)data;
+ uint32_t *id = data;
struct drm_display_mode *mode, *t;
int ret = -EINVAL;
mutex_lock(&dev->mode_config.mutex);
- mode = idr_find(&dev->mode_config.crtc_idr, id);
- if (!mode || (id != mode->mode_id)) {
+ mode = idr_find(&dev->mode_config.crtc_idr, *id);
+ if (!mode || (*id != mode->mode_id)) {
ret = -EINVAL;
goto out;
}
@@ -1812,25 +1783,21 @@ out:
int drm_mode_attachmode(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_mode_cmd __user *argp = (void __user *)data;
- struct drm_mode_mode_cmd mode_cmd;
+ struct drm_mode_mode_cmd *mode_cmd = data;
struct drm_output *output;
struct drm_display_mode *mode;
int i, ret = 0;
- if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd)))
- return -EFAULT;
-
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)) {
+ 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)) {
+ output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
+ if (!output || (output->id != mode_cmd->output_id)) {
ret = -EINVAL;
goto out;
}
@@ -1867,25 +1834,21 @@ out:
int drm_mode_detachmode(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_mode_cmd __user *argp = (void __user *)data;
- struct drm_mode_mode_cmd mode_cmd;
+ struct drm_mode_mode_cmd *mode_cmd = data;
struct drm_output *output;
struct drm_display_mode *mode;
int i, found = 0, ret = 0;
- if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd)))
- return -EFAULT;
-
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)) {
+ 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)) {
+ output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
+ if (!output || (output->id != mode_cmd->output_id)) {
ret = -EINVAL;
goto out;
}