130165b7fSToomas Soome /*
230165b7fSToomas Soome * This file and its contents are supplied under the terms of the
330165b7fSToomas Soome * Common Development and Distribution License ("CDDL"), version 1.0.
430165b7fSToomas Soome * You may only use this file in accordance with the terms of version
530165b7fSToomas Soome * 1.0 of the CDDL.
630165b7fSToomas Soome *
730165b7fSToomas Soome * A full copy of the text of the CDDL should have accompanied this
830165b7fSToomas Soome * source. A copy of the CDDL is also available via the Internet at
930165b7fSToomas Soome * http://www.illumos.org/license/CDDL.
1030165b7fSToomas Soome */
1130165b7fSToomas Soome
1230165b7fSToomas Soome /*
1330165b7fSToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com>
14*24571f7bSPaul Winder * Copyright 2020 RackTop Systems, Inc.
1530165b7fSToomas Soome */
1630165b7fSToomas Soome
1730165b7fSToomas Soome /*
1830165b7fSToomas Soome * Generic framebuffer interface. Implementing common interfaces
1930165b7fSToomas Soome * for bitmapped frame buffer and vgatext.
2030165b7fSToomas Soome */
2130165b7fSToomas Soome #include <sys/types.h>
2230165b7fSToomas Soome #include <sys/ddi.h>
2330165b7fSToomas Soome #include <sys/sunddi.h>
2482bb7c22SToomas Soome #include <sys/file.h>
2530165b7fSToomas Soome #include <sys/visual_io.h>
2630165b7fSToomas Soome #include <sys/vgareg.h>
2730165b7fSToomas Soome #include <sys/vgasubr.h>
2882bb7c22SToomas Soome #include <sys/pci.h>
2982bb7c22SToomas Soome #include <sys/boot_console.h>
3082bb7c22SToomas Soome #include <sys/kd.h>
3182bb7c22SToomas Soome #include <sys/fbio.h>
3230165b7fSToomas Soome #include <sys/gfx_private.h>
3330165b7fSToomas Soome #include "gfxp_fb.h"
3430165b7fSToomas Soome
3582bb7c22SToomas Soome #define MYNAME "gfxp_fb"
3682bb7c22SToomas Soome
3730165b7fSToomas Soome /* need to keep vgatext symbols for compatibility */
3830165b7fSToomas Soome #pragma weak gfxp_vgatext_softc_alloc = gfxp_fb_softc_alloc
3930165b7fSToomas Soome #pragma weak gfxp_vgatext_softc_free = gfxp_fb_softc_free
4030165b7fSToomas Soome #pragma weak gfxp_vgatext_attach = gfxp_fb_attach
4130165b7fSToomas Soome #pragma weak gfxp_vgatext_detach = gfxp_fb_detach
4230165b7fSToomas Soome #pragma weak gfxp_vgatext_open = gfxp_fb_open
4330165b7fSToomas Soome #pragma weak gfxp_vgatext_close = gfxp_fb_close
4430165b7fSToomas Soome #pragma weak gfxp_vgatext_ioctl = gfxp_fb_ioctl
4530165b7fSToomas Soome #pragma weak gfxp_vgatext_devmap = gfxp_fb_devmap
4630165b7fSToomas Soome
4782bb7c22SToomas Soome /*
4882bb7c22SToomas Soome * NOTE: this function is duplicated here and in consplat/vgatext while
4982bb7c22SToomas Soome * we work on a set of commitable interfaces to sunpci.c.
5082bb7c22SToomas Soome *
5182bb7c22SToomas Soome * Use the class code to determine if the device is a PCI-to-PCI bridge.
5282bb7c22SToomas Soome * Returns: B_TRUE if the device is a bridge.
5382bb7c22SToomas Soome * B_FALSE if the device is not a bridge or the property cannot be
5482bb7c22SToomas Soome * retrieved.
5582bb7c22SToomas Soome */
5682bb7c22SToomas Soome static boolean_t
is_pci_bridge(dev_info_t * dip)5782bb7c22SToomas Soome is_pci_bridge(dev_info_t *dip)
5882bb7c22SToomas Soome {
5982bb7c22SToomas Soome uint32_t class_code;
6082bb7c22SToomas Soome
6182bb7c22SToomas Soome class_code = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
6282bb7c22SToomas Soome DDI_PROP_DONTPASS, "class-code", 0xffffffff);
6382bb7c22SToomas Soome
6482bb7c22SToomas Soome if (class_code == 0xffffffff || class_code == DDI_PROP_NOT_FOUND)
6582bb7c22SToomas Soome return (B_FALSE);
6682bb7c22SToomas Soome
6782bb7c22SToomas Soome class_code &= 0x00ffff00;
6882bb7c22SToomas Soome if (class_code == ((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8)))
6982bb7c22SToomas Soome return (B_TRUE);
7082bb7c22SToomas Soome
7182bb7c22SToomas Soome return (B_FALSE);
7282bb7c22SToomas Soome }
7382bb7c22SToomas Soome
7482bb7c22SToomas Soome #define STREQ(a, b) (strcmp((a), (b)) == 0)
7582bb7c22SToomas Soome
7682bb7c22SToomas Soome static void
gfxp_check_for_console(dev_info_t * devi,struct gfxp_fb_softc * softc,int pci_pcie_bus)7782bb7c22SToomas Soome gfxp_check_for_console(dev_info_t *devi, struct gfxp_fb_softc *softc,
7882bb7c22SToomas Soome int pci_pcie_bus)
7982bb7c22SToomas Soome {
8082bb7c22SToomas Soome ddi_acc_handle_t pci_conf;
8182bb7c22SToomas Soome dev_info_t *pdevi;
8282bb7c22SToomas Soome uint16_t data16;
8382bb7c22SToomas Soome
84*24571f7bSPaul Winder /*
85*24571f7bSPaul Winder * fb_info is filled in by data gathered by the bootloader.
86*24571f7bSPaul Winder * In particular we are interested in "paddr" which is the physical
87*24571f7bSPaul Winder * address of the framebuffer. If that is not zero, then we have
88*24571f7bSPaul Winder * a valid framebuffer and we can use this device as a console.
89*24571f7bSPaul Winder */
90*24571f7bSPaul Winder if (fb_info.paddr != 0) {
91*24571f7bSPaul Winder softc->flags |= GFXP_FLAG_CONSOLE;
92*24571f7bSPaul Winder return;
93*24571f7bSPaul Winder }
94*24571f7bSPaul Winder
9582bb7c22SToomas Soome /*
9682bb7c22SToomas Soome * Based on Section 11.3, "PCI Display Subsystem Initialization",
9782bb7c22SToomas Soome * of the 1.1 PCI-to-PCI Bridge Architecture Specification
9882bb7c22SToomas Soome * determine if this is the boot console device. First, see
9982bb7c22SToomas Soome * if the SBIOS has turned on PCI I/O for this device. Then if
10082bb7c22SToomas Soome * this is PCI/PCI-E, verify the parent bridge has VGAEnable set.
10182bb7c22SToomas Soome */
10282bb7c22SToomas Soome
10382bb7c22SToomas Soome if (pci_config_setup(devi, &pci_conf) != DDI_SUCCESS) {
10482bb7c22SToomas Soome cmn_err(CE_WARN, MYNAME ": can't get PCI conf handle");
10582bb7c22SToomas Soome return;
10682bb7c22SToomas Soome }
10782bb7c22SToomas Soome
10882bb7c22SToomas Soome data16 = pci_config_get16(pci_conf, PCI_CONF_COMM);
10982bb7c22SToomas Soome if (data16 & PCI_COMM_IO)
11082bb7c22SToomas Soome softc->flags |= GFXP_FLAG_CONSOLE;
11182bb7c22SToomas Soome
11282bb7c22SToomas Soome pci_config_teardown(&pci_conf);
11382bb7c22SToomas Soome
11482bb7c22SToomas Soome /* If IO not enabled or ISA/EISA, just return */
11582bb7c22SToomas Soome if (!(softc->flags & GFXP_FLAG_CONSOLE) || !pci_pcie_bus)
11682bb7c22SToomas Soome return;
11782bb7c22SToomas Soome
11882bb7c22SToomas Soome /*
11982bb7c22SToomas Soome * Check for VGA Enable in the Bridge Control register for all
12082bb7c22SToomas Soome * PCI/PCIEX parents. If not set all the way up the chain,
12182bb7c22SToomas Soome * this cannot be the boot console.
12282bb7c22SToomas Soome */
12382bb7c22SToomas Soome
12482bb7c22SToomas Soome pdevi = devi;
12582bb7c22SToomas Soome while (pdevi = ddi_get_parent(pdevi)) {
12682bb7c22SToomas Soome int error;
12782bb7c22SToomas Soome ddi_acc_handle_t ppci_conf;
12882bb7c22SToomas Soome char *parent_type = NULL;
12982bb7c22SToomas Soome
13082bb7c22SToomas Soome error = ddi_prop_lookup_string(DDI_DEV_T_ANY, pdevi,
13182bb7c22SToomas Soome DDI_PROP_DONTPASS, "device_type", &parent_type);
13282bb7c22SToomas Soome if (error != DDI_SUCCESS) {
13382bb7c22SToomas Soome return;
13482bb7c22SToomas Soome }
13582bb7c22SToomas Soome
13682bb7c22SToomas Soome /* Verify still on the PCI/PCIEX parent tree */
13782bb7c22SToomas Soome if (!STREQ(parent_type, "pci") &&
13882bb7c22SToomas Soome !STREQ(parent_type, "pciex")) {
13982bb7c22SToomas Soome ddi_prop_free(parent_type);
14082bb7c22SToomas Soome return;
14182bb7c22SToomas Soome }
14282bb7c22SToomas Soome
14382bb7c22SToomas Soome ddi_prop_free(parent_type);
14482bb7c22SToomas Soome parent_type = NULL;
14582bb7c22SToomas Soome
14682bb7c22SToomas Soome /* VGAEnable is set only for PCI-to-PCI bridges. */
14782bb7c22SToomas Soome if (is_pci_bridge(pdevi) == B_FALSE)
14882bb7c22SToomas Soome continue;
14982bb7c22SToomas Soome
15082bb7c22SToomas Soome if (pci_config_setup(pdevi, &ppci_conf) != DDI_SUCCESS)
15182bb7c22SToomas Soome continue;
15282bb7c22SToomas Soome
15382bb7c22SToomas Soome data16 = pci_config_get16(ppci_conf, PCI_BCNF_BCNTRL);
15482bb7c22SToomas Soome pci_config_teardown(&ppci_conf);
15582bb7c22SToomas Soome
15682bb7c22SToomas Soome if (!(data16 & PCI_BCNF_BCNTRL_VGA_ENABLE)) {
15782bb7c22SToomas Soome softc->flags &= ~GFXP_FLAG_CONSOLE;
15882bb7c22SToomas Soome return;
15982bb7c22SToomas Soome }
16082bb7c22SToomas Soome }
16182bb7c22SToomas Soome }
16282bb7c22SToomas Soome
16330165b7fSToomas Soome gfxp_fb_softc_ptr_t
gfxp_fb_softc_alloc(void)16430165b7fSToomas Soome gfxp_fb_softc_alloc(void)
16530165b7fSToomas Soome {
16630165b7fSToomas Soome return (kmem_zalloc(sizeof (struct gfxp_fb_softc), KM_SLEEP));
16730165b7fSToomas Soome }
16830165b7fSToomas Soome
16930165b7fSToomas Soome void
gfxp_fb_softc_free(gfxp_fb_softc_ptr_t ptr)17030165b7fSToomas Soome gfxp_fb_softc_free(gfxp_fb_softc_ptr_t ptr)
17130165b7fSToomas Soome {
17230165b7fSToomas Soome kmem_free(ptr, sizeof (struct gfxp_fb_softc));
17330165b7fSToomas Soome }
17430165b7fSToomas Soome
17582bb7c22SToomas Soome void
gfxp_fb_resume(struct gfxp_fb_softc * softc)17682bb7c22SToomas Soome gfxp_fb_resume(struct gfxp_fb_softc *softc)
17782bb7c22SToomas Soome {
17882bb7c22SToomas Soome if (softc->gfxp_ops->resume != NULL)
17982bb7c22SToomas Soome softc->gfxp_ops->resume(softc);
18082bb7c22SToomas Soome }
18182bb7c22SToomas Soome
18282bb7c22SToomas Soome int
gfxp_fb_suspend(struct gfxp_fb_softc * softc)18382bb7c22SToomas Soome gfxp_fb_suspend(struct gfxp_fb_softc *softc)
18482bb7c22SToomas Soome {
18582bb7c22SToomas Soome if (softc->gfxp_ops->suspend != NULL)
18682bb7c22SToomas Soome return (softc->gfxp_ops->suspend(softc));
18782bb7c22SToomas Soome return (DDI_FAILURE);
18882bb7c22SToomas Soome }
18982bb7c22SToomas Soome
19030165b7fSToomas Soome int
gfxp_fb_attach(dev_info_t * devi,ddi_attach_cmd_t cmd,gfxp_fb_softc_ptr_t ptr)19130165b7fSToomas Soome gfxp_fb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd, gfxp_fb_softc_ptr_t ptr)
19230165b7fSToomas Soome {
19382bb7c22SToomas Soome struct gfxp_fb_softc *softc = (struct gfxp_fb_softc *)ptr;
19482bb7c22SToomas Soome int error;
19582bb7c22SToomas Soome char *parent_type = NULL;
19682bb7c22SToomas Soome int pci_pcie_bus = 0;
19782bb7c22SToomas Soome int value;
19882bb7c22SToomas Soome
19982bb7c22SToomas Soome if (softc == NULL)
20082bb7c22SToomas Soome return (DDI_FAILURE);
20182bb7c22SToomas Soome
20282bb7c22SToomas Soome switch (cmd) {
20382bb7c22SToomas Soome case DDI_ATTACH:
20482bb7c22SToomas Soome break;
20582bb7c22SToomas Soome
20682bb7c22SToomas Soome case DDI_RESUME:
20782bb7c22SToomas Soome gfxp_fb_resume(softc);
20882bb7c22SToomas Soome return (DDI_SUCCESS);
20982bb7c22SToomas Soome
21082bb7c22SToomas Soome default:
21182bb7c22SToomas Soome return (DDI_FAILURE);
21282bb7c22SToomas Soome }
21382bb7c22SToomas Soome
21482bb7c22SToomas Soome /* DDI_ATTACH */
21582bb7c22SToomas Soome softc->devi = devi; /* Copy and init DEVI */
21682bb7c22SToomas Soome softc->polledio.arg = (struct vis_polledio_arg *)softc;
21782bb7c22SToomas Soome softc->mode = -1; /* the actual value will be set by tem */
21882bb7c22SToomas Soome mutex_init(&(softc->lock), NULL, MUTEX_DRIVER, NULL);
21982bb7c22SToomas Soome
22082bb7c22SToomas Soome error = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(devi),
22182bb7c22SToomas Soome DDI_PROP_DONTPASS, "device_type", &parent_type);
22282bb7c22SToomas Soome if (error != DDI_SUCCESS) {
22382bb7c22SToomas Soome cmn_err(CE_WARN, MYNAME ": can't determine parent type.");
22482bb7c22SToomas Soome goto fail;
22582bb7c22SToomas Soome }
22682bb7c22SToomas Soome
22782bb7c22SToomas Soome if (STREQ(parent_type, "pci") || STREQ(parent_type, "pciex")) {
22882bb7c22SToomas Soome pci_pcie_bus = 1;
22982bb7c22SToomas Soome }
23082bb7c22SToomas Soome ddi_prop_free(parent_type);
23182bb7c22SToomas Soome gfxp_check_for_console(devi, softc, pci_pcie_bus);
23282bb7c22SToomas Soome
23382bb7c22SToomas Soome value = GFXP_IS_CONSOLE(softc) ? 1 : 0;
23482bb7c22SToomas Soome if (ddi_prop_update_int(DDI_DEV_T_NONE, devi,
23582bb7c22SToomas Soome "primary-controller", value) != DDI_SUCCESS) {
23682bb7c22SToomas Soome cmn_err(CE_WARN,
23782bb7c22SToomas Soome "Cannot %s primary-controller "
23882bb7c22SToomas Soome "property for driver", value ? "set" : "clear");
23982bb7c22SToomas Soome }
24082bb7c22SToomas Soome
24182bb7c22SToomas Soome switch (fb_info.fb_type) {
24282bb7c22SToomas Soome case FB_TYPE_UNINITIALIZED:
24382bb7c22SToomas Soome /*
24482bb7c22SToomas Soome * While booting from MB1, we do not have FB.
24582bb7c22SToomas Soome * Fall through.
24682bb7c22SToomas Soome */
24782bb7c22SToomas Soome case FB_TYPE_EGA_TEXT:
24882bb7c22SToomas Soome softc->fb_type = GFXP_VGATEXT;
24982bb7c22SToomas Soome error = gfxp_vga_attach(devi, softc);
25082bb7c22SToomas Soome break;
25182bb7c22SToomas Soome
25282bb7c22SToomas Soome case FB_TYPE_INDEXED: /* FB types */
25382bb7c22SToomas Soome case FB_TYPE_RGB:
25482bb7c22SToomas Soome softc->fb_type = GFXP_BITMAP;
25582bb7c22SToomas Soome error = gfxp_bm_attach(devi, softc);
25682bb7c22SToomas Soome break;
25782bb7c22SToomas Soome
25882bb7c22SToomas Soome default:
25982bb7c22SToomas Soome error = DDI_FAILURE;
26082bb7c22SToomas Soome }
26182bb7c22SToomas Soome
26282bb7c22SToomas Soome if (error == DDI_SUCCESS)
26382bb7c22SToomas Soome return (error);
26482bb7c22SToomas Soome
26582bb7c22SToomas Soome (void) ddi_prop_remove(DDI_DEV_T_ANY, devi, "primary-controller");
26682bb7c22SToomas Soome fail:
26782bb7c22SToomas Soome (void) gfxp_fb_detach(devi, DDI_DETACH, (void *)softc);
26882bb7c22SToomas Soome return (error);
26930165b7fSToomas Soome }
27030165b7fSToomas Soome
27130165b7fSToomas Soome int
gfxp_fb_detach(dev_info_t * devi,ddi_detach_cmd_t cmd,gfxp_fb_softc_ptr_t ptr)27230165b7fSToomas Soome gfxp_fb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd, gfxp_fb_softc_ptr_t ptr)
27330165b7fSToomas Soome {
27482bb7c22SToomas Soome struct gfxp_fb_softc *softc = (struct gfxp_fb_softc *)ptr;
27582bb7c22SToomas Soome int error;
27682bb7c22SToomas Soome
27782bb7c22SToomas Soome if (softc == NULL)
27882bb7c22SToomas Soome return (DDI_FAILURE);
27982bb7c22SToomas Soome
28082bb7c22SToomas Soome switch (cmd) {
28182bb7c22SToomas Soome case DDI_SUSPEND:
28282bb7c22SToomas Soome return (gfxp_fb_suspend(softc));
28382bb7c22SToomas Soome
28482bb7c22SToomas Soome case DDI_DETACH:
28582bb7c22SToomas Soome (void) ddi_prop_remove(DDI_DEV_T_ANY, devi,
28682bb7c22SToomas Soome "primary-controller");
287584b574aSToomas Soome error = DDI_SUCCESS;
28882bb7c22SToomas Soome switch (softc->fb_type) {
28982bb7c22SToomas Soome case GFXP_BITMAP:
29082bb7c22SToomas Soome error = gfxp_bm_detach(devi, softc);
29182bb7c22SToomas Soome break;
29282bb7c22SToomas Soome case GFXP_VGATEXT:
29382bb7c22SToomas Soome error = gfxp_vga_detach(devi, softc);
29482bb7c22SToomas Soome break;
29582bb7c22SToomas Soome }
29682bb7c22SToomas Soome mutex_destroy(&(softc->lock));
29782bb7c22SToomas Soome return (error);
29882bb7c22SToomas Soome
29982bb7c22SToomas Soome default:
30082bb7c22SToomas Soome cmn_err(CE_WARN, "gfxp_fb_detach: unknown cmd 0x%x\n",
30182bb7c22SToomas Soome cmd);
30282bb7c22SToomas Soome return (DDI_FAILURE);
30382bb7c22SToomas Soome }
30430165b7fSToomas Soome }
30530165b7fSToomas Soome
30630165b7fSToomas Soome /*ARGSUSED*/
30730165b7fSToomas Soome int
gfxp_fb_open(dev_t * devp,int flag,int otyp,cred_t * cred,gfxp_fb_softc_ptr_t ptr)30830165b7fSToomas Soome gfxp_fb_open(dev_t *devp, int flag, int otyp, cred_t *cred,
30930165b7fSToomas Soome gfxp_fb_softc_ptr_t ptr)
31030165b7fSToomas Soome {
31130165b7fSToomas Soome struct gfxp_fb_softc *softc = (struct gfxp_fb_softc *)ptr;
31230165b7fSToomas Soome
31330165b7fSToomas Soome if (softc == NULL || otyp == OTYP_BLK)
31430165b7fSToomas Soome return (ENXIO);
31530165b7fSToomas Soome
31630165b7fSToomas Soome return (0);
31730165b7fSToomas Soome }
31830165b7fSToomas Soome
31930165b7fSToomas Soome /*ARGSUSED*/
32030165b7fSToomas Soome int
gfxp_fb_close(dev_t devp,int flag,int otyp,cred_t * cred,gfxp_fb_softc_ptr_t ptr)32130165b7fSToomas Soome gfxp_fb_close(dev_t devp, int flag, int otyp, cred_t *cred,
32230165b7fSToomas Soome gfxp_fb_softc_ptr_t ptr)
32330165b7fSToomas Soome {
32430165b7fSToomas Soome return (0);
32530165b7fSToomas Soome }
32630165b7fSToomas Soome
32782bb7c22SToomas Soome static int
do_gfx_ioctl(int cmd,intptr_t data,int mode,struct gfxp_fb_softc * softc)32882bb7c22SToomas Soome do_gfx_ioctl(int cmd, intptr_t data, int mode, struct gfxp_fb_softc *softc)
32982bb7c22SToomas Soome {
33082bb7c22SToomas Soome static char kernel_only[] =
33182bb7c22SToomas Soome "gfxp_fb_ioctl: %s is a kernel only ioctl";
33282bb7c22SToomas Soome int err;
33382bb7c22SToomas Soome int kd_mode;
33482bb7c22SToomas Soome
33582bb7c22SToomas Soome switch (cmd) {
33682bb7c22SToomas Soome case KDSETMODE:
33782bb7c22SToomas Soome kd_mode = (int)data;
33882bb7c22SToomas Soome if ((kd_mode == softc->mode) || (!GFXP_IS_CONSOLE(softc)))
33982bb7c22SToomas Soome break;
34082bb7c22SToomas Soome return (softc->gfxp_ops->kdsetmode(softc, kd_mode));
34182bb7c22SToomas Soome
34282bb7c22SToomas Soome case KDGETMODE:
34382bb7c22SToomas Soome kd_mode = softc->mode;
34482bb7c22SToomas Soome if (ddi_copyout(&kd_mode, (void *)data, sizeof (int), mode))
34582bb7c22SToomas Soome return (EFAULT);
34682bb7c22SToomas Soome break;
34782bb7c22SToomas Soome
34882bb7c22SToomas Soome case VIS_GETIDENTIFIER:
34982bb7c22SToomas Soome if (ddi_copyout(softc->gfxp_ops->ident, (void *)data,
35082bb7c22SToomas Soome sizeof (struct vis_identifier), mode))
35182bb7c22SToomas Soome return (EFAULT);
35282bb7c22SToomas Soome break;
35382bb7c22SToomas Soome
35482bb7c22SToomas Soome case VIS_DEVINIT:
35582bb7c22SToomas Soome
35682bb7c22SToomas Soome if (!(mode & FKIOCTL)) {
35782bb7c22SToomas Soome cmn_err(CE_CONT, kernel_only, "VIS_DEVINIT");
35882bb7c22SToomas Soome return (ENXIO);
35982bb7c22SToomas Soome }
36082bb7c22SToomas Soome
36182bb7c22SToomas Soome err = softc->gfxp_ops->devinit(softc,
36282bb7c22SToomas Soome (struct vis_devinit *)data);
36382bb7c22SToomas Soome if (err != 0) {
36482bb7c22SToomas Soome cmn_err(CE_WARN,
36582bb7c22SToomas Soome "gfxp_fb_ioctl: could not initialize console");
36682bb7c22SToomas Soome return (err);
36782bb7c22SToomas Soome }
36882bb7c22SToomas Soome break;
36982bb7c22SToomas Soome
37082bb7c22SToomas Soome case VIS_CONSCLEAR: /* clear screen */
37182bb7c22SToomas Soome {
37282bb7c22SToomas Soome struct vis_consclear pma;
37382bb7c22SToomas Soome
37482bb7c22SToomas Soome if (ddi_copyin((void *)data, &pma,
37582bb7c22SToomas Soome sizeof (struct vis_consclear), mode))
37682bb7c22SToomas Soome return (EFAULT);
37782bb7c22SToomas Soome
37882bb7c22SToomas Soome return (softc->gfxp_ops->cons_clear(softc, &pma));
37982bb7c22SToomas Soome }
38082bb7c22SToomas Soome
38182bb7c22SToomas Soome case VIS_CONSCOPY: /* move */
38282bb7c22SToomas Soome {
38382bb7c22SToomas Soome struct vis_conscopy pma;
38482bb7c22SToomas Soome
38582bb7c22SToomas Soome if (ddi_copyin((void *)data, &pma,
38682bb7c22SToomas Soome sizeof (struct vis_conscopy), mode))
38782bb7c22SToomas Soome return (EFAULT);
38882bb7c22SToomas Soome
38982bb7c22SToomas Soome softc->gfxp_ops->cons_copy(softc, &pma);
39082bb7c22SToomas Soome break;
39182bb7c22SToomas Soome }
39282bb7c22SToomas Soome
39382bb7c22SToomas Soome case VIS_CONSDISPLAY: /* display */
39482bb7c22SToomas Soome {
39582bb7c22SToomas Soome struct vis_consdisplay display_request;
39682bb7c22SToomas Soome
39782bb7c22SToomas Soome if (ddi_copyin((void *)data, &display_request,
39882bb7c22SToomas Soome sizeof (display_request), mode))
39982bb7c22SToomas Soome return (EFAULT);
40082bb7c22SToomas Soome
40182bb7c22SToomas Soome softc->gfxp_ops->cons_display(softc, &display_request);
40282bb7c22SToomas Soome break;
40382bb7c22SToomas Soome }
40482bb7c22SToomas Soome
40582bb7c22SToomas Soome case VIS_CONSCURSOR:
40682bb7c22SToomas Soome {
40782bb7c22SToomas Soome struct vis_conscursor cursor_request;
40882bb7c22SToomas Soome
40982bb7c22SToomas Soome if (ddi_copyin((void *)data, &cursor_request,
41082bb7c22SToomas Soome sizeof (cursor_request), mode))
41182bb7c22SToomas Soome return (EFAULT);
41282bb7c22SToomas Soome
41382bb7c22SToomas Soome softc->gfxp_ops->cons_cursor(softc, &cursor_request);
41482bb7c22SToomas Soome
41582bb7c22SToomas Soome if (cursor_request.action == VIS_GET_CURSOR &&
41682bb7c22SToomas Soome ddi_copyout(&cursor_request, (void *)data,
41782bb7c22SToomas Soome sizeof (cursor_request), mode))
41882bb7c22SToomas Soome return (EFAULT);
41982bb7c22SToomas Soome break;
42082bb7c22SToomas Soome }
42182bb7c22SToomas Soome
42282bb7c22SToomas Soome case VIS_GETCMAP:
42382bb7c22SToomas Soome case VIS_PUTCMAP:
42482bb7c22SToomas Soome case FBIOPUTCMAP:
42582bb7c22SToomas Soome case FBIOGETCMAP:
42682bb7c22SToomas Soome /*
42782bb7c22SToomas Soome * At the moment, text mode is not considered to have
42882bb7c22SToomas Soome * a color map.
42982bb7c22SToomas Soome */
43082bb7c22SToomas Soome return (EINVAL);
43182bb7c22SToomas Soome
43282bb7c22SToomas Soome case FBIOGATTR:
43382bb7c22SToomas Soome if (copyout(softc->fbgattr, (void *)data,
43482bb7c22SToomas Soome sizeof (struct fbgattr)))
43582bb7c22SToomas Soome return (EFAULT);
43682bb7c22SToomas Soome break;
43782bb7c22SToomas Soome
43882bb7c22SToomas Soome case FBIOGTYPE:
43982bb7c22SToomas Soome if (copyout(&softc->fbgattr->fbtype, (void *)data,
44082bb7c22SToomas Soome sizeof (struct fbtype)))
44182bb7c22SToomas Soome return (EFAULT);
44282bb7c22SToomas Soome break;
44382bb7c22SToomas Soome
44482bb7c22SToomas Soome default:
44582bb7c22SToomas Soome cmn_err(CE_CONT, "!unimplemented cmd: 0x%x\n", cmd);
44682bb7c22SToomas Soome return (ENXIO);
44782bb7c22SToomas Soome }
44882bb7c22SToomas Soome return (0);
44982bb7c22SToomas Soome }
45082bb7c22SToomas Soome
45182bb7c22SToomas Soome /*ARGSUSED*/
45230165b7fSToomas Soome int
gfxp_fb_ioctl(dev_t dev,int cmd,intptr_t data,int mode,cred_t * cred,int * rval,gfxp_fb_softc_ptr_t ptr)45330165b7fSToomas Soome gfxp_fb_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
45430165b7fSToomas Soome cred_t *cred, int *rval, gfxp_fb_softc_ptr_t ptr)
45530165b7fSToomas Soome {
45682bb7c22SToomas Soome struct gfxp_fb_softc *softc = (struct gfxp_fb_softc *)ptr;
45782bb7c22SToomas Soome int error = DDI_FAILURE;
45882bb7c22SToomas Soome
45982bb7c22SToomas Soome if (softc == NULL)
46082bb7c22SToomas Soome return (error);
46182bb7c22SToomas Soome mutex_enter(&(softc->lock));
46282bb7c22SToomas Soome error = do_gfx_ioctl(cmd, data, mode, softc);
46382bb7c22SToomas Soome mutex_exit(&(softc->lock));
46482bb7c22SToomas Soome return (error);
46530165b7fSToomas Soome }
46630165b7fSToomas Soome
46730165b7fSToomas Soome int
gfxp_fb_devmap(dev_t dev,devmap_cookie_t dhp,offset_t off,size_t len,size_t * maplen,uint_t model,void * ptr)46830165b7fSToomas Soome gfxp_fb_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off,
46930165b7fSToomas Soome size_t len, size_t *maplen, uint_t model, void *ptr)
47030165b7fSToomas Soome {
47182bb7c22SToomas Soome struct gfxp_fb_softc *softc = (struct gfxp_fb_softc *)ptr;
47282bb7c22SToomas Soome
47382bb7c22SToomas Soome if (softc == NULL)
47482bb7c22SToomas Soome return (DDI_FAILURE);
47582bb7c22SToomas Soome
47682bb7c22SToomas Soome return (softc->gfxp_ops->devmap(dev, dhp, off, len, maplen,
47782bb7c22SToomas Soome model, ptr));
47830165b7fSToomas Soome }
479