--- ofwfb.c.orig 2025-12-16 17:31:07.000000000 +0000 +++ ofwfb.c 2026-01-22 22:54:43.858960000 +0000 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,8 @@ #include #include #include +#include +#include struct ofwfb_softc { struct fb_info fb; @@ -94,6 +97,7 @@ ofwfb_probe(struct vt_device *vd) { int disabled; + struct ofwfb_softc *sc; phandle_t chosen, node; ihandle_t stdout; char buf[64]; @@ -107,6 +111,7 @@ if (chosen == -1) return (CN_DEAD); + sc = &ofwfb_conssoftc; node = -1; if (OF_getencprop(chosen, "stdout", &stdout, sizeof(stdout)) == sizeof(stdout)) @@ -120,16 +125,105 @@ * using "screen" directly. */ node = OF_finddevice("screen"); + if (node == -1) + return (CN_DEAD); + stdout = OF_open("screen"); } + OF_getprop(node, "device_type", buf, sizeof(buf)); if (strcmp(buf, "display") != 0) return (CN_DEAD); + sc->sc_handle = stdout; + sc->sc_node = node; + /* Looks OK... */ return (CN_INTERNAL); } static void +ofwfb_dev_identify(driver_t *driver, device_t parent) +{ + + /* Try to guess if we need a device attachment. */ + if (ofwfb_conssoftc.sc_node > 0) + return; + + if (device_find_child(parent, "fb", -1) != NULL) + return; + + device_add_child(parent, "fb", -1); +} + +static int +ofwfb_dev_probe(device_t dev) +{ + phandle_t node; + device_t check; + const char *type; + + check = dev; + node = ofw_bus_get_node(check); + + /* This may be a fake child of an OF node. */ + if (node == -1) { + /* Check the parent. */ + check = device_get_parent(check); + node = ofw_bus_get_node(check); + if (node == -1) + return (ENXIO); + } + + type = ofw_bus_get_type(check); + if ((type == NULL || strcmp(type, "display") != 0) + && pci_get_class(check) != PCIC_DISPLAY) + return (ENXIO); + + device_set_desc(dev, "Open Firmware video console"); + return (BUS_PROBE_DEFAULT); +} + +static int +ofwfb_dev_attach(device_t dev) +{ + struct ofwfb_softc *sc = &ofwfb_conssoftc; + phandle_t node; + + device_set_softc(dev, sc); + + node = ofw_bus_get_node(dev); + + /* This may be a fake child of an OF node. */ + if (node == -1) { + /* Check the parent. */ + node = ofw_bus_get_node(device_get_parent(dev)); + if (node == -1) + return (ENXIO); + } + + sc->sc_node = node; + + vt_allocate(&vt_ofwfb_driver, &sc->fb); + + return (0); +} + +static device_method_t ofwfb_dev_methods[] = { + DEVMETHOD(device_identify, ofwfb_dev_identify), + DEVMETHOD(device_probe, ofwfb_dev_probe), + DEVMETHOD(device_attach, ofwfb_dev_attach), + DEVMETHOD_END +}; + + +static driver_t ofwfb_dev_driver = { + "fb", + ofwfb_dev_methods, + 0 /* Don't allocate a softc, one will be provided. */ +}; + +DRIVER_MODULE(fb, vgapci, ofwfb_dev_driver, 0, 0); +static void ofwfb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw, const uint8_t *pattern, const uint8_t *mask, unsigned int width, unsigned int height, @@ -489,8 +583,6 @@ ofwfb_init(struct vt_device *vd) { struct ofwfb_softc *sc; - char buf[64]; - phandle_t chosen; phandle_t node; pcell_t depth, height, width, stride; uint32_t vendor_id = 0; @@ -503,29 +595,7 @@ /* Initialize softc */ vd->vd_softc = sc = &ofwfb_conssoftc; - node = -1; - chosen = OF_finddevice("/chosen"); - if (OF_getencprop(chosen, "stdout", &sc->sc_handle, - sizeof(ihandle_t)) == sizeof(ihandle_t)) - node = OF_instance_to_package(sc->sc_handle); - if (node == -1) - /* Try "/chosen/stdout-path" now */ - if (OF_getprop(chosen, "stdout-path", buf, sizeof(buf)) > 0) { - node = OF_finddevice(buf); - if (node != -1) - sc->sc_handle = OF_open(buf); - } - if (node == -1) { - /* - * The "/chosen/stdout" does not exist try - * using "screen" directly. - */ - node = OF_finddevice("screen"); - sc->sc_handle = OF_open("screen"); - } - OF_getprop(node, "device_type", buf, sizeof(buf)); - if (strcmp(buf, "display") != 0) - return (CN_DEAD); + node = sc->sc_node; /* * Retrieve vendor-id from /chosen parent node, usually pointing to @@ -536,9 +606,6 @@ sizeof(vendor_id)) == sizeof(vendor_id)) sc->vendor_id = vendor_id; - /* Keep track of the OF node */ - sc->sc_node = node; - /* * Try to use a 32-bit framebuffer if possible. This may be * unimplemented and fail. That's fine -- it just means we are