no need to copy to/from user as the unlocked ioctl does
that for us. other small cleanups.main
parent
b2c4c7ae5e
commit
dfcf9272ce
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue