Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152806030
D687.id3176.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D687.id3176.diff
View Options
Index: sys/dev/drm2/drm_fb_helper.c
===================================================================
--- sys/dev/drm2/drm_fb_helper.c
+++ sys/dev/drm2/drm_fb_helper.c
@@ -934,19 +934,21 @@
info->fb_priv = sc;
info->enter = &vt_kms_postswitch;
+ kdev = fb_helper->dev->device;
+ info->fb_video_dev = device_get_parent(kdev);
+
/* set the fb pointer */
for (i = 0; i < fb_helper->crtc_count; i++) {
fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
}
if (new_fb) {
- device_t fbd;
int ret;
- kdev = fb_helper->dev->device;
- fbd = device_add_child(kdev, "fbd", device_get_unit(kdev));
- if (fbd != NULL)
- ret = device_probe_and_attach(fbd);
+ info->fb_fbd_dev = device_add_child(kdev, "fbd",
+ device_get_unit(kdev));
+ if (info->fb_fbd_dev != NULL)
+ ret = device_probe_and_attach(info->fb_fbd_dev);
else
ret = ENODEV;
#ifdef DEV_VT
Index: sys/dev/drm2/radeon/radeon_fb.c
===================================================================
--- sys/dev/drm2/radeon/radeon_fb.c
+++ sys/dev/drm2/radeon/radeon_fb.c
@@ -291,6 +291,8 @@
if (rfbdev->helper.fbdev) {
info = rfbdev->helper.fbdev;
+ if (info->fb_fbd_dev != NULL)
+ device_delete_child(dev->device, info->fb_fbd_dev);
free(info->fb_priv, DRM_MEM_KMS);
free(info, DRM_MEM_KMS);
}
Index: sys/dev/fb/fbd.c
===================================================================
--- sys/dev/fb/fbd.c
+++ sys/dev/fb/fbd.c
@@ -262,6 +262,8 @@
LIST_FOREACH_SAFE(entry, &fb_list_head, fb_list, tmp) {
if (entry->fb_info == info) {
LIST_REMOVE(entry, fb_list);
+ if (LIST_EMPTY(&fb_list_head))
+ vt_fb_detach(info);
free(entry, M_DEVBUF);
return (0);
}
Index: sys/dev/pci/pcivar.h
===================================================================
--- sys/dev/pci/pcivar.h
+++ sys/dev/pci/pcivar.h
@@ -565,5 +565,6 @@
int vga_pci_is_boot_display(device_t dev);
void * vga_pci_map_bios(device_t dev, size_t *size);
void vga_pci_unmap_bios(device_t dev, void *bios);
+int vga_pci_repost(device_t dev);
#endif /* _PCIVAR_H_ */
Index: sys/dev/pci/vga_pci.c
===================================================================
--- sys/dev/pci/vga_pci.c
+++ sys/dev/pci/vga_pci.c
@@ -51,6 +51,8 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#include <compat/x86bios/x86bios.h> /* To re-POST the card. */
+
struct vga_resource {
struct resource *vr_res;
int vr_refs;
@@ -194,6 +196,36 @@
vr->vr_res);
}
+int
+vga_pci_repost(device_t dev)
+{
+#if defined(__amd64__) || defined(__i386__)
+ x86regs_t regs;
+
+ if (!vga_pci_is_boot_display(dev))
+ return (EINVAL);
+
+ if (x86bios_get_orm(VGA_PCI_BIOS_SHADOW_ADDR) == NULL)
+ return (ENOTSUP);
+
+ x86bios_init_regs(®s);
+
+ regs.R_AH = pci_get_bus(dev);
+ regs.R_AL = (pci_get_slot(dev) << 3) | (pci_get_function(dev) & 0x07);
+ regs.R_DL = 0x80;
+
+ device_printf(dev, "REPOSTing\n");
+ x86bios_call(®s, X86BIOS_PHYSTOSEG(VGA_PCI_BIOS_SHADOW_ADDR + 3),
+ X86BIOS_PHYSTOOFF(VGA_PCI_BIOS_SHADOW_ADDR + 3));
+
+ x86bios_get_intr(0x10);
+
+ return (0);
+#else
+ return (ENOTSUP);
+#endif
+}
+
static int
vga_pci_probe(device_t dev)
{
Index: sys/dev/vt/hw/fb/vt_fb.h
===================================================================
--- sys/dev/vt/hw/fb/vt_fb.h
+++ sys/dev/vt/hw/fb/vt_fb.h
@@ -35,8 +35,10 @@
int vt_fb_attach(struct fb_info *info);
void vt_fb_resume(void);
void vt_fb_suspend(void);
+int vt_fb_detach(struct fb_info *info);
vd_init_t vt_fb_init;
+vd_fini_t vt_fb_fini;
vd_blank_t vt_fb_blank;
vd_bitblt_text_t vt_fb_bitblt_text;
vd_bitblt_bmp_t vt_fb_bitblt_bitmap;
Index: sys/dev/vt/hw/fb/vt_fb.c
===================================================================
--- sys/dev/vt/hw/fb/vt_fb.c
+++ sys/dev/vt/hw/fb/vt_fb.c
@@ -44,6 +44,7 @@
static struct vt_driver vt_fb_driver = {
.vd_name = "fb",
.vd_init = vt_fb_init,
+ .vd_fini = vt_fb_fini,
.vd_blank = vt_fb_blank,
.vd_bitblt_text = vt_fb_bitblt_text,
.vd_bitblt_bmp = vt_fb_bitblt_bitmap,
@@ -417,6 +418,7 @@
info = vd->vd_softc;
vd->vd_height = info->fb_height;
vd->vd_width = info->fb_width;
+ vd->vd_video_dev = info->fb_video_dev;
if (info->fb_size == 0)
return (CN_DEAD);
@@ -440,6 +442,13 @@
return (CN_INTERNAL);
}
+void
+vt_fb_fini(struct vt_device *vd, void *softc)
+{
+
+ vd->vd_video_dev = NULL;
+}
+
int
vt_fb_attach(struct fb_info *info)
{
@@ -449,6 +458,15 @@
return (0);
}
+int
+vt_fb_detach(struct fb_info *info)
+{
+
+ vt_deallocate(&vt_fb_driver, info);
+
+ return (0);
+}
+
void
vt_fb_resume(void)
{
Index: sys/dev/vt/hw/vga/vt_vga.c
===================================================================
--- sys/dev/vt/hw/vga/vt_vga.c
+++ sys/dev/vt/hw/vga/vt_vga.c
@@ -42,6 +42,7 @@
#include <dev/vt/vt.h>
#include <dev/vt/hw/vga/vt_vga_reg.h>
+#include <dev/pci/pcivar.h>
#include <machine/bus.h>
@@ -1213,6 +1214,9 @@
sc = vd->vd_softc;
textmode = 0;
+ if (vd->vd_flags & VDF_DOWNGRADE && vd->vd_video_dev != NULL)
+ vga_pci_repost(vd->vd_video_dev);
+
#if defined(__amd64__) || defined(__i386__)
sc->vga_fb_tag = X86_BUS_SPACE_MEM;
sc->vga_fb_handle = KERNBASE + VGA_MEM_BASE;
Index: sys/dev/vt/vt.h
===================================================================
--- sys/dev/vt/vt.h
+++ sys/dev/vt/vt.h
@@ -89,7 +89,8 @@
struct vt_driver;
-void vt_allocate(struct vt_driver *, void *);
+void vt_allocate(const struct vt_driver *, void *);
+void vt_deallocate(const struct vt_driver *, void *);
void vt_resume(void);
void vt_suspend(void);
@@ -126,6 +127,9 @@
struct vt_pastebuf vd_pastebuf; /* (?) Copy/paste buf. */
const struct vt_driver *vd_driver; /* (c) Graphics driver. */
void *vd_softc; /* (u) Driver data. */
+ const struct vt_driver *vd_prev_driver;/* (?) Previous driver. */
+ void *vd_prev_softc; /* (?) Previous driver data. */
+ device_t vd_video_dev; /* (?) Video adapter. */
#ifndef SC_NO_CUTPASTE
struct vt_mouse_cursor *vd_mcursor; /* (?) Cursor bitmap. */
term_color_t vd_mcursor_fg; /* (?) Cursor fg color. */
@@ -152,6 +156,7 @@
#define VDF_INITIALIZED 0x20 /* vtterm_cnprobe already done. */
#define VDF_MOUSECURSOR 0x40 /* Mouse cursor visible. */
#define VDF_QUIET_BELL 0x80 /* Disable bell. */
+#define VDF_DOWNGRADE 0x8000 /* The driver is being downgraded. */
int vd_keyboard; /* (G) Keyboard index. */
unsigned int vd_kbstate; /* (?) Device unit. */
unsigned int vd_unit; /* (c) Device unit. */
@@ -300,6 +305,7 @@
typedef int vd_init_t(struct vt_device *vd);
typedef int vd_probe_t(struct vt_device *vd);
+typedef void vd_fini_t(struct vt_device *vd, void *softc);
typedef void vd_postswitch_t(struct vt_device *vd);
typedef void vd_blank_t(struct vt_device *vd, term_color_t color);
typedef void vd_bitblt_text_t(struct vt_device *vd, const struct vt_window *vw,
@@ -320,6 +326,7 @@
/* Console attachment. */
vd_probe_t *vd_probe;
vd_init_t *vd_init;
+ vd_fini_t *vd_fini;
/* Drawing. */
vd_blank_t *vd_blank;
Index: sys/dev/vt/vt_core.c
===================================================================
--- sys/dev/vt/vt_core.c
+++ sys/dev/vt/vt_core.c
@@ -178,6 +178,8 @@
static struct vt_device vt_consdev = {
.vd_driver = NULL,
.vd_softc = NULL,
+ .vd_prev_driver = NULL,
+ .vd_prev_softc = NULL,
.vd_flags = VDF_INVALID,
.vd_windows = { [VT_CONSWINDOW] = &vt_conswindow, },
.vd_curwindow = &vt_conswindow,
@@ -2582,31 +2584,11 @@
}
}
-void
-vt_allocate(struct vt_driver *drv, void *softc)
+static void
+vt_replace_backend(const struct vt_driver *drv, void *softc)
{
struct vt_device *vd;
- if (!vty_enabled(VTY_VT))
- return;
-
- if (main_vd->vd_driver == NULL) {
- main_vd->vd_driver = drv;
- printf("VT: initialize with new VT driver \"%s\".\n",
- drv->vd_name);
- } else {
- /*
- * Check if have rights to replace current driver. For example:
- * it is bad idea to replace KMS driver with generic VGA one.
- */
- if (drv->vd_priority <= main_vd->vd_driver->vd_priority) {
- printf("VT: Driver priority %d too low. Current %d\n ",
- drv->vd_priority, main_vd->vd_driver->vd_priority);
- return;
- }
- printf("VT: Replacing driver \"%s\" with new \"%s\".\n",
- main_vd->vd_driver->vd_name, drv->vd_name);
- }
vd = main_vd;
if (vd->vd_flags & VDF_ASYNC) {
@@ -2628,9 +2610,44 @@
VT_LOCK(vd);
vd->vd_flags &= ~VDF_TEXTMODE;
- vd->vd_driver = drv;
- vd->vd_softc = softc;
- vd->vd_driver->vd_init(vd);
+ if (drv != NULL) {
+ /*
+ * We want to upgrade from the current driver to the
+ * given driver.
+ */
+
+ vd->vd_prev_driver = vd->vd_driver;
+ vd->vd_prev_softc = vd->vd_softc;
+ vd->vd_driver = drv;
+ vd->vd_softc = softc;
+
+ vd->vd_driver->vd_init(vd);
+ } else if (vd->vd_prev_driver != NULL && vd->vd_prev_softc != NULL) {
+ /*
+ * No driver given: we want to downgrade to the previous
+ * driver.
+ */
+ const struct vt_driver *old_drv;
+ void *old_softc;
+
+ old_drv = vd->vd_driver;
+ old_softc = vd->vd_softc;
+
+ vd->vd_driver = vd->vd_prev_driver;
+ vd->vd_softc = vd->vd_prev_softc;
+ vd->vd_prev_driver = NULL;
+ vd->vd_prev_softc = NULL;
+
+ vd->vd_flags |= VDF_DOWNGRADE;
+
+ vd->vd_driver->vd_init(vd);
+
+ if (old_drv->vd_fini)
+ old_drv->vd_fini(vd, old_softc);
+
+ vd->vd_flags &= ~VDF_DOWNGRADE;
+ }
+
VT_UNLOCK(vd);
/* Update windows sizes and initialize last items. */
@@ -2656,6 +2673,52 @@
}
void
+vt_allocate(const struct vt_driver *drv, void *softc)
+{
+
+ if (!vty_enabled(VTY_VT))
+ return;
+
+ if (main_vd->vd_driver == NULL) {
+ main_vd->vd_driver = drv;
+ printf("VT: initialize with new VT driver \"%s\".\n",
+ drv->vd_name);
+ } else {
+ /*
+ * Check if have rights to replace current driver. For example:
+ * it is bad idea to replace KMS driver with generic VGA one.
+ */
+ if (drv->vd_priority <= main_vd->vd_driver->vd_priority) {
+ printf("VT: Driver priority %d too low. Current %d\n ",
+ drv->vd_priority, main_vd->vd_driver->vd_priority);
+ return;
+ }
+ printf("VT: Replacing driver \"%s\" with new \"%s\".\n",
+ main_vd->vd_driver->vd_name, drv->vd_name);
+ }
+
+ vt_replace_backend(drv, softc);
+}
+
+void
+vt_deallocate(const struct vt_driver *drv, void *softc)
+{
+
+ if (!vty_enabled(VTY_VT))
+ return;
+
+ if (main_vd->vd_prev_driver == NULL ||
+ main_vd->vd_driver != drv ||
+ main_vd->vd_softc != softc)
+ return;
+
+ printf("VT: Switching back from \"%s\" to \"%s\".\n",
+ main_vd->vd_driver->vd_name, main_vd->vd_prev_driver->vd_name);
+
+ vt_replace_backend(NULL, NULL);
+}
+
+void
vt_suspend()
{
Index: sys/sys/fbio.h
===================================================================
--- sys/sys/fbio.h
+++ sys/sys/fbio.h
@@ -127,6 +127,9 @@
struct cdev *fb_cdev;
+ device_t fb_fbd_dev; /* "fbd" device. */
+ device_t fb_video_dev; /* Video adapter. */
+
fb_enter_t *enter;
fb_leave_t *leave;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 18, 5:48 AM (1 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31701546
Default Alt Text
D687.id3176.diff (10 KB)
Attached To
Mode
D687: vt(4): Add support to "downgrade" from eg. vt_fb to vt_vga
Attached
Detach File
Event Timeline
Log In to Comment