* [PATCH 5/5]: fbcon module unloading
@ 2003-02-16 6:09 Antonino Daplas
2003-02-16 6:23 ` Antonino Daplas
0 siblings, 1 reply; 2+ messages in thread
From: Antonino Daplas @ 2003-02-16 6:09 UTC (permalink / raw)
To: James Simmons, Geert Uytterhoeven; +Cc: Linux Fbdev development list
[-- Attachment #1: Type: text/plain, Size: 101 bytes --]
Attached is a rediff (linux-2.5.61 + James' fbdev.diff) to enable fbcon module unloading.
Tony
[-- Attachment #2: fbcon_unload.diff --]
[-- Type: text/x-patch, Size: 7222 bytes --]
diff -Naur linux-2.5.61-fbdev/drivers/char/vt.c linux-2.5.61-ad/drivers/char/vt.c
--- linux-2.5.61-fbdev/drivers/char/vt.c 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/char/vt.c 2003-02-16 04:52:07.000000000 +0000
@@ -109,6 +109,7 @@
const struct consw *conswitchp;
+const struct consw *defcsw = NULL; /* for recovery of default console */
/* A bitmap for codes <32. A bit of 1 indicates that the code
* corresponding to that bit number invokes some special action
@@ -2571,10 +2572,14 @@
int i, j = -1;
const char *desc;
+ if (deflt && defcsw != NULL)
+ return;
desc = csw->con_startup();
if (!desc) return;
- if (deflt)
+ if (deflt) {
+ defcsw = conswitchp;
conswitchp = csw;
+ }
for (i = first; i <= last; i++) {
int old_was_color;
@@ -2616,11 +2621,78 @@
void give_up_console(const struct consw *csw)
{
- int i;
+ const char *desc;
+ int i, j = -1, first = -1, last = -1;
- for(i = 0; i < MAX_NR_CONSOLES; i++)
- if (con_driver_map[i] == csw)
+ for(i = 0; i < MAX_NR_CONSOLES; i++) {
+ if (con_driver_map[i] == csw) {
+ if (first == -1)
+ first = i;
+ last = i;
con_driver_map[i] = NULL;
+ }
+ }
+
+ if (defcsw == NULL)
+ return;
+ conswitchp = defcsw;
+ defcsw = NULL;
+
+ desc = conswitchp->con_startup();
+ if (!desc) return;
+
+ for (i = first; i <= last; i++) {
+ int old_was_color;
+ int currcons = i;
+
+ con_driver_map[i] = conswitchp;
+
+ if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)
+ continue;
+ j = i;
+ if (IS_VISIBLE)
+ save_screen(i);
+ old_was_color = vc_cons[i].d->vc_can_do_color;
+ vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);
+ visual_init(i, 0);
+ set_origin(i);
+
+ /*
+ * partial reset_terminal()
+ */
+ top = 0;
+ bottom = video_num_lines;
+ gotoxy(i, x, y);
+ save_cur(i);
+ update_attr(i);
+
+
+ /* If the console changed between mono <-> color, then
+ * the attributes in the screenbuf will be wrong. The
+ * following resets all attributes to something sane.
+ */
+ if (old_was_color != vc_cons[i].d->vc_can_do_color ||
+ IS_VISIBLE)
+ clear_buffer_attributes(i);
+
+ if (IS_VISIBLE)
+ update_screen(i);
+ if (vc_cons[i].d->vc_tty) {
+ kill_pg(vc_cons[i].d->vc_tty->pgrp, SIGWINCH, 1);
+ vc_cons[i].d->vc_tty->winsize.ws_col =
+ video_num_columns;
+ vc_cons[i].d->vc_tty->winsize.ws_row =
+ video_num_lines;
+ }
+ }
+ printk("Console: switching ");
+ if (j >= 0)
+ printk("to %s %s %dx%d\n",
+ vc_cons[j].d->vc_can_do_color ? "colour" : "mono",
+ desc, vc_cons[j].d->vc_cols, vc_cons[j].d->vc_rows);
+ else
+ printk("to %s\n", desc);
+
}
#endif
diff -Naur linux-2.5.61-fbdev/drivers/video/console/Kconfig linux-2.5.61-ad/drivers/video/console/Kconfig
--- linux-2.5.61-fbdev/drivers/video/console/Kconfig 2003-02-16 00:49:23.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/console/Kconfig 2003-02-16 04:52:07.000000000 +0000
@@ -106,6 +106,19 @@
tristate "Framebuffer Console support"
depends on FB
+config FRAMEBUFFER_CONSOLE_UNLOAD
+ bool "Allow Framebuffer Console Module Unloading (DANGEROUS)"
+ depends on FRAMEBUFFER_CONSOLE=m
+ default n
+ ---help---
+ If you say Y, the framebuffer console module can be unloaded
+ and the console reverted to the default console driver that was
+ loaded at boot time. Not all drivers support unloading, and even
+ if it does, it might leave you with a corrupted display.
+
+ Unless you are a framebuffer driver developer, or you really know
+ what you're doing, say N here.
+
config PCI_CONSOLE
bool
depends on FRAMEBUFFER_CONSOLE
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.c linux-2.5.61-ad/drivers/video/console/fbcon.c
--- linux-2.5.61-fbdev/drivers/video/console/fbcon.c 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/console/fbcon.c 2003-02-16 04:52:07.000000000 +0000
@@ -199,6 +199,23 @@
static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
int dx, int height, int width, u_int y_break);
+/*
+ * fbcon module unloading
+ */
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD
+static void __init fbcon_mod_unload(struct fb_info *info)
+{
+ if (!info->fbops->fb_release)
+ __unsafe(THIS_MODULE);
+}
+#else
+static void __init fbcon_mod_unload(struct fb_info *info)
+{
+ __unsafe(THIS_MODULE);
+}
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD */
+
#ifdef CONFIG_MAC
/*
* On the Macintoy, there may or may not be a working VBL int. We need to probe
@@ -580,7 +597,7 @@
struct fb_info *info;
struct vc_data *vc;
static int done = 0;
- int irqres = 1;
+ int irqres = 1, i;
/*
* If num_registered_fb is zero, this is a call for the dummy part.
@@ -590,8 +607,11 @@
return display_desc;
done = 1;
- info = registered_fb[num_registered_fb-1];
- if (!info) return NULL;
+ for (i = 0; i < FB_MAX; i++) {
+ info = registered_fb[i];
+ if (info != NULL)
+ break;
+ }
info->currcon = -1;
owner = info->fbops->owner;
@@ -2558,19 +2578,86 @@
int __init fb_console_init(void)
{
+ struct fb_info *info = NULL;
+ int i, unit = 0;
+
if (!num_registered_fb)
return -ENODEV;
+ for (i = 0; i < FB_MAX; i++) {
+ info = registered_fb[i];
+ if (info != NULL) {
+ unit = i;
+ break;
+ }
+ }
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ con2fb_map[i] = unit;
take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
+ fbcon_mod_unload(info);
+ return 0;
+}
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD
+static int __exit fbcon_exit(void)
+{
+ struct fb_info *info;
+ int i, j, mapped;
+
+ for (i = 0; i < FB_MAX; i++) {
+ info = registered_fb[i];
+ if (info != NULL && !info->fbops->fb_release)
+ return -EINVAL;
+ }
+
+ del_timer_sync(&cursor_timer);
+#ifdef CONFIG_AMIGA
+ if (MACH_IS_AMIGA)
+ free_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler);
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+ if (MACH_IS_ATARI)
+ free_irq(IRQ_AUTO_4, fbcon_vbl_handler);
+#endif /* CONFIG_ATARI */
+#ifdef CONFIG_MAC
+ if (MACH_IS_MAC && vbl_detected)
+ free_irq(IRQ_MAC_VBL, fbcon_vbl_handler);
+#endif /* CONFIG_MAC */
+#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
+ free_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler);
+#endif
+ if (softback_buf)
+ kfree((void *) softback_buf);
+
+ for (i = 0; i < FB_MAX; i++) {
+ mapped = 0;
+ info = registered_fb[i];
+ if (info == NULL)
+ continue;
+ for (j = 0; j < MAX_NR_CONSOLES; j++) {
+ if (con2fb_map[j] == i) {
+ con2fb_map[j] = -1;
+ mapped = 1;
+ }
+ }
+ if (mapped) {
+ info->fbops->fb_release(info, 0);
+ module_put(info->fbops->owner);
+ kfree(info->display_fg);
+ }
+ }
return 0;
}
void __exit fb_console_exit(void)
{
+ if (fbcon_exit())
+ return;
give_up_console(&fb_con);
}
+module_exit(fb_console_exit);
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD */
module_init(fb_console_init);
-module_exit(fb_console_exit);
/*
* Visible symbols for modules
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH 5/5]: fbcon module unloading
2003-02-16 6:09 [PATCH 5/5]: fbcon module unloading Antonino Daplas
@ 2003-02-16 6:23 ` Antonino Daplas
0 siblings, 0 replies; 2+ messages in thread
From: Antonino Daplas @ 2003-02-16 6:23 UTC (permalink / raw)
To: Antonino Daplas
Cc: James Simmons, Geert Uytterhoeven, Linux Fbdev development list
[-- Attachment #1: Type: text/plain, Size: 228 bytes --]
On Sun, 2003-02-16 at 14:09, Antonino Daplas wrote:
> Attached is a rediff (linux-2.5.61 + James' fbdev.diff) to enable fbcon module unloading.
>
Oops. Please disregard the previous patch. Attached is an updated
diff.
Tony
[-- Attachment #2: fbcon_unload.diff --]
[-- Type: text/x-patch, Size: 7432 bytes --]
diff -Naur linux-2.5.61-fbdev/drivers/char/vt.c linux-2.5.61-ad/drivers/char/vt.c
--- linux-2.5.61-fbdev/drivers/char/vt.c 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/char/vt.c 2003-02-16 06:17:36.000000000 +0000
@@ -109,6 +109,7 @@
const struct consw *conswitchp;
+const struct consw *defcsw = NULL; /* for recovery of default console */
/* A bitmap for codes <32. A bit of 1 indicates that the code
* corresponding to that bit number invokes some special action
@@ -2571,10 +2572,14 @@
int i, j = -1;
const char *desc;
+ if (deflt && defcsw != NULL)
+ return;
desc = csw->con_startup();
if (!desc) return;
- if (deflt)
+ if (deflt) {
+ defcsw = conswitchp;
conswitchp = csw;
+ }
for (i = first; i <= last; i++) {
int old_was_color;
@@ -2616,11 +2621,78 @@
void give_up_console(const struct consw *csw)
{
- int i;
+ const char *desc;
+ int i, j = -1, first = -1, last = -1;
- for(i = 0; i < MAX_NR_CONSOLES; i++)
- if (con_driver_map[i] == csw)
+ for(i = 0; i < MAX_NR_CONSOLES; i++) {
+ if (con_driver_map[i] == csw) {
+ if (first == -1)
+ first = i;
+ last = i;
con_driver_map[i] = NULL;
+ }
+ }
+
+ if (defcsw == NULL)
+ return;
+ conswitchp = defcsw;
+ defcsw = NULL;
+
+ desc = conswitchp->con_startup();
+ if (!desc) return;
+
+ for (i = first; i <= last; i++) {
+ int old_was_color;
+ int currcons = i;
+
+ con_driver_map[i] = conswitchp;
+
+ if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)
+ continue;
+ j = i;
+ if (IS_VISIBLE)
+ save_screen(i);
+ old_was_color = vc_cons[i].d->vc_can_do_color;
+ vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);
+ visual_init(i, 0);
+ set_origin(i);
+
+ /*
+ * partial reset_terminal()
+ */
+ top = 0;
+ bottom = video_num_lines;
+ gotoxy(i, x, y);
+ save_cur(i);
+ update_attr(i);
+
+
+ /* If the console changed between mono <-> color, then
+ * the attributes in the screenbuf will be wrong. The
+ * following resets all attributes to something sane.
+ */
+ if (old_was_color != vc_cons[i].d->vc_can_do_color ||
+ IS_VISIBLE)
+ clear_buffer_attributes(i);
+
+ if (IS_VISIBLE)
+ update_screen(i);
+ if (vc_cons[i].d->vc_tty) {
+ kill_pg(vc_cons[i].d->vc_tty->pgrp, SIGWINCH, 1);
+ vc_cons[i].d->vc_tty->winsize.ws_col =
+ video_num_columns;
+ vc_cons[i].d->vc_tty->winsize.ws_row =
+ video_num_lines;
+ }
+ }
+ printk("Console: switching ");
+ if (j >= 0)
+ printk("to %s %s %dx%d\n",
+ vc_cons[j].d->vc_can_do_color ? "colour" : "mono",
+ desc, vc_cons[j].d->vc_cols, vc_cons[j].d->vc_rows);
+ else
+ printk("to %s\n", desc);
+
}
#endif
diff -Naur linux-2.5.61-fbdev/drivers/video/console/Kconfig linux-2.5.61-ad/drivers/video/console/Kconfig
--- linux-2.5.61-fbdev/drivers/video/console/Kconfig 2003-02-16 00:49:23.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/console/Kconfig 2003-02-16 06:17:36.000000000 +0000
@@ -106,6 +106,19 @@
tristate "Framebuffer Console support"
depends on FB
+config FRAMEBUFFER_CONSOLE_UNLOAD
+ bool "Allow Framebuffer Console Module Unloading (DANGEROUS)"
+ depends on FRAMEBUFFER_CONSOLE=m
+ default n
+ ---help---
+ If you say Y, the framebuffer console module can be unloaded
+ and the console reverted to the default console driver that was
+ loaded at boot time. Not all drivers support unloading, and even
+ if it does, it might leave you with a corrupted display.
+
+ Unless you are a framebuffer driver developer, or you really know
+ what you're doing, say N here.
+
config PCI_CONSOLE
bool
depends on FRAMEBUFFER_CONSOLE
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.c linux-2.5.61-ad/drivers/video/console/fbcon.c
--- linux-2.5.61-fbdev/drivers/video/console/fbcon.c 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/console/fbcon.c 2003-02-16 06:18:29.000000000 +0000
@@ -146,6 +146,7 @@
static int vbl_cursor_cnt;
static int cursor_on;
static int cursor_blink_rate;
+static int irqres = 1;
static inline void cursor_undrawn(void)
{
@@ -199,6 +200,23 @@
static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
int dx, int height, int width, u_int y_break);
+/*
+ * fbcon module unloading
+ */
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD
+static void __init fbcon_mod_unload(struct fb_info *info)
+{
+ if (!info->fbops->fb_release)
+ __unsafe(THIS_MODULE);
+}
+#else
+static void __init fbcon_mod_unload(struct fb_info *info)
+{
+ __unsafe(THIS_MODULE);
+}
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD */
+
#ifdef CONFIG_MAC
/*
* On the Macintoy, there may or may not be a working VBL int. We need to probe
@@ -580,7 +598,7 @@
struct fb_info *info;
struct vc_data *vc;
static int done = 0;
- int irqres = 1;
+ int i;
/*
* If num_registered_fb is zero, this is a call for the dummy part.
@@ -590,8 +608,11 @@
return display_desc;
done = 1;
- info = registered_fb[num_registered_fb-1];
- if (!info) return NULL;
+ for (i = 0; i < FB_MAX; i++) {
+ info = registered_fb[i];
+ if (info != NULL)
+ break;
+ }
info->currcon = -1;
owner = info->fbops->owner;
@@ -2558,19 +2579,89 @@
int __init fb_console_init(void)
{
+ struct fb_info *info = NULL;
+ int i, unit = 0;
+
if (!num_registered_fb)
return -ENODEV;
+ for (i = 0; i < FB_MAX; i++) {
+ info = registered_fb[i];
+ if (info != NULL) {
+ unit = i;
+ break;
+ }
+ }
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ con2fb_map[i] = unit;
take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
+ fbcon_mod_unload(info);
+ return 0;
+}
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD
+static int __exit fbcon_exit(void)
+{
+ struct fb_info *info;
+ int i, j, mapped;
+
+ for (i = 0; i < FB_MAX; i++) {
+ info = registered_fb[i];
+ if (info != NULL && !info->fbops->fb_release)
+ return -EINVAL;
+ }
+
+ if (irqres) {
+ del_timer_sync(&cursor_timer);
+ } else {
+#ifdef CONFIG_AMIGA
+ if (MACH_IS_AMIGA)
+ free_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler);
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+ if (MACH_IS_ATARI)
+ free_irq(IRQ_AUTO_4, fbcon_vbl_handler);
+#endif /* CONFIG_ATARI */
+#ifdef CONFIG_MAC
+ if (MACH_IS_MAC && vbl_detected)
+ free_irq(IRQ_MAC_VBL, fbcon_vbl_handler);
+#endif /* CONFIG_MAC */
+#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
+ free_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler);
+#endif
+ }
+ if (softback_buf)
+ kfree((void *) softback_buf);
+
+ for (i = 0; i < FB_MAX; i++) {
+ mapped = 0;
+ info = registered_fb[i];
+ if (info == NULL)
+ continue;
+ for (j = 0; j < MAX_NR_CONSOLES; j++) {
+ if (con2fb_map[j] == i) {
+ con2fb_map[j] = -1;
+ mapped = 1;
+ }
+ }
+ if (mapped) {
+ info->fbops->fb_release(info, 0);
+ module_put(info->fbops->owner);
+ kfree(info->display_fg);
+ }
+ }
return 0;
}
void __exit fb_console_exit(void)
{
+ if (fbcon_exit())
+ return;
give_up_console(&fb_con);
}
+module_exit(fb_console_exit);
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_UNLOAD */
module_init(fb_console_init);
-module_exit(fb_console_exit);
/*
* Visible symbols for modules
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-02-16 6:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-02-16 6:09 [PATCH 5/5]: fbcon module unloading Antonino Daplas
2003-02-16 6:23 ` Antonino Daplas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).