Merge tag 'gpio-fixes-for-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / tty / vt / vt_ioctl.c
index 89aeaf3..0e0cd9e 100644 (file)
@@ -671,21 +671,58 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
        if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
                return -EFAULT;
 
-       if (v.v_vlin)
-               pr_info_once("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n");
-       if (v.v_clin)
-               pr_info_once("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n");
+       /* FIXME: Should check the copies properly */
+       if (!v.v_vlin)
+               v.v_vlin = vc->vc_scan_lines;
+
+       if (v.v_clin) {
+               int rows = v.v_vlin / v.v_clin;
+               if (v.v_rows != rows) {
+                       if (v.v_rows) /* Parameters don't add up */
+                               return -EINVAL;
+                       v.v_rows = rows;
+               }
+       }
+
+       if (v.v_vcol && v.v_ccol) {
+               int cols = v.v_vcol / v.v_ccol;
+               if (v.v_cols != cols) {
+                       if (v.v_cols)
+                               return -EINVAL;
+                       v.v_cols = cols;
+               }
+       }
+
+       if (v.v_clin > 32)
+               return -EINVAL;
 
-       console_lock();
        for (i = 0; i < MAX_NR_CONSOLES; i++) {
-               vc = vc_cons[i].d;
+               struct vc_data *vcp;
 
-               if (vc) {
-                       vc->vc_resize_user = 1;
-                       vc_resize(vc, v.v_cols, v.v_rows);
+               if (!vc_cons[i].d)
+                       continue;
+               console_lock();
+               vcp = vc_cons[i].d;
+               if (vcp) {
+                       int ret;
+                       int save_scan_lines = vcp->vc_scan_lines;
+                       int save_cell_height = vcp->vc_cell_height;
+
+                       if (v.v_vlin)
+                               vcp->vc_scan_lines = v.v_vlin;
+                       if (v.v_clin)
+                               vcp->vc_cell_height = v.v_clin;
+                       vcp->vc_resize_user = 1;
+                       ret = vc_resize(vcp, v.v_cols, v.v_rows);
+                       if (ret) {
+                               vcp->vc_scan_lines = save_scan_lines;
+                               vcp->vc_cell_height = save_cell_height;
+                               console_unlock();
+                               return ret;
+                       }
                }
+               console_unlock();
        }
-       console_unlock();
 
        return 0;
 }