18e8e46ccSJohn Baldwin /*- 28e8e46ccSJohn Baldwin * Copyright (c) 2005 John Baldwin <jhb@FreeBSD.org> 38e8e46ccSJohn Baldwin * All rights reserved. 48e8e46ccSJohn Baldwin * 58e8e46ccSJohn Baldwin * Redistribution and use in source and binary forms, with or without 68e8e46ccSJohn Baldwin * modification, are permitted provided that the following conditions 78e8e46ccSJohn Baldwin * are met: 88e8e46ccSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 98e8e46ccSJohn Baldwin * notice, this list of conditions and the following disclaimer. 108e8e46ccSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 118e8e46ccSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 128e8e46ccSJohn Baldwin * documentation and/or other materials provided with the distribution. 138e8e46ccSJohn Baldwin * 3. Neither the name of the author nor the names of any co-contributors 148e8e46ccSJohn Baldwin * may be used to endorse or promote products derived from this software 158e8e46ccSJohn Baldwin * without specific prior written permission. 168e8e46ccSJohn Baldwin * 178e8e46ccSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 188e8e46ccSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 198e8e46ccSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 208e8e46ccSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 218e8e46ccSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 228e8e46ccSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 238e8e46ccSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 248e8e46ccSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258e8e46ccSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 268e8e46ccSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 278e8e46ccSJohn Baldwin * SUCH DAMAGE. 288e8e46ccSJohn Baldwin */ 298e8e46ccSJohn Baldwin 308e8e46ccSJohn Baldwin #include <sys/cdefs.h> 318e8e46ccSJohn Baldwin __FBSDID("$FreeBSD$"); 328e8e46ccSJohn Baldwin 338e8e46ccSJohn Baldwin /* 348e8e46ccSJohn Baldwin * Simple driver for PCI VGA display devices. Drivers such as agp(4) and 358e8e46ccSJohn Baldwin * drm(4) should attach as children of this device. 368e8e46ccSJohn Baldwin * 378e8e46ccSJohn Baldwin * XXX: The vgapci name is a hack until we somehow merge the isa vga driver 388e8e46ccSJohn Baldwin * in or rename it. 398e8e46ccSJohn Baldwin */ 408e8e46ccSJohn Baldwin 418e8e46ccSJohn Baldwin #include <sys/param.h> 428e8e46ccSJohn Baldwin #include <sys/bus.h> 438e8e46ccSJohn Baldwin #include <sys/kernel.h> 448e8e46ccSJohn Baldwin #include <sys/module.h> 458e8e46ccSJohn Baldwin 468e8e46ccSJohn Baldwin #include <dev/pci/pcireg.h> 478e8e46ccSJohn Baldwin #include <dev/pci/pcivar.h> 488e8e46ccSJohn Baldwin 49e7e2941bSJohn Baldwin struct vga_pci_softc { 50e7e2941bSJohn Baldwin device_t vga_msi_child; /* Child driver using MSI. */ 51e7e2941bSJohn Baldwin }; 52e7e2941bSJohn Baldwin 538e8e46ccSJohn Baldwin static int 548e8e46ccSJohn Baldwin vga_pci_probe(device_t dev) 558e8e46ccSJohn Baldwin { 568e8e46ccSJohn Baldwin 578e8e46ccSJohn Baldwin switch (pci_get_class(dev)) { 588e8e46ccSJohn Baldwin case PCIC_DISPLAY: 598e8e46ccSJohn Baldwin break; 608e8e46ccSJohn Baldwin case PCIC_OLD: 618e8e46ccSJohn Baldwin if (pci_get_subclass(dev) != PCIS_OLD_VGA) 628e8e46ccSJohn Baldwin return (ENXIO); 638e8e46ccSJohn Baldwin break; 648e8e46ccSJohn Baldwin default: 658e8e46ccSJohn Baldwin return (ENXIO); 668e8e46ccSJohn Baldwin } 678e8e46ccSJohn Baldwin device_set_desc(dev, "VGA-compatible display"); 68be7ccc4bSJohn Baldwin return (BUS_PROBE_GENERIC); 698e8e46ccSJohn Baldwin } 708e8e46ccSJohn Baldwin 718e8e46ccSJohn Baldwin static int 728e8e46ccSJohn Baldwin vga_pci_attach(device_t dev) 738e8e46ccSJohn Baldwin { 748e8e46ccSJohn Baldwin 758e8e46ccSJohn Baldwin bus_generic_probe(dev); 768e8e46ccSJohn Baldwin 778e8e46ccSJohn Baldwin /* Always create a drm child for now to make it easier on drm. */ 788e8e46ccSJohn Baldwin device_add_child(dev, "drm", -1); 798e8e46ccSJohn Baldwin bus_generic_attach(dev); 808e8e46ccSJohn Baldwin return (0); 818e8e46ccSJohn Baldwin } 828e8e46ccSJohn Baldwin 838e8e46ccSJohn Baldwin static int 848e8e46ccSJohn Baldwin vga_pci_suspend(device_t dev) 858e8e46ccSJohn Baldwin { 868e8e46ccSJohn Baldwin 878e8e46ccSJohn Baldwin return (bus_generic_suspend(dev)); 888e8e46ccSJohn Baldwin } 898e8e46ccSJohn Baldwin 908e8e46ccSJohn Baldwin static int 918e8e46ccSJohn Baldwin vga_pci_resume(device_t dev) 928e8e46ccSJohn Baldwin { 938e8e46ccSJohn Baldwin 948e8e46ccSJohn Baldwin return (bus_generic_resume(dev)); 958e8e46ccSJohn Baldwin } 968e8e46ccSJohn Baldwin 978e8e46ccSJohn Baldwin /* Bus interface. */ 988e8e46ccSJohn Baldwin 998e8e46ccSJohn Baldwin static int 1008e8e46ccSJohn Baldwin vga_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 1018e8e46ccSJohn Baldwin { 1028e8e46ccSJohn Baldwin 1038e8e46ccSJohn Baldwin return (BUS_READ_IVAR(device_get_parent(dev), dev, which, result)); 1048e8e46ccSJohn Baldwin } 1058e8e46ccSJohn Baldwin 1068e8e46ccSJohn Baldwin static int 1078e8e46ccSJohn Baldwin vga_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 1088e8e46ccSJohn Baldwin { 1098e8e46ccSJohn Baldwin 1108e8e46ccSJohn Baldwin return (EINVAL); 1118e8e46ccSJohn Baldwin } 1128e8e46ccSJohn Baldwin 1138e8e46ccSJohn Baldwin static struct resource * 1148e8e46ccSJohn Baldwin vga_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, 1158e8e46ccSJohn Baldwin u_long start, u_long end, u_long count, u_int flags) 1168e8e46ccSJohn Baldwin { 1178e8e46ccSJohn Baldwin 1188e8e46ccSJohn Baldwin return (bus_alloc_resource(dev, type, rid, start, end, count, flags)); 1198e8e46ccSJohn Baldwin } 1208e8e46ccSJohn Baldwin 1218e8e46ccSJohn Baldwin static int 1228e8e46ccSJohn Baldwin vga_pci_release_resource(device_t dev, device_t child, int type, int rid, 1238e8e46ccSJohn Baldwin struct resource *r) 1248e8e46ccSJohn Baldwin { 1258e8e46ccSJohn Baldwin 1268e8e46ccSJohn Baldwin return (bus_release_resource(dev, type, rid, r)); 1278e8e46ccSJohn Baldwin } 1288e8e46ccSJohn Baldwin 1298e8e46ccSJohn Baldwin /* PCI interface. */ 1308e8e46ccSJohn Baldwin 1318e8e46ccSJohn Baldwin static uint32_t 1328e8e46ccSJohn Baldwin vga_pci_read_config(device_t dev, device_t child, int reg, int width) 1338e8e46ccSJohn Baldwin { 1348e8e46ccSJohn Baldwin 1358e8e46ccSJohn Baldwin return (pci_read_config(dev, reg, width)); 1368e8e46ccSJohn Baldwin } 1378e8e46ccSJohn Baldwin 1388e8e46ccSJohn Baldwin static void 1398e8e46ccSJohn Baldwin vga_pci_write_config(device_t dev, device_t child, int reg, 1408e8e46ccSJohn Baldwin uint32_t val, int width) 1418e8e46ccSJohn Baldwin { 1428e8e46ccSJohn Baldwin 1438e8e46ccSJohn Baldwin pci_write_config(dev, reg, val, width); 1448e8e46ccSJohn Baldwin } 1458e8e46ccSJohn Baldwin 1468e8e46ccSJohn Baldwin static int 1478e8e46ccSJohn Baldwin vga_pci_enable_busmaster(device_t dev, device_t child) 1488e8e46ccSJohn Baldwin { 1498e8e46ccSJohn Baldwin 1508e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_enable_busmaster\n", 1518e8e46ccSJohn Baldwin device_get_nameunit(child)); 1528e8e46ccSJohn Baldwin return (pci_enable_busmaster(dev)); 1538e8e46ccSJohn Baldwin } 1548e8e46ccSJohn Baldwin 1558e8e46ccSJohn Baldwin static int 1568e8e46ccSJohn Baldwin vga_pci_disable_busmaster(device_t dev, device_t child) 1578e8e46ccSJohn Baldwin { 1588e8e46ccSJohn Baldwin 1598e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_disable_busmaster\n", 1608e8e46ccSJohn Baldwin device_get_nameunit(child)); 1618e8e46ccSJohn Baldwin return (pci_disable_busmaster(dev)); 1628e8e46ccSJohn Baldwin } 1638e8e46ccSJohn Baldwin 1648e8e46ccSJohn Baldwin static int 1658e8e46ccSJohn Baldwin vga_pci_enable_io(device_t dev, device_t child, int space) 1668e8e46ccSJohn Baldwin { 1678e8e46ccSJohn Baldwin 1688e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_enable_io\n", 1698e8e46ccSJohn Baldwin device_get_nameunit(child)); 1708e8e46ccSJohn Baldwin return (pci_enable_io(dev, space)); 1718e8e46ccSJohn Baldwin } 1728e8e46ccSJohn Baldwin 1738e8e46ccSJohn Baldwin static int 1748e8e46ccSJohn Baldwin vga_pci_disable_io(device_t dev, device_t child, int space) 1758e8e46ccSJohn Baldwin { 1768e8e46ccSJohn Baldwin 1778e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_disable_io\n", 1788e8e46ccSJohn Baldwin device_get_nameunit(child)); 1798e8e46ccSJohn Baldwin return (pci_disable_io(dev, space)); 1808e8e46ccSJohn Baldwin } 1818e8e46ccSJohn Baldwin 1828e8e46ccSJohn Baldwin static int 183e7e2941bSJohn Baldwin vga_pci_get_vpd_ident(device_t dev, device_t child, const char **identptr) 184e7e2941bSJohn Baldwin { 185e7e2941bSJohn Baldwin 186e7e2941bSJohn Baldwin return (pci_get_vpd_ident(dev, identptr)); 187e7e2941bSJohn Baldwin } 188e7e2941bSJohn Baldwin 189e7e2941bSJohn Baldwin static int 190e7e2941bSJohn Baldwin vga_pci_get_vpd_readonly(device_t dev, device_t child, const char *kw, 191e7e2941bSJohn Baldwin const char **vptr) 192e7e2941bSJohn Baldwin { 193e7e2941bSJohn Baldwin 194e7e2941bSJohn Baldwin return (pci_get_vpd_readonly(dev, kw, vptr)); 195e7e2941bSJohn Baldwin } 196e7e2941bSJohn Baldwin 197e7e2941bSJohn Baldwin static int 1988e8e46ccSJohn Baldwin vga_pci_set_powerstate(device_t dev, device_t child, int state) 1998e8e46ccSJohn Baldwin { 2008e8e46ccSJohn Baldwin 2018e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_set_powerstate\n", 2028e8e46ccSJohn Baldwin device_get_nameunit(child)); 2038e8e46ccSJohn Baldwin return (pci_set_powerstate(dev, state)); 2048e8e46ccSJohn Baldwin } 2058e8e46ccSJohn Baldwin 2068e8e46ccSJohn Baldwin static int 2078e8e46ccSJohn Baldwin vga_pci_get_powerstate(device_t dev, device_t child) 2088e8e46ccSJohn Baldwin { 2098e8e46ccSJohn Baldwin 2108e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_get_powerstate\n", 2118e8e46ccSJohn Baldwin device_get_nameunit(child)); 2128e8e46ccSJohn Baldwin return (pci_get_powerstate(dev)); 2138e8e46ccSJohn Baldwin } 2148e8e46ccSJohn Baldwin 2158e8e46ccSJohn Baldwin static int 2168e8e46ccSJohn Baldwin vga_pci_assign_interrupt(device_t dev, device_t child) 2178e8e46ccSJohn Baldwin { 2188e8e46ccSJohn Baldwin 2198e8e46ccSJohn Baldwin device_printf(dev, "child %s requested pci_assign_interrupt\n", 2208e8e46ccSJohn Baldwin device_get_nameunit(child)); 2218e8e46ccSJohn Baldwin return (PCI_ASSIGN_INTERRUPT(device_get_parent(dev), dev)); 2228e8e46ccSJohn Baldwin } 2238e8e46ccSJohn Baldwin 2248e8e46ccSJohn Baldwin static int 2258e8e46ccSJohn Baldwin vga_pci_find_extcap(device_t dev, device_t child, int capability, 2268e8e46ccSJohn Baldwin int *capreg) 2278e8e46ccSJohn Baldwin { 2288e8e46ccSJohn Baldwin 2298e8e46ccSJohn Baldwin return (pci_find_extcap(dev, capability, capreg)); 2308e8e46ccSJohn Baldwin } 2318e8e46ccSJohn Baldwin 232e7e2941bSJohn Baldwin static int 233e7e2941bSJohn Baldwin vga_pci_alloc_msi(device_t dev, device_t child, int *count) 234e7e2941bSJohn Baldwin { 235e7e2941bSJohn Baldwin struct vga_pci_softc *sc; 236e7e2941bSJohn Baldwin int error; 237e7e2941bSJohn Baldwin 238e7e2941bSJohn Baldwin sc = device_get_softc(dev); 239e7e2941bSJohn Baldwin if (sc->vga_msi_child != NULL) 240e7e2941bSJohn Baldwin return (EBUSY); 241e7e2941bSJohn Baldwin error = pci_alloc_msi(dev, count); 242e7e2941bSJohn Baldwin if (error == 0) 243e7e2941bSJohn Baldwin sc->vga_msi_child = child; 244e7e2941bSJohn Baldwin return (error); 245e7e2941bSJohn Baldwin } 246e7e2941bSJohn Baldwin 247e7e2941bSJohn Baldwin static int 248e7e2941bSJohn Baldwin vga_pci_alloc_msix(device_t dev, device_t child, int *count) 249e7e2941bSJohn Baldwin { 250e7e2941bSJohn Baldwin struct vga_pci_softc *sc; 251e7e2941bSJohn Baldwin int error; 252e7e2941bSJohn Baldwin 253e7e2941bSJohn Baldwin sc = device_get_softc(dev); 254e7e2941bSJohn Baldwin if (sc->vga_msi_child != NULL) 255e7e2941bSJohn Baldwin return (EBUSY); 256e7e2941bSJohn Baldwin error = pci_alloc_msix(dev, count); 257e7e2941bSJohn Baldwin if (error == 0) 258e7e2941bSJohn Baldwin sc->vga_msi_child = child; 259e7e2941bSJohn Baldwin return (error); 260e7e2941bSJohn Baldwin } 261e7e2941bSJohn Baldwin 262e7e2941bSJohn Baldwin static int 263e7e2941bSJohn Baldwin vga_pci_remap_msix(device_t dev, device_t child, int count, 264e7e2941bSJohn Baldwin const u_int *vectors) 265e7e2941bSJohn Baldwin { 266e7e2941bSJohn Baldwin struct vga_pci_softc *sc; 267e7e2941bSJohn Baldwin 268e7e2941bSJohn Baldwin sc = device_get_softc(dev); 269e7e2941bSJohn Baldwin if (sc->vga_msi_child != child) 270e7e2941bSJohn Baldwin return (ENXIO); 271e7e2941bSJohn Baldwin return (pci_remap_msix(dev, count, vectors)); 272e7e2941bSJohn Baldwin } 273e7e2941bSJohn Baldwin 274e7e2941bSJohn Baldwin static int 275e7e2941bSJohn Baldwin vga_pci_release_msi(device_t dev, device_t child) 276e7e2941bSJohn Baldwin { 277e7e2941bSJohn Baldwin struct vga_pci_softc *sc; 278e7e2941bSJohn Baldwin int error; 279e7e2941bSJohn Baldwin 280e7e2941bSJohn Baldwin sc = device_get_softc(dev); 281e7e2941bSJohn Baldwin if (sc->vga_msi_child != child) 282e7e2941bSJohn Baldwin return (ENXIO); 283e7e2941bSJohn Baldwin error = pci_release_msi(dev); 284e7e2941bSJohn Baldwin if (error == 0) 285e7e2941bSJohn Baldwin sc->vga_msi_child = NULL; 286e7e2941bSJohn Baldwin return (error); 287e7e2941bSJohn Baldwin } 288e7e2941bSJohn Baldwin 289e7e2941bSJohn Baldwin static int 290e7e2941bSJohn Baldwin vga_pci_msi_count(device_t dev, device_t child) 291e7e2941bSJohn Baldwin { 292e7e2941bSJohn Baldwin 293e7e2941bSJohn Baldwin return (pci_msi_count(dev)); 294e7e2941bSJohn Baldwin } 295e7e2941bSJohn Baldwin 296e7e2941bSJohn Baldwin static int 297e7e2941bSJohn Baldwin vga_pci_msix_count(device_t dev, device_t child) 298e7e2941bSJohn Baldwin { 299e7e2941bSJohn Baldwin 300e7e2941bSJohn Baldwin return (pci_msix_count(dev)); 301e7e2941bSJohn Baldwin } 302e7e2941bSJohn Baldwin 3038e8e46ccSJohn Baldwin static device_method_t vga_pci_methods[] = { 3048e8e46ccSJohn Baldwin /* Device interface */ 3058e8e46ccSJohn Baldwin DEVMETHOD(device_probe, vga_pci_probe), 3068e8e46ccSJohn Baldwin DEVMETHOD(device_attach, vga_pci_attach), 3078e8e46ccSJohn Baldwin DEVMETHOD(device_shutdown, bus_generic_shutdown), 3088e8e46ccSJohn Baldwin DEVMETHOD(device_suspend, vga_pci_suspend), 3098e8e46ccSJohn Baldwin DEVMETHOD(device_resume, vga_pci_resume), 3108e8e46ccSJohn Baldwin 3118e8e46ccSJohn Baldwin /* Bus interface */ 3128e8e46ccSJohn Baldwin DEVMETHOD(bus_read_ivar, vga_pci_read_ivar), 3138e8e46ccSJohn Baldwin DEVMETHOD(bus_write_ivar, vga_pci_write_ivar), 3148e8e46ccSJohn Baldwin DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 3158e8e46ccSJohn Baldwin DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 3168e8e46ccSJohn Baldwin 3178e8e46ccSJohn Baldwin DEVMETHOD(bus_alloc_resource, vga_pci_alloc_resource), 3188e8e46ccSJohn Baldwin DEVMETHOD(bus_release_resource, vga_pci_release_resource), 3198e8e46ccSJohn Baldwin DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 3208e8e46ccSJohn Baldwin DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 3218e8e46ccSJohn Baldwin 3228e8e46ccSJohn Baldwin /* PCI interface */ 3238e8e46ccSJohn Baldwin DEVMETHOD(pci_read_config, vga_pci_read_config), 3248e8e46ccSJohn Baldwin DEVMETHOD(pci_write_config, vga_pci_write_config), 3258e8e46ccSJohn Baldwin DEVMETHOD(pci_enable_busmaster, vga_pci_enable_busmaster), 3268e8e46ccSJohn Baldwin DEVMETHOD(pci_disable_busmaster, vga_pci_disable_busmaster), 3278e8e46ccSJohn Baldwin DEVMETHOD(pci_enable_io, vga_pci_enable_io), 3288e8e46ccSJohn Baldwin DEVMETHOD(pci_disable_io, vga_pci_disable_io), 329e7e2941bSJohn Baldwin DEVMETHOD(pci_get_vpd_ident, vga_pci_get_vpd_ident), 330e7e2941bSJohn Baldwin DEVMETHOD(pci_get_vpd_readonly, vga_pci_get_vpd_readonly), 3318e8e46ccSJohn Baldwin DEVMETHOD(pci_get_powerstate, vga_pci_get_powerstate), 3328e8e46ccSJohn Baldwin DEVMETHOD(pci_set_powerstate, vga_pci_set_powerstate), 3338e8e46ccSJohn Baldwin DEVMETHOD(pci_assign_interrupt, vga_pci_assign_interrupt), 3348e8e46ccSJohn Baldwin DEVMETHOD(pci_find_extcap, vga_pci_find_extcap), 335e7e2941bSJohn Baldwin DEVMETHOD(pci_alloc_msi, vga_pci_alloc_msi), 336e7e2941bSJohn Baldwin DEVMETHOD(pci_alloc_msix, vga_pci_alloc_msix), 337e7e2941bSJohn Baldwin DEVMETHOD(pci_remap_msix, vga_pci_remap_msix), 338e7e2941bSJohn Baldwin DEVMETHOD(pci_release_msi, vga_pci_release_msi), 339e7e2941bSJohn Baldwin DEVMETHOD(pci_msi_count, vga_pci_msi_count), 340e7e2941bSJohn Baldwin DEVMETHOD(pci_msix_count, vga_pci_msix_count), 3418e8e46ccSJohn Baldwin 3428e8e46ccSJohn Baldwin { 0, 0 } 3438e8e46ccSJohn Baldwin }; 3448e8e46ccSJohn Baldwin 3458e8e46ccSJohn Baldwin static driver_t vga_pci_driver = { 3468e8e46ccSJohn Baldwin "vgapci", 3478e8e46ccSJohn Baldwin vga_pci_methods, 348e7e2941bSJohn Baldwin sizeof(struct vga_pci_softc), 3498e8e46ccSJohn Baldwin }; 3508e8e46ccSJohn Baldwin 3518e8e46ccSJohn Baldwin static devclass_t vga_devclass; 3528e8e46ccSJohn Baldwin 3538e8e46ccSJohn Baldwin DRIVER_MODULE(vgapci, pci, vga_pci_driver, vga_devclass, 0, 0); 354