schedule_work(&console_work);
 }
 
-static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
+static void scrup(struct vc_data *vc, unsigned int t, unsigned int b,
+               unsigned int nr)
 {
        unsigned short *d, *s;
 
                    vc->vc_size_row * nr);
 }
 
-static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
+static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b,
+               unsigned int nr)
 {
        unsigned short *s;
        unsigned int step;
 
        mutex_unlock(&sisusb->lock);
 }
 
-static int
+static bool
 sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
-                                       int t, int b, int dir, int lines)
+               unsigned int t, unsigned int b, enum con_scroll dir,
+               unsigned int lines)
 {
        int cols = sisusb->sisusb_num_columns;
        int length = ((b - t) * cols) * 2;
 }
 
 /* Interface routine */
-static int
-sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+static bool
+sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
+               enum con_scroll dir, unsigned int lines)
 {
        struct sisusb_usb_data *sisusb;
        u16 eattr = c->vc_video_erase_char;
         */
 
        if (!lines)
-               return 1;
+               return true;
 
        sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num);
        if (!sisusb)
-               return 0;
+               return false;
 
        /* sisusb->lock is down */
 
        if (sisusb_is_inactive(c, sisusb)) {
                mutex_unlock(&sisusb->lock);
-               return 0;
+               return false;
        }
 
        /* Special case */
 
        mutex_unlock(&sisusb->lock);
 
-       return 1;
+       return true;
 }
 
 /* Interface routine */
 
                        int count, int ypos, int xpos);
 static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);
 static void fbcon_cursor(struct vc_data *vc, int mode);
-static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
-                       int count);
 static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
                        int height, int width);
 static int fbcon_switch(struct vc_data *vc);
        softback_curr = softback_in;
 }
 
-static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
-                       int count)
+static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+               enum con_scroll dir, unsigned int count)
 {
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        struct display *p = &fb_display[vc->vc_num];
        int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
 
        if (fbcon_is_inactive(vc, info))
-               return -EINVAL;
+               return true;
 
        fbcon_cursor(vc, CM_ERASE);
 
                                                        (b - count)),
                                    vc->vc_video_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       return true;
                        break;
 
                case SCROLL_WRAP_MOVE:
                                                        (b - count)),
                                    vc->vc_video_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       return true;
                }
                break;
 
                                                        t),
                                    vc->vc_video_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       return true;
                        break;
 
                case SCROLL_WRAP_MOVE:
                                                        t),
                                    vc->vc_video_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       return true;
                }
        }
-       return 0;
+       return false;
 }
 
 
 
        }
 }
 
-static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+static bool mdacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
+               enum con_scroll dir, unsigned int lines)
 {
        u16 eattr = mda_convert_attr(c->vc_video_erase_char);
 
        if (!lines)
-               return 0;
+               return false;
 
        if (lines > c->vc_rows)   /* maximum realistic size */
                lines = c->vc_rows;
                break;
        }
 
-       return 0;
+       return false;
 }
 
 
 
        return newport_set_font(vc->vc_num, font);
 }
 
-static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
-                         int lines)
+static bool newport_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
+               enum con_scroll dir, unsigned int lines)
 {
        int count, x, y;
        unsigned short *s, *d;
                                            (vc->vc_color & 0xf0) >> 4);
                }
                npregs->cset.topscan = (topscan - 1) & 0x3ff;
-               return 0;
+               return false;
        }
 
        count = (b - t - lines) * vc->vc_cols;
                        }
                }
        }
-       return 1;
+       return true;
 }
 
 static int newport_dummy(struct vc_data *c)
 
     }
 }
 
-static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+static bool sticon_scroll(struct vc_data *conp, unsigned int t,
+               unsigned int b, enum con_scroll dir, unsigned int count)
 {
     struct sti_struct *sti = sticon_sti;
 
     if (vga_is_gfx)
-        return 0;
+        return false;
 
     sticon_cursor(conp, CM_ERASE);
 
        break;
     }
 
-    return 0;
+    return false;
 }
 
 static void sticon_init(struct vc_data *c, int init)
 
 static void vgacon_scrolldelta(struct vc_data *c, int lines);
 static int vgacon_set_origin(struct vc_data *c);
 static void vgacon_save_screen(struct vc_data *c);
-static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
-                        int lines);
 static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
 static struct uni_pagedir *vgacon_uni_pagedir;
 static int vgacon_refcount;
                            c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size);
 }
 
-static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
-                        int lines)
+static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
+               enum con_scroll dir, unsigned int lines)
 {
        unsigned long oldo;
        unsigned int delta;
 
        if (t || b != c->vc_rows || vga_is_gfx || c->vc_mode != KD_TEXT)
-               return 0;
+               return false;
 
        if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
-               return 0;
+               return false;
 
        vgacon_restore_screen(c);
        oldo = c->vc_origin;
        c->vc_visible_origin = c->vc_origin;
        vga_set_mem_top(c);
        c->vc_pos = (c->vc_pos - oldo) + c->vc_origin;
-       return 1;
+       return true;
 }
 
 
 
 #define VT100ID "\033[?1;2c"
 #define VT102ID "\033[?6c"
 
+enum con_scroll {
+       SM_UP,
+       SM_DOWN,
+};
+
 /**
  * struct consw - callbacks for consoles
  *
+ * @con_scroll: move lines from @top to @bottom in direction @dir by @lines.
+ *             Return true if no generic handling should be done.
+ *             Invoked by csi_M and printing to the console.
  * @con_set_palette: sets the palette of the console to @table (optional)
  * @con_scrolldelta: the contents of the console should be scrolled by @lines.
  *                  Invoked by user. (optional)
        void    (*con_putc)(struct vc_data *, int, int, int);
        void    (*con_putcs)(struct vc_data *, const unsigned short *, int, int, int);
        void    (*con_cursor)(struct vc_data *, int);
-       int     (*con_scroll)(struct vc_data *, int, int, int, int);
+       bool    (*con_scroll)(struct vc_data *, unsigned int top,
+                       unsigned int bottom, enum con_scroll dir,
+                       unsigned int lines);
        int     (*con_switch)(struct vc_data *);
        int     (*con_blank)(struct vc_data *, int, int);
        int     (*con_font_set)(struct vc_data *, struct console_font *, unsigned);
 }
 #endif
 
-/* scroll */
-#define SM_UP       (1)
-#define SM_DOWN     (2)
-
 /* cursor */
 #define CM_DRAW     (1)
 #define CM_ERASE    (2)