Index: head/sys/dev/agp/agp_i810.c =================================================================== --- head/sys/dev/agp/agp_i810.c (revision 153578) +++ head/sys/dev/agp/agp_i810.c (revision 153579) @@ -1,863 +1,831 @@ /*- * Copyright (c) 2000 Doug Rabson * Copyright (c) 2000 Ruslan Ermilov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Fixes for 830/845G support: David Dawes * 852GM/855GM/865G support added by David Dawes */ #include __FBSDID("$FreeBSD$"); #include "opt_bus.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MALLOC_DECLARE(M_AGP); #define READ1(off) bus_space_read_1(sc->bst, sc->bsh, off) #define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off) #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) #define WRITEGTT(off,v) bus_space_write_4(sc->gtt_bst, sc->gtt_bsh, off, v) #define CHIP_I810 0 /* i810/i815 */ #define CHIP_I830 1 /* 830M/845G */ #define CHIP_I855 2 /* 852GM/855GM/865G */ #define CHIP_I915 3 /* 915G/915GM */ struct agp_i810_softc { struct agp_softc agp; u_int32_t initial_aperture; /* aperture size at startup */ struct agp_gatt *gatt; int chiptype; /* i810-like or i830 */ u_int32_t dcache_size; /* i810 only */ u_int32_t stolen; /* number of i830/845 gtt entries for stolen memory */ device_t bdev; /* bridge device */ struct resource *regs; /* memory mapped GC registers */ bus_space_tag_t bst; /* bus_space tag */ bus_space_handle_t bsh; /* bus_space handle */ struct resource *gtt; /* memory mapped GATT entries */ bus_space_tag_t gtt_bst; /* bus_space tag */ bus_space_handle_t gtt_bsh; /* bus_space handle */ }; static const char* agp_i810_match(device_t dev) { if (pci_get_class(dev) != PCIC_DISPLAY || pci_get_subclass(dev) != PCIS_DISPLAY_VGA) return NULL; switch (pci_get_devid(dev)) { case 0x71218086: return ("Intel 82810 (i810 GMCH) SVGA controller"); case 0x71238086: return ("Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller"); case 0x71258086: return ("Intel 82810E (i810E GMCH) SVGA controller"); case 0x11328086: return ("Intel 82815 (i815 GMCH) SVGA controller"); case 0x35778086: return ("Intel 82830M (830M GMCH) SVGA controller"); case 0x25628086: return ("Intel 82845G (845G GMCH) SVGA controller"); case 0x35828086: switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) { case AGP_I855_GME: return ("Intel 82855GME (855GME GMCH) SVGA controller"); case AGP_I855_GM: return ("Intel 82855GM (855GM GMCH) SVGA controller"); case AGP_I852_GME: return ("Intel 82852GME (852GME GMCH) SVGA controller"); case AGP_I852_GM: return ("Intel 82852GM (852GM GMCH) SVGA controller"); default: return ("Intel 8285xM (85xGM GMCH) SVGA controller"); } case 0x25728086: return ("Intel 82865G (865G GMCH) SVGA controller"); case 0x25828086: return ("Intel 82915G (915G GMCH) SVGA controller"); case 0x25928086: return ("Intel 82915GM (915GM GMCH) SVGA controller"); }; return NULL; } /* * Find bridge device. */ static device_t agp_i810_find_bridge(device_t dev) { device_t *children, child; int nchildren, i; u_int32_t devid; /* * Calculate bridge device's ID. */ devid = pci_get_devid(dev); switch (devid) { case 0x71218086: case 0x71238086: case 0x71258086: devid -= 0x10000; break; case 0x11328086: case 0x35778086: case 0x25628086: case 0x35828086: case 0x25728086: case 0x25828086: case 0x25928086: devid -= 0x20000; break; }; - if (device_get_children(device_get_parent(dev), &children, &nchildren)) + if (device_get_children(device_get_parent(device_get_parent(dev)), + &children, &nchildren)) return 0; for (i = 0; i < nchildren; i++) { child = children[i]; if (pci_get_devid(child) == devid) { free(children, M_TEMP); return child; } } free(children, M_TEMP); return 0; } static int agp_i810_probe(device_t dev) { const char *desc; if (resource_disabled("agp", device_get_unit(dev))) return (ENXIO); desc = agp_i810_match(dev); if (desc) { device_t bdev; u_int8_t smram; unsigned int gcc1; int devid = pci_get_devid(dev); bdev = agp_i810_find_bridge(dev); if (!bdev) { if (bootverbose) printf("I810: can't find bridge device\n"); return ENXIO; } /* * checking whether internal graphics device has been activated. */ switch (devid) { /* i810 */ case 0x71218086: case 0x71238086: case 0x71258086: case 0x11328086: smram = pci_read_config(bdev, AGP_I810_SMRAM, 1); if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED) { if (bootverbose) printf("I810: disabled, not probing\n"); return ENXIO; } break; /* i830 */ case 0x35778086: case 0x35828086: case 0x25628086: case 0x25728086: gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1); if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) { if (bootverbose) printf("I830: disabled, not probing\n"); return ENXIO; } break; /* i915 */ case 0x25828086: case 0x25928086: gcc1 = pci_read_config(bdev, AGP_I915_DEVEN, 4); if ((gcc1 & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED) { if (bootverbose) printf("I915: disabled, not probing\n"); return ENXIO; } break; default: return ENXIO; } - device_verbose(dev); device_set_desc(dev, desc); return BUS_PROBE_DEFAULT; } return ENXIO; } static int agp_i810_attach(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); struct agp_gatt *gatt; int error, rid; sc->bdev = agp_i810_find_bridge(dev); if (!sc->bdev) return ENOENT; error = agp_generic_attach(dev); if (error) return error; switch (pci_get_devid(dev)) { case 0x71218086: case 0x71238086: case 0x71258086: case 0x11328086: sc->chiptype = CHIP_I810; break; case 0x35778086: case 0x25628086: sc->chiptype = CHIP_I830; break; case 0x35828086: case 0x25728086: sc->chiptype = CHIP_I855; break; case 0x25828086: case 0x25928086: sc->chiptype = CHIP_I915; break; }; /* Same for i810 and i830 */ if (sc->chiptype == CHIP_I915) rid = AGP_I915_MMADR; else rid = AGP_I810_MMADR; sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->regs) { agp_generic_detach(dev); return ENODEV; } sc->bst = rman_get_bustag(sc->regs); sc->bsh = rman_get_bushandle(sc->regs); if (sc->chiptype == CHIP_I915) { rid = AGP_I915_GTTADR; sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->gtt) { bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR, sc->regs); agp_generic_detach(dev); return ENODEV; } sc->gtt_bst = rman_get_bustag(sc->gtt); sc->gtt_bsh = rman_get_bushandle(sc->gtt); } sc->initial_aperture = AGP_GET_APERTURE(dev); gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT); if (!gatt) { agp_generic_detach(dev); return ENOMEM; } sc->gatt = gatt; gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT; if ( sc->chiptype == CHIP_I810 ) { /* Some i810s have on-chip memory called dcache */ if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) sc->dcache_size = 4 * 1024 * 1024; else sc->dcache_size = 0; /* According to the specs the gatt on the i810 must be 64k */ gatt->ag_virtual = contigmalloc( 64 * 1024, M_AGP, 0, 0, ~0, PAGE_SIZE, 0); if (!gatt->ag_virtual) { if (bootverbose) device_printf(dev, "contiguous allocation failed\n"); free(gatt, M_AGP); agp_generic_detach(dev); return ENOMEM; } bzero(gatt->ag_virtual, gatt->ag_entries * sizeof(u_int32_t)); gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); agp_flush_cache(); /* Install the GATT. */ WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); } else if ( sc->chiptype == CHIP_I830 ) { /* The i830 automatically initializes the 128k gatt on boot. */ unsigned int gcc1, pgtblctl; gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1); switch (gcc1 & AGP_I830_GCC1_GMS) { case AGP_I830_GCC1_GMS_STOLEN_512: sc->stolen = (512 - 132) * 1024 / 4096; break; case AGP_I830_GCC1_GMS_STOLEN_1024: sc->stolen = (1024 - 132) * 1024 / 4096; break; case AGP_I830_GCC1_GMS_STOLEN_8192: sc->stolen = (8192 - 132) * 1024 / 4096; break; default: sc->stolen = 0; device_printf(dev, "unknown memory configuration, disabling\n"); agp_generic_detach(dev); return EINVAL; } if (sc->stolen > 0) device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024); /* GATT address is already in there, make sure it's enabled */ pgtblctl = READ4(AGP_I810_PGTBL_CTL); pgtblctl |= 1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); gatt->ag_physical = pgtblctl & ~1; } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915) { /* CHIP_I855 */ unsigned int gcc1, pgtblctl, stolen; /* Stolen memory is set up at the beginning of the aperture by * the BIOS, consisting of the GATT followed by 4kb for the BIOS * display. */ if (sc->chiptype == CHIP_I855) stolen = 132; else stolen = 260; gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1); switch (gcc1 & AGP_I855_GCC1_GMS) { case AGP_I855_GCC1_GMS_STOLEN_1M: sc->stolen = (1024 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_4M: sc->stolen = (4096 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_8M: sc->stolen = (8192 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_16M: sc->stolen = (16384 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_32M: sc->stolen = (32768 - stolen) * 1024 / 4096; break; case AGP_I915_GCC1_GMS_STOLEN_48M: sc->stolen = (49152 - stolen) * 1024 / 4096; break; case AGP_I915_GCC1_GMS_STOLEN_64M: sc->stolen = (65536 - stolen) * 1024 / 4096; break; default: sc->stolen = 0; device_printf(dev, "unknown memory configuration, disabling\n"); agp_generic_detach(dev); return EINVAL; } if (sc->stolen > 0) device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024); /* GATT address is already in there, make sure it's enabled */ pgtblctl = READ4(AGP_I810_PGTBL_CTL); pgtblctl |= 1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); gatt->ag_physical = pgtblctl & ~1; } - /* Add a device for the drm to attach to */ - if (!device_add_child( dev, "drmsub", -1 )) - printf("out of memory...\n"); - - return bus_generic_attach(dev); + return 0; } static int agp_i810_detach(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); int error; - device_t child; error = agp_generic_detach(dev); if (error) return error; /* Clear the GATT base. */ if ( sc->chiptype == CHIP_I810 ) { WRITE4(AGP_I810_PGTBL_CTL, 0); } else { unsigned int pgtblctl; pgtblctl = READ4(AGP_I810_PGTBL_CTL); pgtblctl &= ~1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); } /* Put the aperture back the way it started. */ AGP_SET_APERTURE(dev, sc->initial_aperture); if ( sc->chiptype == CHIP_I810 ) { contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP); } free(sc->gatt, M_AGP); if (sc->chiptype == CHIP_I915) { bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR, sc->gtt); bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_MMADR, sc->regs); } else { bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR, sc->regs); } - child = device_find_child( dev, "drmsub", 0 ); - if (child) - device_delete_child( dev, child ); - return 0; } static u_int32_t agp_i810_get_aperture(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); uint32_t temp; u_int16_t miscc; switch (sc->chiptype) { case CHIP_I810: miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32) return 32 * 1024 * 1024; else return 64 * 1024 * 1024; case CHIP_I830: temp = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); if ((temp & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) return 64 * 1024 * 1024; else return 128 * 1024 * 1024; case CHIP_I855: return 128 * 1024 * 1024; case CHIP_I915: temp = pci_read_config(dev, AGP_I915_MSAC, 1); if ((temp & AGP_I915_MSAC_GMASIZE) == AGP_I915_MSAC_GMASIZE_128) { return 128 * 1024 * 1024; } else { return 256 * 1024 * 1024; } } return 0; } static int agp_i810_set_aperture(device_t dev, u_int32_t aperture) { struct agp_i810_softc *sc = device_get_softc(dev); u_int16_t miscc, gcc1; u_int32_t temp; switch (sc->chiptype) { case CHIP_I810: /* * Double check for sanity. */ if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) { device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); miscc &= ~AGP_I810_MISCC_WINSIZE; if (aperture == 32 * 1024 * 1024) miscc |= AGP_I810_MISCC_WINSIZE_32; else miscc |= AGP_I810_MISCC_WINSIZE_64; pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2); break; case CHIP_I830: if (aperture != 64 * 1024 * 1024 && aperture != 128 * 1024 * 1024) { device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); gcc1 &= ~AGP_I830_GCC1_GMASIZE; if (aperture == 64 * 1024 * 1024) gcc1 |= AGP_I830_GCC1_GMASIZE_64; else gcc1 |= AGP_I830_GCC1_GMASIZE_128; pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2); break; case CHIP_I855: if (aperture != 128 * 1024 * 1024) { device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } break; case CHIP_I915: temp = pci_read_config(dev, AGP_I915_MSAC, 1); temp &= ~AGP_I915_MSAC_GMASIZE; switch (aperture) { case 128 * 1024 * 1024: temp |= AGP_I915_MSAC_GMASIZE_128; break; case 256 * 1024 * 1024: temp |= AGP_I915_MSAC_GMASIZE_256; break; default: device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } pci_write_config(dev, AGP_I915_MSAC, temp, 1); break; } return 0; } static int agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical) { struct agp_i810_softc *sc = device_get_softc(dev); if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) { device_printf(dev, "failed: offset is 0x%08x, shift is %d, entries is %d\n", offset, AGP_PAGE_SHIFT, sc->gatt->ag_entries); return EINVAL; } if ( sc->chiptype != CHIP_I810 ) { if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) { device_printf(dev, "trying to bind into stolen memory"); return EINVAL; } } if (sc->chiptype == CHIP_I915) { WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, physical | 1); } else { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical | 1); } return 0; } static int agp_i810_unbind_page(device_t dev, int offset) { struct agp_i810_softc *sc = device_get_softc(dev); if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) return EINVAL; if ( sc->chiptype != CHIP_I810 ) { if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) { device_printf(dev, "trying to unbind from stolen memory"); return EINVAL; } } if (sc->chiptype == CHIP_I915) { WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, 0); } else { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0); } return 0; } /* * Writing via memory mapped registers already flushes all TLBs. */ static void agp_i810_flush_tlb(device_t dev) { } static int agp_i810_enable(device_t dev, u_int32_t mode) { return 0; } static struct agp_memory * agp_i810_alloc_memory(device_t dev, int type, vm_size_t size) { struct agp_i810_softc *sc = device_get_softc(dev); struct agp_memory *mem; if ((size & (AGP_PAGE_SIZE - 1)) != 0) return 0; if (sc->agp.as_allocated + size > sc->agp.as_maxmem) return 0; if (type == 1) { /* * Mapping local DRAM into GATT. */ if ( sc->chiptype != CHIP_I810 ) return 0; if (size != sc->dcache_size) return 0; } else if (type == 2) { /* * Bogus mapping of a single page for the hardware cursor. */ if (size != AGP_PAGE_SIZE) return 0; } mem = malloc(sizeof *mem, M_AGP, M_WAITOK); mem->am_id = sc->agp.as_nextid++; mem->am_size = size; mem->am_type = type; if (type != 1) mem->am_obj = vm_object_allocate(OBJT_DEFAULT, atop(round_page(size))); else mem->am_obj = 0; if (type == 2) { /* * Allocate and wire down the page now so that we can * get its physical address. */ vm_page_t m; VM_OBJECT_LOCK(mem->am_obj); m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY | VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); VM_OBJECT_UNLOCK(mem->am_obj); mem->am_physical = VM_PAGE_TO_PHYS(m); } else { mem->am_physical = 0; } mem->am_offset = 0; mem->am_is_bound = 0; TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link); sc->agp.as_allocated += size; return mem; } static int agp_i810_free_memory(device_t dev, struct agp_memory *mem) { struct agp_i810_softc *sc = device_get_softc(dev); if (mem->am_is_bound) return EBUSY; if (mem->am_type == 2) { /* * Unwire the page which we wired in alloc_memory. */ vm_page_t m; VM_OBJECT_LOCK(mem->am_obj); m = vm_page_lookup(mem->am_obj, 0); VM_OBJECT_UNLOCK(mem->am_obj); vm_page_lock_queues(); vm_page_unwire(m, 0); vm_page_unlock_queues(); } sc->agp.as_allocated -= mem->am_size; TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link); if (mem->am_obj) vm_object_deallocate(mem->am_obj); free(mem, M_AGP); return 0; } static int agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset) { struct agp_i810_softc *sc = device_get_softc(dev); vm_offset_t i; if (mem->am_type != 1) return agp_generic_bind_memory(dev, mem, offset); if ( sc->chiptype != CHIP_I810 ) return EINVAL; for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, i | 3); } return 0; } static int agp_i810_unbind_memory(device_t dev, struct agp_memory *mem) { struct agp_i810_softc *sc = device_get_softc(dev); vm_offset_t i; if (mem->am_type != 1) return agp_generic_unbind_memory(dev, mem); if ( sc->chiptype != CHIP_I810 ) return EINVAL; for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0); return 0; } -static int -agp_i810_print_child(device_t dev, device_t child) -{ - int retval = 0; - - retval += bus_print_child_header(dev, child); - retval += printf(": (child of agp_i810.c)"); - retval += bus_print_child_footer(dev, child); - - return retval; -} - static device_method_t agp_i810_methods[] = { /* Device interface */ DEVMETHOD(device_probe, agp_i810_probe), DEVMETHOD(device_attach, agp_i810_attach), DEVMETHOD(device_detach, agp_i810_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), /* AGP interface */ DEVMETHOD(agp_get_aperture, agp_i810_get_aperture), DEVMETHOD(agp_set_aperture, agp_i810_set_aperture), DEVMETHOD(agp_bind_page, agp_i810_bind_page), DEVMETHOD(agp_unbind_page, agp_i810_unbind_page), DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb), DEVMETHOD(agp_enable, agp_i810_enable), DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory), DEVMETHOD(agp_free_memory, agp_i810_free_memory), DEVMETHOD(agp_bind_memory, agp_i810_bind_memory), DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory), - /* bus methods */ - DEVMETHOD(bus_print_child, agp_i810_print_child), - DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), { 0, 0 } }; static driver_t agp_i810_driver = { "agp", agp_i810_methods, sizeof(struct agp_i810_softc), }; static devclass_t agp_devclass; -DRIVER_MODULE(agp_i810, pci, agp_i810_driver, agp_devclass, 0, 0); +DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0); MODULE_DEPEND(agp_i810, agp, 1, 1, 1); MODULE_DEPEND(agp_i810, pci, 1, 1, 1); Index: head/sys/dev/drm/drm_agpsupport.c =================================================================== --- head/sys/dev/drm/drm_agpsupport.c (revision 153578) +++ head/sys/dev/drm/drm_agpsupport.c (revision 153579) @@ -1,473 +1,478 @@ /* drm_agpsupport.h -- DRM support for AGP/GART backend -*- linux-c -*- * Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Author: * Rickard E. (Rik) Faith * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #ifdef __FreeBSD__ #include #include #endif /* Returns 1 if AGP or 0 if not. */ static int drm_device_find_capability(drm_device_t *dev, int cap) { int ret; if (dev->driver.device_is_agp != NULL) { ret = (*dev->driver.device_is_agp)(dev); if (ret != DRM_MIGHT_BE_AGP) { return ret == 2; } } #ifdef __FreeBSD__ +#if __FreeBSD_version >= 700010 + + return (pci_find_extcap(dev->device, cap, NULL) == 0); +#else /* Code taken from agp.c. IWBNI that was a public interface. */ u_int32_t status; u_int8_t ptr, next; /* * Check the CAP_LIST bit of the PCI status register first. */ status = pci_read_config(dev->device, PCIR_STATUS, 2); if (!(status & 0x10)) return 0; /* * Traverse the capabilities list. */ for (ptr = pci_read_config(dev->device, AGP_CAPPTR, 1); ptr != 0; ptr = next) { u_int32_t capid = pci_read_config(dev->device, ptr, 4); next = AGP_CAPID_GET_NEXT_PTR(capid); /* * If this capability entry ID is cap, then we are done. */ if (AGP_CAPID_GET_CAP_ID(capid) == cap) return 1; } return 0; +#endif #else /* XXX: fill me in for non-FreeBSD */ return 1; #endif } int drm_device_is_agp(drm_device_t *dev) { if (dev->driver.device_is_agp != NULL) { int ret; /* device_is_agp returns a tristate, 0 = not AGP, 1 = definitely * AGP, 2 = fall back to PCI capability */ ret = (*dev->driver.device_is_agp)(dev); if (ret != 2) return ret; } return (drm_device_find_capability(dev, PCIY_AGP)); } int drm_device_is_pcie(drm_device_t *dev) { return (drm_device_find_capability(dev, PCIY_EXPRESS)); } int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info) { struct agp_info *kern; if (!dev->agp || !dev->agp->acquired) return EINVAL; kern = &dev->agp->info; agp_get_info(dev->agp->agpdev, kern); info->agp_version_major = 1; info->agp_version_minor = 0; info->mode = kern->ai_mode; info->aperture_base = kern->ai_aperture_base; info->aperture_size = kern->ai_aperture_size; info->memory_allowed = kern->ai_memory_allowed; info->memory_used = kern->ai_memory_used; info->id_vendor = kern->ai_devid & 0xffff; info->id_device = kern->ai_devid >> 16; return 0; } int drm_agp_info_ioctl(DRM_IOCTL_ARGS) { int err; drm_agp_info_t info; DRM_DEVICE; err = drm_agp_info(dev, &info); if (err != 0) return err; *(drm_agp_info_t *) data = info; return 0; } int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; return drm_agp_acquire(dev); } int drm_agp_acquire(drm_device_t *dev) { int retcode; if (!dev->agp || dev->agp->acquired) return EINVAL; retcode = agp_acquire(dev->agp->agpdev); if (retcode) return retcode; dev->agp->acquired = 1; return 0; } int drm_agp_release_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; return drm_agp_release(dev); } int drm_agp_release(drm_device_t * dev) { if (!dev->agp || !dev->agp->acquired) return EINVAL; agp_release(dev->agp->agpdev); dev->agp->acquired = 0; return 0; } int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode) { if (!dev->agp || !dev->agp->acquired) return EINVAL; dev->agp->mode = mode.mode; agp_enable(dev->agp->agpdev, mode.mode); dev->agp->base = dev->agp->info.ai_aperture_base; dev->agp->enabled = 1; return 0; } int drm_agp_enable_ioctl(DRM_IOCTL_ARGS) { drm_agp_mode_t mode; DRM_DEVICE; mode = *(drm_agp_mode_t *) data; return drm_agp_enable(dev, mode); } int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) { drm_agp_mem_t *entry; void *handle; unsigned long pages; u_int32_t type; struct agp_memory_info info; if (!dev->agp || !dev->agp->acquired) return EINVAL; entry = malloc(sizeof(*entry), M_DRM, M_NOWAIT | M_ZERO); if (entry == NULL) return ENOMEM; pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u_int32_t) request->type; DRM_UNLOCK(); handle = drm_agp_allocate_memory(pages, type); DRM_LOCK(); if (handle == NULL) { free(entry, M_DRM); return ENOMEM; } entry->handle = handle; entry->bound = 0; entry->pages = pages; entry->prev = NULL; entry->next = dev->agp->memory; if (dev->agp->memory) dev->agp->memory->prev = entry; dev->agp->memory = entry; agp_memory_info(dev->agp->agpdev, entry->handle, &info); request->handle = (unsigned long) entry->handle; request->physical = info.ami_physical; return 0; } int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_agp_buffer_t request; int retcode; request = *(drm_agp_buffer_t *) data; DRM_LOCK(); retcode = drm_agp_alloc(dev, &request); DRM_UNLOCK(); *(drm_agp_buffer_t *) data = request; return retcode; } static drm_agp_mem_t * drm_agp_lookup_entry(drm_device_t *dev, void *handle) { drm_agp_mem_t *entry; for (entry = dev->agp->memory; entry; entry = entry->next) { if (entry->handle == handle) return entry; } return NULL; } int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) { drm_agp_mem_t *entry; int retcode; if (!dev->agp || !dev->agp->acquired) return EINVAL; entry = drm_agp_lookup_entry(dev, (void *)request->handle); if (entry == NULL || !entry->bound) return EINVAL; DRM_UNLOCK(); retcode = drm_agp_unbind_memory(entry->handle); DRM_LOCK(); if (retcode == 0) entry->bound = 0; return retcode; } int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_agp_binding_t request; int retcode; request = *(drm_agp_binding_t *) data; DRM_LOCK(); retcode = drm_agp_unbind(dev, &request); DRM_UNLOCK(); return retcode; } int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) { drm_agp_mem_t *entry; int retcode; int page; if (!dev->agp || !dev->agp->acquired) return EINVAL; DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE); entry = drm_agp_lookup_entry(dev, (void *)request->handle); if (entry == NULL || entry->bound) return EINVAL; page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; DRM_UNLOCK(); retcode = drm_agp_bind_memory(entry->handle, page); DRM_LOCK(); if (retcode == 0) entry->bound = dev->agp->base + (page << PAGE_SHIFT); return retcode; } int drm_agp_bind_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_agp_binding_t request; int retcode; request = *(drm_agp_binding_t *) data; DRM_LOCK(); retcode = drm_agp_bind(dev, &request); DRM_UNLOCK(); return retcode; } int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) { drm_agp_mem_t *entry; if (!dev->agp || !dev->agp->acquired) return EINVAL; entry = drm_agp_lookup_entry(dev, (void*)request->handle); if (entry == NULL) return EINVAL; if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; DRM_UNLOCK(); if (entry->bound) drm_agp_unbind_memory(entry->handle); drm_agp_free_memory(entry->handle); DRM_LOCK(); free(entry, M_DRM); return 0; } int drm_agp_free_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_agp_buffer_t request; int retcode; request = *(drm_agp_buffer_t *) data; DRM_LOCK(); retcode = drm_agp_free(dev, &request); DRM_UNLOCK(); return retcode; } drm_agp_head_t *drm_agp_init(void) { device_t agpdev; drm_agp_head_t *head = NULL; int agp_available = 1; agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev) agp_available = 0; DRM_DEBUG("agp_available = %d\n", agp_available); if (agp_available) { head = malloc(sizeof(*head), M_DRM, M_NOWAIT | M_ZERO); if (head == NULL) return NULL; head->agpdev = agpdev; agp_get_info(agpdev, &head->info); head->memory = NULL; DRM_INFO("AGP at 0x%08lx %dMB\n", (long)head->info.ai_aperture_base, (int)(head->info.ai_aperture_size >> 20)); } return head; } void *drm_agp_allocate_memory(size_t pages, u32 type) { device_t agpdev; agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev) return NULL; return agp_alloc_memory(agpdev, type, pages << AGP_PAGE_SHIFT); } int drm_agp_free_memory(void *handle) { device_t agpdev; agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return 0; agp_free_memory(agpdev, handle); return 1; } int drm_agp_bind_memory(void *handle, off_t start) { device_t agpdev; agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return EINVAL; return agp_bind_memory(agpdev, handle, start * PAGE_SIZE); } int drm_agp_unbind_memory(void *handle) { device_t agpdev; agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return EINVAL; return agp_unbind_memory(agpdev, handle); } Index: head/sys/dev/drm/drm_drv.c =================================================================== --- head/sys/dev/drm/drm_drv.c (revision 153578) +++ head/sys/dev/drm/drm_drv.c (revision 153579) @@ -1,946 +1,954 @@ /* drm_drv.h -- Generic driver template -*- linux-c -*- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com */ /*- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Rickard E. (Rik) Faith * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/drm_sarea.h" #ifdef DRM_DEBUG_DEFAULT_ON int drm_debug_flag = 1; #else int drm_debug_flag = 0; #endif static int drm_load(drm_device_t *dev); static void drm_unload(drm_device_t *dev); static drm_pci_id_list_t *drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist); #ifdef __FreeBSD__ #define DRIVER_SOFTC(unit) \ ((drm_device_t *)devclass_get_softc(drm_devclass, unit)) MODULE_VERSION(drm, 1); MODULE_DEPEND(drm, agp, 1, 1, 1); MODULE_DEPEND(drm, pci, 1, 1, 1); #if __FreeBSD_version > 502127 MODULE_DEPEND(drm, mem, 1, 1, 1); #endif #endif /* __FreeBSD__ */ #if defined(__NetBSD__) || defined(__OpenBSD__) #define DRIVER_SOFTC(unit) \ ((drm_device_t *)device_lookup(&drm_cd, unit)) #endif /* __NetBSD__ || __OpenBSD__ */ static drm_ioctl_desc_t drm_ioctls[256] = { [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, DRM_AUTH|DRM_MASTER }, [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { drm_dma, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, DRM_AUTH }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0 }, }; #ifdef __FreeBSD__ static struct cdevsw drm_cdevsw = { #if __FreeBSD_version >= 502103 .d_version = D_VERSION, #endif .d_open = drm_open, .d_close = drm_close, .d_read = drm_read, .d_ioctl = drm_ioctl, .d_poll = drm_poll, .d_mmap = drm_mmap, .d_name = "drm", #if __FreeBSD_version >= 502103 .d_flags = D_TRACKCLOSE | D_NEEDGIANT, #else .d_maj = 145, .d_flags = D_TRACKCLOSE, #endif #if __FreeBSD_version < 500000 .d_bmaj = -1 #endif }; int drm_probe(device_t dev, drm_pci_id_list_t *idlist) { drm_pci_id_list_t *id_entry; int vendor, device; +#if __FreeBSD_version < 700010 device_t realdev; if (!strcmp(device_get_name(dev), "drmsub")) realdev = device_get_parent(dev); else realdev = dev; vendor = pci_get_vendor(realdev); device = pci_get_device(realdev); +#else + vendor = pci_get_vendor(dev); + device = pci_get_device(dev); +#endif id_entry = drm_find_description(vendor, device, idlist); if (id_entry != NULL) { device_set_desc(dev, id_entry->name); return 0; } return ENXIO; } int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist) { drm_device_t *dev; drm_pci_id_list_t *id_entry; int unit; unit = device_get_unit(nbdev); dev = device_get_softc(nbdev); +#if __FreeBSD_version < 700010 if (!strcmp(device_get_name(nbdev), "drmsub")) dev->device = device_get_parent(nbdev); else dev->device = nbdev; - +#else + dev->device = nbdev; +#endif dev->devnode = make_dev(&drm_cdevsw, unit, DRM_DEV_UID, DRM_DEV_GID, DRM_DEV_MODE, "dri/card%d", unit); #if __FreeBSD_version >= 500000 mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF); #endif id_entry = drm_find_description(pci_get_vendor(dev->device), pci_get_device(dev->device), idlist); dev->id_entry = id_entry; return drm_load(dev); } int drm_detach(device_t dev) { drm_unload(device_get_softc(dev)); return 0; } #ifndef DRM_DEV_NAME #define DRM_DEV_NAME "drm" #endif devclass_t drm_devclass; #elif defined(__NetBSD__) || defined(__OpenBSD__) static struct cdevsw drm_cdevsw = { drm_open, drm_close, drm_read, nowrite, drm_ioctl, nostop, notty, drm_poll, drm_mmap, nokqfilter, D_TTY }; int drm_refcnt = 0; #if defined(__NetBSD__) && __NetBSD_Version__ >= 106080000 MOD_DEV("drm", DRIVER_NAME, NULL, -1, &drm_cdevsw, CDEV_MAJOR); #else MOD_DEV("drm", LM_DT_CHAR, CDEV_MAJOR, &drm_cdevsw); #endif int drm_lkmentry(struct lkm_table *lkmtp, int cmd, int ver); static int drm_lkmhandle(struct lkm_table *lkmtp, int cmd); int drm_modprobe(void); int drm_probe(struct pci_attach_args *pa); void drm_attach(struct pci_attach_args *pa, dev_t kdev); int drm_lkmentry(struct lkm_table *lkmtp, int cmd, int ver) { DISPATCH(lkmtp, cmd, ver, drm_lkmhandle, drm_lkmhandle, drm_lkmhandle); } static int drm_lkmhandle(struct lkm_table *lkmtp, int cmd) { int error = 0; switch(cmd) { case LKM_E_LOAD: if (lkmexists(lkmtp)) return EEXIST; if(drm_modprobe()) return 0; return 1; case LKM_E_UNLOAD: if (drm_refcnt > 0) return (EBUSY); break; case LKM_E_STAT: break; default: error = EIO; break; } return error; } int drm_modprobe(void) { struct pci_attach_args pa; int error; error = pci_find_device(&pa, drm_probe, idlist); if (error != 0) drm_attach(&pa, 0); return error; } int drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t idlist) { const char *desc; drm_pci_id_list_t *id_entry; id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), idlist); if (id_entry != NULL) { return 1; } return 0; } void drm_attach(struct pci_attach_args *pa, dev_t kdev, drm_pci_id_list_t *idlist) { int i; drm_device_t *dev; drm_pci_id_list_t *id_entry; config_makeroom(kdev, &drm_cd); drm_cd.cd_devs[(kdev)] = malloc(sizeof(drm_device_t), M_DRM, M_WAITOK); dev = DRIVER_SOFTC(kdev); memset(dev, 0, sizeof(drm_device_t)); memcpy(&dev->pa, pa, sizeof(dev->pa)); dev->irq = pa->pa_intrline; dev->pci_domain = 0; dev->pci_bus = pa->pa_bus; dev->pci_slot = pa->pa_device; dev->pci_func = pa->pa_function; dev->dma_tag = pa->pa_dmat; id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), idlist); dev->driver.pci_id_entry = id_entry; DRM_INFO("%s", id_entry->name); drm_load(dev); } int drm_detach(struct device *self, int flags) { drm_unload((drm_device_t *)self); return 0; } int drm_activate(struct device *self, enum devact act) { switch (act) { case DVACT_ACTIVATE: return (EOPNOTSUPP); break; case DVACT_DEACTIVATE: /* FIXME */ break; } return (0); } #endif /* __NetBSD__ || __OpenBSD__ */ drm_pci_id_list_t *drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist) { int i = 0; for (i = 0; idlist[i].vendor != 0; i++) { if ((idlist[i].vendor == vendor) && (idlist[i].device == device)) { return &idlist[i]; } } return NULL; } static int drm_firstopen(drm_device_t *dev) { drm_local_map_t *map; int i; DRM_SPINLOCK_ASSERT(&dev->dev_lock); /* prebuild the SAREA */ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); if (i != 0) return i; if (dev->driver.firstopen) dev->driver.firstopen(dev); dev->buf_use = 0; if (dev->driver.use_dma) { i = drm_dma_setup(dev); if (i != 0) return i; } dev->counters = 6; dev->types[0] = _DRM_STAT_LOCK; dev->types[1] = _DRM_STAT_OPENS; dev->types[2] = _DRM_STAT_CLOSES; dev->types[3] = _DRM_STAT_IOCTLS; dev->types[4] = _DRM_STAT_LOCKS; dev->types[5] = _DRM_STAT_UNLOCKS; for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ ) atomic_set( &dev->counts[i], 0 ); for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { dev->magiclist[i].head = NULL; dev->magiclist[i].tail = NULL; } dev->lock.lock_queue = 0; dev->irq_enabled = 0; dev->context_flag = 0; dev->last_context = 0; dev->if_version = 0; #ifdef __FreeBSD__ dev->buf_sigio = NULL; #elif defined(__NetBSD__) || defined(__OpenBSD__) dev->buf_pgid = 0; #endif DRM_DEBUG( "\n" ); return 0; } static int drm_lastclose(drm_device_t *dev) { drm_magic_entry_t *pt, *next; drm_local_map_t *map, *mapsave; int i; DRM_SPINLOCK_ASSERT(&dev->dev_lock); DRM_DEBUG( "\n" ); if (dev->driver.lastclose != NULL) dev->driver.lastclose(dev); if (dev->irq_enabled) drm_irq_uninstall(dev); if ( dev->unique ) { free(dev->unique, M_DRM); dev->unique = NULL; dev->unique_len = 0; } /* Clear pid list */ for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { for ( pt = dev->magiclist[i].head ; pt ; pt = next ) { next = pt->next; free(pt, M_DRM); } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } /* Clear AGP information */ if ( dev->agp ) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; /* Remove AGP resources, but leave dev->agp intact until * drm_unload is called. */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; if ( entry->bound ) drm_agp_unbind_memory(entry->handle); drm_agp_free_memory(entry->handle); free(entry, M_DRM); } dev->agp->memory = NULL; if (dev->agp->acquired) drm_agp_release(dev); dev->agp->acquired = 0; dev->agp->enabled = 0; } if (dev->sg != NULL) { drm_sg_cleanup(dev->sg); dev->sg = NULL; } TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) { drm_rmmap(dev, map); } drm_dma_takedown(dev); if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } return 0; } static int drm_load(drm_device_t *dev) { int retcode; DRM_DEBUG( "\n" ); dev->irq = pci_get_irq(dev->device); /* XXX Fix domain number (alpha hoses) */ dev->pci_domain = 0; dev->pci_bus = pci_get_bus(dev->device); dev->pci_slot = pci_get_slot(dev->device); dev->pci_func = pci_get_function(dev->device); TAILQ_INIT(&dev->maplist); drm_mem_init(); #ifdef __FreeBSD__ drm_sysctl_init(dev); #endif TAILQ_INIT(&dev->files); if (dev->driver.load != NULL) { DRM_LOCK(); retcode = dev->driver.load(dev, dev->id_entry->driver_private); DRM_UNLOCK(); if (retcode != 0) goto error; } if (dev->driver.use_agp) { if (drm_device_is_agp(dev)) dev->agp = drm_agp_init(); if (dev->driver.require_agp && dev->agp == NULL) { DRM_ERROR("Card isn't AGP, or couldn't initialize " "AGP.\n"); retcode = DRM_ERR(ENOMEM); goto error; } if (dev->agp != NULL) { if (drm_mtrr_add(dev->agp->info.ai_aperture_base, dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0) dev->agp->mtrr = 1; } } retcode = drm_ctxbitmap_init(dev); if (retcode != 0) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); goto error; } DRM_INFO("Initialized %s %d.%d.%d %s\n", dev->driver.name, dev->driver.major, dev->driver.minor, dev->driver.patchlevel, dev->driver.date); return 0; error: #ifdef __FreeBSD__ drm_sysctl_cleanup(dev); #endif DRM_LOCK(); drm_lastclose(dev); DRM_UNLOCK(); #ifdef __FreeBSD__ destroy_dev(dev->devnode); #if __FreeBSD_version >= 500000 mtx_destroy(&dev->dev_lock); #endif #endif return retcode; } static void drm_unload(drm_device_t *dev) { int i; DRM_DEBUG( "\n" ); #ifdef __FreeBSD__ drm_sysctl_cleanup(dev); destroy_dev(dev->devnode); #endif drm_ctxbitmap_cleanup(dev); if (dev->agp && dev->agp->mtrr) { int __unused retcode; retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base, dev->agp->info.ai_aperture_size, DRM_MTRR_WC); DRM_DEBUG("mtrr_del = %d", retcode); } DRM_LOCK(); drm_lastclose(dev); DRM_UNLOCK(); /* Clean up PCI resources allocated by drm_bufs.c. We're not really * worried about resource consumption while the DRM is inactive (between * lastclose and firstopen or unload) because these aren't actually * taking up KVA, just keeping the PCI resource allocated. */ for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { if (dev->pcir[i] == NULL) continue; bus_release_resource(dev->device, SYS_RES_MEMORY, dev->pcirid[i], dev->pcir[i]); dev->pcir[i] = NULL; } if ( dev->agp ) { free(dev->agp, M_DRM); dev->agp = NULL; } if (dev->driver.unload != NULL) dev->driver.unload(dev); drm_mem_uninit(); #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 mtx_destroy(&dev->dev_lock); #endif } int drm_version(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_version_t version; int len; DRM_COPY_FROM_USER_IOCTL( version, (drm_version_t *)data, sizeof(version) ); #define DRM_COPY( name, value ) \ len = strlen( value ); \ if ( len > name##_len ) len = name##_len; \ name##_len = strlen( value ); \ if ( len && name ) { \ if ( DRM_COPY_TO_USER( name, value, len ) ) \ return DRM_ERR(EFAULT); \ } version.version_major = dev->driver.major; version.version_minor = dev->driver.minor; version.version_patchlevel = dev->driver.patchlevel; DRM_COPY(version.name, dev->driver.name); DRM_COPY(version.date, dev->driver.date); DRM_COPY(version.desc, dev->driver.desc); DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) ); return 0; } int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) { drm_device_t *dev = NULL; int retcode = 0; dev = DRIVER_SOFTC(minor(kdev)); DRM_DEBUG( "open_count = %d\n", dev->open_count ); retcode = drm_open_helper(kdev, flags, fmt, p, dev); if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); DRM_LOCK(); #ifdef __FreeBSD__ device_busy(dev->device); #endif if ( !dev->open_count++ ) retcode = drm_firstopen(dev); DRM_UNLOCK(); } return retcode; } int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) { drm_file_t *priv; DRM_DEVICE; int retcode = 0; DRMFILE filp = (void *)(uintptr_t)(DRM_CURRENTPID); DRM_DEBUG( "open_count = %d\n", dev->open_count ); DRM_LOCK(); priv = drm_find_file_by_proc(dev, p); if (!priv) { DRM_UNLOCK(); DRM_ERROR("can't find authenticator\n"); return EINVAL; } if (dev->driver.preclose != NULL) dev->driver.preclose(dev, filp); /* ======================================================== * Begin inline drm_release */ #ifdef __FreeBSD__ DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", DRM_CURRENTPID, (long)dev->device, dev->open_count ); #elif defined(__NetBSD__) || defined(__OpenBSD__) DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", DRM_CURRENTPID, (long)&dev->device, dev->open_count); #endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.filp == filp) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); if (dev->driver.reclaim_buffers_locked != NULL) dev->driver.reclaim_buffers_locked(dev, filp); drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); /* FIXME: may require heavy-handed reset of hardware at this point, possibly processed via a callback to the X server. */ } else if (dev->driver.reclaim_buffers_locked != NULL && dev->lock.hw_lock != NULL) { /* The lock is required to reclaim buffers */ for (;;) { if ( !dev->lock.hw_lock ) { /* Device has been unregistered */ retcode = DRM_ERR(EINTR); break; } if (drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ } /* Contention */ #if defined(__FreeBSD__) && __FreeBSD_version > 500000 retcode = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); #else retcode = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH, "drmlk2", 0); #endif if (retcode) break; } if (retcode == 0) { dev->driver.reclaim_buffers_locked(dev, filp); drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); } } if (dev->driver.use_dma && !dev->driver.reclaim_buffers_locked) drm_reclaim_buffers(dev, filp); #if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) funsetown(&dev->buf_sigio); #elif defined(__FreeBSD__) funsetown(dev->buf_sigio); #elif defined(__NetBSD__) || defined(__OpenBSD__) dev->buf_pgid = 0; #endif /* __NetBSD__ || __OpenBSD__ */ if (--priv->refs == 0) { if (dev->driver.postclose != NULL) dev->driver.postclose(dev, priv); TAILQ_REMOVE(&dev->files, priv, link); free(priv, M_DRM); } /* ======================================================== * End inline drm_release */ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); #ifdef __FreeBSD__ device_unbusy(dev->device); #endif if (--dev->open_count == 0) { retcode = drm_lastclose(dev); } DRM_UNLOCK(); return retcode; } /* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */ int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p) { DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); int is_driver_ioctl = 0; drm_file_t *priv; DRMFILE filp = (DRMFILE)(uintptr_t)DRM_CURRENTPID; DRM_LOCK(); priv = drm_find_file_by_proc(dev, p); DRM_UNLOCK(); if (priv == NULL) { DRM_ERROR("can't find authenticator\n"); return EINVAL; } atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; #ifdef __FreeBSD__ DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", DRM_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated ); #elif defined(__NetBSD__) || defined(__OpenBSD__) DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", DRM_CURRENTPID, cmd, nr, (long)&dev->device, priv->authenticated ); #endif switch (cmd) { case FIONBIO: case FIOASYNC: return 0; #ifdef __FreeBSD__ case FIOSETOWN: return fsetown(*(int *)data, &dev->buf_sigio); case FIOGETOWN: #if (__FreeBSD_version >= 500000) *(int *) data = fgetown(&dev->buf_sigio); #else *(int *) data = fgetown(dev->buf_sigio); #endif return 0; #endif /* __FreeBSD__ */ #if defined(__NetBSD__) || defined(__OpenBSD__) case TIOCSPGRP: dev->buf_pgid = *(int *)data; return 0; case TIOCGPGRP: *(int *)data = dev->buf_pgid; return 0; #endif /* __NetBSD__ */ } if (IOCGROUP(cmd) != DRM_IOCTL_BASE) { DRM_DEBUG("Bad ioctl group 0x%x\n", (int)IOCGROUP(cmd)); return EINVAL; } ioctl = &drm_ioctls[nr]; /* It's not a core DRM ioctl, try driver-specific. */ if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) { /* The array entries begin at DRM_COMMAND_BASE ioctl nr */ nr -= DRM_COMMAND_BASE; if (nr > dev->driver.max_ioctl) { DRM_DEBUG("Bad driver ioctl number, 0x%x (of 0x%x)\n", nr, dev->driver.max_ioctl); return EINVAL; } ioctl = &dev->driver.ioctls[nr]; is_driver_ioctl = 1; } func = ioctl->func; if (func == NULL) { DRM_DEBUG( "no function\n" ); return EINVAL; } /* ioctl->master check should be against something in the filp set up * for the first opener, but it doesn't matter yet. */ if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) || ((ioctl->flags & DRM_AUTH) && !priv->authenticated) || ((ioctl->flags & DRM_MASTER) && !priv->master)) return EACCES; if (is_driver_ioctl) DRM_LOCK(); retcode = func(kdev, cmd, data, flags, p, filp); if (is_driver_ioctl) DRM_UNLOCK(); if (retcode != 0) DRM_DEBUG(" returning %d\n", retcode); return DRM_ERR(retcode); } #if DRM_LINUX #include MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); #define LINUX_IOCTL_DRM_MIN 0x6400 #define LINUX_IOCTL_DRM_MAX 0x64ff static linux_ioctl_function_t drm_linux_ioctl; static struct linux_ioctl_handler drm_handler = {drm_linux_ioctl, LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX}; SYSINIT(drm_register, SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_register_handler, &drm_handler); SYSUNINIT(drm_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_unregister_handler, &drm_handler); /* The bits for in/out are switched on Linux */ #define LINUX_IOC_IN IOC_OUT #define LINUX_IOC_OUT IOC_IN static int drm_linux_ioctl(DRM_STRUCTPROC *p, struct linux_ioctl_args* args) { int error; int cmd = args->cmd; args->cmd &= ~(LINUX_IOC_IN | LINUX_IOC_OUT); if (cmd & LINUX_IOC_IN) args->cmd |= IOC_IN; if (cmd & LINUX_IOC_OUT) args->cmd |= IOC_OUT; error = ioctl(p, (struct ioctl_args *)args); return error; } #endif /* DRM_LINUX */ Index: head/sys/dev/drm/i915_drv.c =================================================================== --- head/sys/dev/drm/i915_drv.c (revision 153578) +++ head/sys/dev/drm/i915_drv.c (revision 153579) @@ -1,112 +1,120 @@ /* i915_drv.c -- ATI Radeon driver -*- linux-c -*- * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com */ /*- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/i915_drm.h" #include "dev/drm/i915_drv.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t i915_pciidlist[] = { i915_PCI_IDS }; static void i915_configure(drm_device_t *dev) { dev->driver.buf_priv_size = 1; /* No dev_priv */ dev->driver.load = i915_driver_load; dev->driver.preclose = i915_driver_preclose; dev->driver.lastclose = i915_driver_lastclose; dev->driver.device_is_agp = i915_driver_device_is_agp, dev->driver.irq_preinstall = i915_driver_irq_preinstall; dev->driver.irq_postinstall = i915_driver_irq_postinstall; dev->driver.irq_uninstall = i915_driver_irq_uninstall; dev->driver.irq_handler = i915_driver_irq_handler; dev->driver.ioctls = i915_ioctls; dev->driver.max_ioctl = i915_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.require_agp = 1; dev->driver.use_mtrr = 1; dev->driver.use_irq = 1; } #ifdef __FreeBSD__ static int i915_probe(device_t dev) { return drm_probe(dev, i915_pciidlist); } static int i915_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); i915_configure(dev); return drm_attach(nbdev, i915_pciidlist); } static device_method_t i915_methods[] = { /* Device interface */ DEVMETHOD(device_probe, i915_probe), DEVMETHOD(device_attach, i915_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t i915_driver = { +#if __FreeBSD_version >= 700010 + "drm", +#else "drmsub", +#endif i915_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(i915, vgapci, i915_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(i915, agp, i915_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(i915, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) CFDRIVER_DECL(i915, DV_TTY, NULL); #endif Index: head/sys/dev/drm/mach64_drv.c =================================================================== --- head/sys/dev/drm/mach64_drv.c (revision 153578) +++ head/sys/dev/drm/mach64_drv.c (revision 153579) @@ -1,117 +1,121 @@ /* mach64_drv.c -- ATI Rage 128 driver -*- linux-c -*- * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Rickard E. (Rik) Faith * Gareth Hughes */ #include __FBSDID("$FreeBSD$"); #include #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mach64_drm.h" #include "dev/drm/mach64_drv.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t mach64_pciidlist[] = { mach64_PCI_IDS }; static void mach64_configure(drm_device_t *dev) { dev->driver.buf_priv_size = 1; /* No dev_priv */ dev->driver.lastclose = mach64_driver_lastclose; dev->driver.vblank_wait = mach64_driver_vblank_wait; dev->driver.irq_preinstall = mach64_driver_irq_preinstall; dev->driver.irq_postinstall = mach64_driver_irq_postinstall; dev->driver.irq_uninstall = mach64_driver_irq_uninstall; dev->driver.irq_handler = mach64_driver_irq_handler; dev->driver.dma_ioctl = mach64_dma_buffers; dev->driver.ioctls = mach64_ioctls; dev->driver.max_ioctl = mach64_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.use_mtrr = 1; dev->driver.use_pci_dma = 1; dev->driver.use_dma = 1; dev->driver.use_irq = 1; dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ static int mach64_probe(device_t dev) { return drm_probe(dev, mach64_pciidlist); } static int mach64_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); mach64_configure(dev); return drm_attach(nbdev, mach64_pciidlist); } static device_method_t mach64_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mach64_probe), DEVMETHOD(device_attach, mach64_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t mach64_driver = { "drm", mach64_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(mach64, vgapci, mach64_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(mach64, pci, mach64_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(mach64, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) CFDRIVER_DECL(mach64, DV_TTY, NULL); #endif Index: head/sys/dev/drm/mga_drv.c =================================================================== --- head/sys/dev/drm/mga_drv.c (revision 153578) +++ head/sys/dev/drm/mga_drv.c (revision 153579) @@ -1,161 +1,172 @@ /* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*- * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Rickard E. (Rik) Faith * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/mga_drm.h" #include "dev/drm/mga_drv.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t mga_pciidlist[] = { mga_PCI_IDS }; /** * Determine if the device really is AGP or not. * * In addition to the usual tests performed by \c drm_device_is_agp, this * function detects PCI G450 cards that appear to the system exactly like * AGP G450 cards. * * \param dev The device to be tested. * * \returns * If the device is a PCI G450, zero is returned. Otherwise non-zero is * returned. * * \bug * This function needs to be filled in! The implementation in * linux-core/mga_drv.c shows what needs to be done. */ static int mga_driver_device_is_agp(drm_device_t * dev) { + device_t bus; + /* There are PCI versions of the G450. These cards have the * same PCI ID as the AGP G450, but have an additional PCI-to-PCI * bridge chip. We detect these cards, which are not currently * supported by this driver, by looking at the device ID of the * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the * device. */ +#if __FreeBSD_version >= 700010 + bus = device_get_parent(device_get_parent(dev->device)); +#else + bus = device_get_parent(dev->device); +#endif if (pci_get_device(dev->device) == 0x0525 && - pci_get_vendor(device_get_parent(dev->device)) == 0x3388 && - pci_get_device(device_get_parent(dev->device)) == 0x0021) + pci_get_vendor(bus) == 0x3388 && + pci_get_device(bus) == 0x0021) return 0; else return 2; } static void mga_configure(drm_device_t *dev) { dev->driver.buf_priv_size = sizeof(drm_mga_buf_priv_t); dev->driver.load = mga_driver_load; dev->driver.unload = mga_driver_unload; dev->driver.lastclose = mga_driver_lastclose; dev->driver.vblank_wait = mga_driver_vblank_wait; dev->driver.irq_preinstall = mga_driver_irq_preinstall; dev->driver.irq_postinstall = mga_driver_irq_postinstall; dev->driver.irq_uninstall = mga_driver_irq_uninstall; dev->driver.irq_handler = mga_driver_irq_handler; dev->driver.dma_ioctl = mga_dma_buffers; dev->driver.dma_quiescent = mga_driver_dma_quiescent; dev->driver.device_is_agp = mga_driver_device_is_agp; dev->driver.ioctls = mga_ioctls; dev->driver.max_ioctl = mga_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.require_agp = 1; dev->driver.use_mtrr = 1; dev->driver.use_dma = 1; dev->driver.use_irq = 1; dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ static int mga_probe(device_t dev) { return drm_probe(dev, mga_pciidlist); } static int mga_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); mga_configure(dev); return drm_attach(nbdev, mga_pciidlist); } static device_method_t mga_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mga_probe), DEVMETHOD(device_attach, mga_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t mga_driver = { "drm", mga_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(mga, vgapci, mga_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(mga, pci, mga_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(mga, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) #ifdef _LKM CFDRIVER_DECL(mga, DV_TTY, NULL); #else CFATTACH_DECL(mga, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, drm_activate); #endif #endif Index: head/sys/dev/drm/r128_drv.c =================================================================== --- head/sys/dev/drm/r128_drv.c (revision 153578) +++ head/sys/dev/drm/r128_drv.c (revision 153579) @@ -1,122 +1,126 @@ /* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*- * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Rickard E. (Rik) Faith * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/r128_drm.h" #include "dev/drm/r128_drv.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t r128_pciidlist[] = { r128_PCI_IDS }; static void r128_configure(drm_device_t *dev) { dev->driver.buf_priv_size = sizeof(drm_r128_buf_priv_t); dev->driver.preclose = r128_driver_preclose; dev->driver.lastclose = r128_driver_lastclose; dev->driver.vblank_wait = r128_driver_vblank_wait; dev->driver.irq_preinstall = r128_driver_irq_preinstall; dev->driver.irq_postinstall = r128_driver_irq_postinstall; dev->driver.irq_uninstall = r128_driver_irq_uninstall; dev->driver.irq_handler = r128_driver_irq_handler; dev->driver.dma_ioctl = r128_cce_buffers; dev->driver.ioctls = r128_ioctls; dev->driver.max_ioctl = r128_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.use_mtrr = 1; dev->driver.use_pci_dma = 1; dev->driver.use_sg = 1; dev->driver.use_dma = 1; dev->driver.use_irq = 1; dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ static int r128_probe(device_t dev) { return drm_probe(dev, r128_pciidlist); } static int r128_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); r128_configure(dev); return drm_attach(nbdev, r128_pciidlist); } static device_method_t r128_methods[] = { /* Device interface */ DEVMETHOD(device_probe, r128_probe), DEVMETHOD(device_attach, r128_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t r128_driver = { "drm", r128_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(r128, vgapci, r128_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(r128, pci, r128_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(r128, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) #ifdef _LKM CFDRIVER_DECL(r128, DV_TTY, NULL); #else CFATTACH_DECL(r128, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, drm_activate); #endif #endif Index: head/sys/dev/drm/radeon_drv.c =================================================================== --- head/sys/dev/drm/radeon_drv.c (revision 153578) +++ head/sys/dev/drm/radeon_drv.c (revision 153579) @@ -1,127 +1,131 @@ /* radeon_drv.c -- ATI Radeon driver -*- linux-c -*- * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com */ /*- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/radeon_drm.h" #include "dev/drm/radeon_drv.h" #include "dev/drm/drm_pciids.h" int radeon_no_wb; /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t radeon_pciidlist[] = { radeon_PCI_IDS }; static void radeon_configure(drm_device_t *dev) { dev->driver.buf_priv_size = sizeof(drm_radeon_buf_priv_t); dev->driver.load = radeon_driver_load; dev->driver.unload = radeon_driver_unload; dev->driver.firstopen = radeon_driver_firstopen; dev->driver.open = radeon_driver_open; dev->driver.preclose = radeon_driver_preclose; dev->driver.postclose = radeon_driver_postclose; dev->driver.lastclose = radeon_driver_lastclose; dev->driver.vblank_wait = radeon_driver_vblank_wait; dev->driver.irq_preinstall = radeon_driver_irq_preinstall; dev->driver.irq_postinstall = radeon_driver_irq_postinstall; dev->driver.irq_uninstall = radeon_driver_irq_uninstall; dev->driver.irq_handler = radeon_driver_irq_handler; dev->driver.dma_ioctl = radeon_cp_buffers; dev->driver.ioctls = radeon_ioctls; dev->driver.max_ioctl = radeon_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.use_mtrr = 1; dev->driver.use_pci_dma = 1; dev->driver.use_sg = 1; dev->driver.use_dma = 1; dev->driver.use_irq = 1; dev->driver.use_vbl_irq = 1; } #ifdef __FreeBSD__ static int radeon_probe(device_t dev) { return drm_probe(dev, radeon_pciidlist); } static int radeon_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); radeon_configure(dev); return drm_attach(nbdev, radeon_pciidlist); } static device_method_t radeon_methods[] = { /* Device interface */ DEVMETHOD(device_probe, radeon_probe), DEVMETHOD(device_attach, radeon_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t radeon_driver = { "drm", radeon_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(radeon, vgapci, radeon_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(radeon, pci, radeon_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(radeon, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) #ifdef _LKM CFDRIVER_DECL(radeon, DV_TTY, NULL); #else CFATTACH_DECL(radeon, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, drm_activate); #endif #endif /* __FreeBSD__ */ Index: head/sys/dev/drm/savage_drv.c =================================================================== --- head/sys/dev/drm/savage_drv.c (revision 153578) +++ head/sys/dev/drm/savage_drv.c (revision 153579) @@ -1,107 +1,111 @@ /* savage_drv.c -- Savage DRI driver */ /*- * Copyright 2005 Eric Anholt * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Eric Anholt */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/drm.h" #include "dev/drm/savage_drm.h" #include "dev/drm/savage_drv.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t savage_pciidlist[] = { savage_PCI_IDS }; static void savage_configure(drm_device_t *dev) { dev->driver.buf_priv_size = sizeof(drm_savage_buf_priv_t); dev->driver.load = savage_driver_load; dev->driver.firstopen = savage_driver_firstopen; dev->driver.lastclose = savage_driver_lastclose; dev->driver.unload = savage_driver_unload; dev->driver.reclaim_buffers_locked = savage_reclaim_buffers; dev->driver.dma_ioctl = savage_bci_buffers; dev->driver.ioctls = savage_ioctls; dev->driver.max_ioctl = savage_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.use_mtrr = 1; dev->driver.use_pci_dma = 1; dev->driver.use_dma = 1; } #ifdef __FreeBSD__ static int savage_probe(device_t dev) { return drm_probe(dev, savage_pciidlist); } static int savage_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); savage_configure(dev); return drm_attach(nbdev, savage_pciidlist); } static device_method_t savage_methods[] = { /* Device interface */ DEVMETHOD(device_probe, savage_probe), DEVMETHOD(device_attach, savage_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t savage_driver = { "drm", savage_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(savage, vgapci, savage_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(savage, pci, savage_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(savage, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) CFDRIVER_DECL(savage, DV_TTY, NULL); #endif Index: head/sys/dev/drm/sis_drv.c =================================================================== --- head/sys/dev/drm/sis_drv.c (revision 153578) +++ head/sys/dev/drm/sis_drv.c (revision 153579) @@ -1,105 +1,109 @@ /* sis.c -- sis driver -*- linux-c -*- */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/drmP.h" #include "dev/drm/sis_drm.h" #include "dev/drm/sis_drv.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t sis_pciidlist[] = { sis_PCI_IDS }; static void sis_configure(drm_device_t *dev) { dev->driver.buf_priv_size = 1; /* No dev_priv */ dev->driver.context_ctor = sis_init_context; dev->driver.context_dtor = sis_final_context; dev->driver.ioctls = sis_ioctls; dev->driver.max_ioctl = sis_max_ioctl; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_agp = 1; dev->driver.use_mtrr = 1; } #ifdef __FreeBSD__ static int sis_probe(device_t dev) { return drm_probe(dev, sis_pciidlist); } static int sis_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); sis_configure(dev); return drm_attach(nbdev, sis_pciidlist); } static device_method_t sis_methods[] = { /* Device interface */ DEVMETHOD(device_probe, sis_probe), DEVMETHOD(device_attach, sis_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t sis_driver = { "drm", sis_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(sisdrm, vgapci, sis_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(sisdrm, pci, sis_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(sisdrm, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) #ifdef _LKM CFDRIVER_DECL(sis, DV_TTY, NULL); #else CFATTACH_DECL(sis, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, drm_activate); #endif #endif Index: head/sys/dev/drm/tdfx_drv.c =================================================================== --- head/sys/dev/drm/tdfx_drv.c (revision 153578) +++ head/sys/dev/drm/tdfx_drv.c (revision 153579) @@ -1,106 +1,110 @@ /* tdfx_drv.c -- tdfx driver -*- linux-c -*- * Created: Thu Oct 7 10:38:32 1999 by faith@precisioninsight.com */ /*- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Rickard E. (Rik) Faith * Daryll Strauss * Gareth Hughes * */ #include __FBSDID("$FreeBSD$"); #include "dev/drm/tdfx_drv.h" #include "dev/drm/drmP.h" #include "dev/drm/drm_pciids.h" /* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ static drm_pci_id_list_t tdfx_pciidlist[] = { tdfx_PCI_IDS }; static void tdfx_configure(drm_device_t *dev) { dev->driver.buf_priv_size = 1; /* No dev_priv */ dev->driver.max_ioctl = 0; dev->driver.name = DRIVER_NAME; dev->driver.desc = DRIVER_DESC; dev->driver.date = DRIVER_DATE; dev->driver.major = DRIVER_MAJOR; dev->driver.minor = DRIVER_MINOR; dev->driver.patchlevel = DRIVER_PATCHLEVEL; dev->driver.use_mtrr = 1; } #ifdef __FreeBSD__ static int tdfx_probe(device_t dev) { return drm_probe(dev, tdfx_pciidlist); } static int tdfx_attach(device_t nbdev) { drm_device_t *dev = device_get_softc(nbdev); bzero(dev, sizeof(drm_device_t)); tdfx_configure(dev); return drm_attach(nbdev, tdfx_pciidlist); } static device_method_t tdfx_methods[] = { /* Device interface */ DEVMETHOD(device_probe, tdfx_probe), DEVMETHOD(device_attach, tdfx_attach), DEVMETHOD(device_detach, drm_detach), { 0, 0 } }; static driver_t tdfx_driver = { "drm", tdfx_methods, sizeof(drm_device_t) }; extern devclass_t drm_devclass; +#if __FreeBSD_version >= 700010 +DRIVER_MODULE(tdfx, vgapci, tdfx_driver, drm_devclass, 0, 0); +#else DRIVER_MODULE(tdfx, pci, tdfx_driver, drm_devclass, 0, 0); +#endif MODULE_DEPEND(tdfx, drm, 1, 1, 1); #elif defined(__NetBSD__) || defined(__OpenBSD__) #ifdef _LKM CFDRIVER_DECL(tdfx, DV_TTY, NULL); #else CFATTACH_DECL(tdfx, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach, drm_activate); #endif #endif Index: head/sys/pci/agp_i810.c =================================================================== --- head/sys/pci/agp_i810.c (revision 153578) +++ head/sys/pci/agp_i810.c (revision 153579) @@ -1,863 +1,831 @@ /*- * Copyright (c) 2000 Doug Rabson * Copyright (c) 2000 Ruslan Ermilov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Fixes for 830/845G support: David Dawes * 852GM/855GM/865G support added by David Dawes */ #include __FBSDID("$FreeBSD$"); #include "opt_bus.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MALLOC_DECLARE(M_AGP); #define READ1(off) bus_space_read_1(sc->bst, sc->bsh, off) #define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off) #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) #define WRITEGTT(off,v) bus_space_write_4(sc->gtt_bst, sc->gtt_bsh, off, v) #define CHIP_I810 0 /* i810/i815 */ #define CHIP_I830 1 /* 830M/845G */ #define CHIP_I855 2 /* 852GM/855GM/865G */ #define CHIP_I915 3 /* 915G/915GM */ struct agp_i810_softc { struct agp_softc agp; u_int32_t initial_aperture; /* aperture size at startup */ struct agp_gatt *gatt; int chiptype; /* i810-like or i830 */ u_int32_t dcache_size; /* i810 only */ u_int32_t stolen; /* number of i830/845 gtt entries for stolen memory */ device_t bdev; /* bridge device */ struct resource *regs; /* memory mapped GC registers */ bus_space_tag_t bst; /* bus_space tag */ bus_space_handle_t bsh; /* bus_space handle */ struct resource *gtt; /* memory mapped GATT entries */ bus_space_tag_t gtt_bst; /* bus_space tag */ bus_space_handle_t gtt_bsh; /* bus_space handle */ }; static const char* agp_i810_match(device_t dev) { if (pci_get_class(dev) != PCIC_DISPLAY || pci_get_subclass(dev) != PCIS_DISPLAY_VGA) return NULL; switch (pci_get_devid(dev)) { case 0x71218086: return ("Intel 82810 (i810 GMCH) SVGA controller"); case 0x71238086: return ("Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller"); case 0x71258086: return ("Intel 82810E (i810E GMCH) SVGA controller"); case 0x11328086: return ("Intel 82815 (i815 GMCH) SVGA controller"); case 0x35778086: return ("Intel 82830M (830M GMCH) SVGA controller"); case 0x25628086: return ("Intel 82845G (845G GMCH) SVGA controller"); case 0x35828086: switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) { case AGP_I855_GME: return ("Intel 82855GME (855GME GMCH) SVGA controller"); case AGP_I855_GM: return ("Intel 82855GM (855GM GMCH) SVGA controller"); case AGP_I852_GME: return ("Intel 82852GME (852GME GMCH) SVGA controller"); case AGP_I852_GM: return ("Intel 82852GM (852GM GMCH) SVGA controller"); default: return ("Intel 8285xM (85xGM GMCH) SVGA controller"); } case 0x25728086: return ("Intel 82865G (865G GMCH) SVGA controller"); case 0x25828086: return ("Intel 82915G (915G GMCH) SVGA controller"); case 0x25928086: return ("Intel 82915GM (915GM GMCH) SVGA controller"); }; return NULL; } /* * Find bridge device. */ static device_t agp_i810_find_bridge(device_t dev) { device_t *children, child; int nchildren, i; u_int32_t devid; /* * Calculate bridge device's ID. */ devid = pci_get_devid(dev); switch (devid) { case 0x71218086: case 0x71238086: case 0x71258086: devid -= 0x10000; break; case 0x11328086: case 0x35778086: case 0x25628086: case 0x35828086: case 0x25728086: case 0x25828086: case 0x25928086: devid -= 0x20000; break; }; - if (device_get_children(device_get_parent(dev), &children, &nchildren)) + if (device_get_children(device_get_parent(device_get_parent(dev)), + &children, &nchildren)) return 0; for (i = 0; i < nchildren; i++) { child = children[i]; if (pci_get_devid(child) == devid) { free(children, M_TEMP); return child; } } free(children, M_TEMP); return 0; } static int agp_i810_probe(device_t dev) { const char *desc; if (resource_disabled("agp", device_get_unit(dev))) return (ENXIO); desc = agp_i810_match(dev); if (desc) { device_t bdev; u_int8_t smram; unsigned int gcc1; int devid = pci_get_devid(dev); bdev = agp_i810_find_bridge(dev); if (!bdev) { if (bootverbose) printf("I810: can't find bridge device\n"); return ENXIO; } /* * checking whether internal graphics device has been activated. */ switch (devid) { /* i810 */ case 0x71218086: case 0x71238086: case 0x71258086: case 0x11328086: smram = pci_read_config(bdev, AGP_I810_SMRAM, 1); if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED) { if (bootverbose) printf("I810: disabled, not probing\n"); return ENXIO; } break; /* i830 */ case 0x35778086: case 0x35828086: case 0x25628086: case 0x25728086: gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1); if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) { if (bootverbose) printf("I830: disabled, not probing\n"); return ENXIO; } break; /* i915 */ case 0x25828086: case 0x25928086: gcc1 = pci_read_config(bdev, AGP_I915_DEVEN, 4); if ((gcc1 & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED) { if (bootverbose) printf("I915: disabled, not probing\n"); return ENXIO; } break; default: return ENXIO; } - device_verbose(dev); device_set_desc(dev, desc); return BUS_PROBE_DEFAULT; } return ENXIO; } static int agp_i810_attach(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); struct agp_gatt *gatt; int error, rid; sc->bdev = agp_i810_find_bridge(dev); if (!sc->bdev) return ENOENT; error = agp_generic_attach(dev); if (error) return error; switch (pci_get_devid(dev)) { case 0x71218086: case 0x71238086: case 0x71258086: case 0x11328086: sc->chiptype = CHIP_I810; break; case 0x35778086: case 0x25628086: sc->chiptype = CHIP_I830; break; case 0x35828086: case 0x25728086: sc->chiptype = CHIP_I855; break; case 0x25828086: case 0x25928086: sc->chiptype = CHIP_I915; break; }; /* Same for i810 and i830 */ if (sc->chiptype == CHIP_I915) rid = AGP_I915_MMADR; else rid = AGP_I810_MMADR; sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->regs) { agp_generic_detach(dev); return ENODEV; } sc->bst = rman_get_bustag(sc->regs); sc->bsh = rman_get_bushandle(sc->regs); if (sc->chiptype == CHIP_I915) { rid = AGP_I915_GTTADR; sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->gtt) { bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR, sc->regs); agp_generic_detach(dev); return ENODEV; } sc->gtt_bst = rman_get_bustag(sc->gtt); sc->gtt_bsh = rman_get_bushandle(sc->gtt); } sc->initial_aperture = AGP_GET_APERTURE(dev); gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT); if (!gatt) { agp_generic_detach(dev); return ENOMEM; } sc->gatt = gatt; gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT; if ( sc->chiptype == CHIP_I810 ) { /* Some i810s have on-chip memory called dcache */ if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) sc->dcache_size = 4 * 1024 * 1024; else sc->dcache_size = 0; /* According to the specs the gatt on the i810 must be 64k */ gatt->ag_virtual = contigmalloc( 64 * 1024, M_AGP, 0, 0, ~0, PAGE_SIZE, 0); if (!gatt->ag_virtual) { if (bootverbose) device_printf(dev, "contiguous allocation failed\n"); free(gatt, M_AGP); agp_generic_detach(dev); return ENOMEM; } bzero(gatt->ag_virtual, gatt->ag_entries * sizeof(u_int32_t)); gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); agp_flush_cache(); /* Install the GATT. */ WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); } else if ( sc->chiptype == CHIP_I830 ) { /* The i830 automatically initializes the 128k gatt on boot. */ unsigned int gcc1, pgtblctl; gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1); switch (gcc1 & AGP_I830_GCC1_GMS) { case AGP_I830_GCC1_GMS_STOLEN_512: sc->stolen = (512 - 132) * 1024 / 4096; break; case AGP_I830_GCC1_GMS_STOLEN_1024: sc->stolen = (1024 - 132) * 1024 / 4096; break; case AGP_I830_GCC1_GMS_STOLEN_8192: sc->stolen = (8192 - 132) * 1024 / 4096; break; default: sc->stolen = 0; device_printf(dev, "unknown memory configuration, disabling\n"); agp_generic_detach(dev); return EINVAL; } if (sc->stolen > 0) device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024); /* GATT address is already in there, make sure it's enabled */ pgtblctl = READ4(AGP_I810_PGTBL_CTL); pgtblctl |= 1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); gatt->ag_physical = pgtblctl & ~1; } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915) { /* CHIP_I855 */ unsigned int gcc1, pgtblctl, stolen; /* Stolen memory is set up at the beginning of the aperture by * the BIOS, consisting of the GATT followed by 4kb for the BIOS * display. */ if (sc->chiptype == CHIP_I855) stolen = 132; else stolen = 260; gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1); switch (gcc1 & AGP_I855_GCC1_GMS) { case AGP_I855_GCC1_GMS_STOLEN_1M: sc->stolen = (1024 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_4M: sc->stolen = (4096 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_8M: sc->stolen = (8192 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_16M: sc->stolen = (16384 - stolen) * 1024 / 4096; break; case AGP_I855_GCC1_GMS_STOLEN_32M: sc->stolen = (32768 - stolen) * 1024 / 4096; break; case AGP_I915_GCC1_GMS_STOLEN_48M: sc->stolen = (49152 - stolen) * 1024 / 4096; break; case AGP_I915_GCC1_GMS_STOLEN_64M: sc->stolen = (65536 - stolen) * 1024 / 4096; break; default: sc->stolen = 0; device_printf(dev, "unknown memory configuration, disabling\n"); agp_generic_detach(dev); return EINVAL; } if (sc->stolen > 0) device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024); /* GATT address is already in there, make sure it's enabled */ pgtblctl = READ4(AGP_I810_PGTBL_CTL); pgtblctl |= 1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); gatt->ag_physical = pgtblctl & ~1; } - /* Add a device for the drm to attach to */ - if (!device_add_child( dev, "drmsub", -1 )) - printf("out of memory...\n"); - - return bus_generic_attach(dev); + return 0; } static int agp_i810_detach(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); int error; - device_t child; error = agp_generic_detach(dev); if (error) return error; /* Clear the GATT base. */ if ( sc->chiptype == CHIP_I810 ) { WRITE4(AGP_I810_PGTBL_CTL, 0); } else { unsigned int pgtblctl; pgtblctl = READ4(AGP_I810_PGTBL_CTL); pgtblctl &= ~1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); } /* Put the aperture back the way it started. */ AGP_SET_APERTURE(dev, sc->initial_aperture); if ( sc->chiptype == CHIP_I810 ) { contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP); } free(sc->gatt, M_AGP); if (sc->chiptype == CHIP_I915) { bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR, sc->gtt); bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_MMADR, sc->regs); } else { bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR, sc->regs); } - child = device_find_child( dev, "drmsub", 0 ); - if (child) - device_delete_child( dev, child ); - return 0; } static u_int32_t agp_i810_get_aperture(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); uint32_t temp; u_int16_t miscc; switch (sc->chiptype) { case CHIP_I810: miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32) return 32 * 1024 * 1024; else return 64 * 1024 * 1024; case CHIP_I830: temp = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); if ((temp & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) return 64 * 1024 * 1024; else return 128 * 1024 * 1024; case CHIP_I855: return 128 * 1024 * 1024; case CHIP_I915: temp = pci_read_config(dev, AGP_I915_MSAC, 1); if ((temp & AGP_I915_MSAC_GMASIZE) == AGP_I915_MSAC_GMASIZE_128) { return 128 * 1024 * 1024; } else { return 256 * 1024 * 1024; } } return 0; } static int agp_i810_set_aperture(device_t dev, u_int32_t aperture) { struct agp_i810_softc *sc = device_get_softc(dev); u_int16_t miscc, gcc1; u_int32_t temp; switch (sc->chiptype) { case CHIP_I810: /* * Double check for sanity. */ if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) { device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2); miscc &= ~AGP_I810_MISCC_WINSIZE; if (aperture == 32 * 1024 * 1024) miscc |= AGP_I810_MISCC_WINSIZE_32; else miscc |= AGP_I810_MISCC_WINSIZE_64; pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2); break; case CHIP_I830: if (aperture != 64 * 1024 * 1024 && aperture != 128 * 1024 * 1024) { device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2); gcc1 &= ~AGP_I830_GCC1_GMASIZE; if (aperture == 64 * 1024 * 1024) gcc1 |= AGP_I830_GCC1_GMASIZE_64; else gcc1 |= AGP_I830_GCC1_GMASIZE_128; pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2); break; case CHIP_I855: if (aperture != 128 * 1024 * 1024) { device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } break; case CHIP_I915: temp = pci_read_config(dev, AGP_I915_MSAC, 1); temp &= ~AGP_I915_MSAC_GMASIZE; switch (aperture) { case 128 * 1024 * 1024: temp |= AGP_I915_MSAC_GMASIZE_128; break; case 256 * 1024 * 1024: temp |= AGP_I915_MSAC_GMASIZE_256; break; default: device_printf(dev, "bad aperture size %d\n", aperture); return EINVAL; } pci_write_config(dev, AGP_I915_MSAC, temp, 1); break; } return 0; } static int agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical) { struct agp_i810_softc *sc = device_get_softc(dev); if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) { device_printf(dev, "failed: offset is 0x%08x, shift is %d, entries is %d\n", offset, AGP_PAGE_SHIFT, sc->gatt->ag_entries); return EINVAL; } if ( sc->chiptype != CHIP_I810 ) { if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) { device_printf(dev, "trying to bind into stolen memory"); return EINVAL; } } if (sc->chiptype == CHIP_I915) { WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, physical | 1); } else { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical | 1); } return 0; } static int agp_i810_unbind_page(device_t dev, int offset) { struct agp_i810_softc *sc = device_get_softc(dev); if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) return EINVAL; if ( sc->chiptype != CHIP_I810 ) { if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) { device_printf(dev, "trying to unbind from stolen memory"); return EINVAL; } } if (sc->chiptype == CHIP_I915) { WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, 0); } else { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0); } return 0; } /* * Writing via memory mapped registers already flushes all TLBs. */ static void agp_i810_flush_tlb(device_t dev) { } static int agp_i810_enable(device_t dev, u_int32_t mode) { return 0; } static struct agp_memory * agp_i810_alloc_memory(device_t dev, int type, vm_size_t size) { struct agp_i810_softc *sc = device_get_softc(dev); struct agp_memory *mem; if ((size & (AGP_PAGE_SIZE - 1)) != 0) return 0; if (sc->agp.as_allocated + size > sc->agp.as_maxmem) return 0; if (type == 1) { /* * Mapping local DRAM into GATT. */ if ( sc->chiptype != CHIP_I810 ) return 0; if (size != sc->dcache_size) return 0; } else if (type == 2) { /* * Bogus mapping of a single page for the hardware cursor. */ if (size != AGP_PAGE_SIZE) return 0; } mem = malloc(sizeof *mem, M_AGP, M_WAITOK); mem->am_id = sc->agp.as_nextid++; mem->am_size = size; mem->am_type = type; if (type != 1) mem->am_obj = vm_object_allocate(OBJT_DEFAULT, atop(round_page(size))); else mem->am_obj = 0; if (type == 2) { /* * Allocate and wire down the page now so that we can * get its physical address. */ vm_page_t m; VM_OBJECT_LOCK(mem->am_obj); m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY | VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); VM_OBJECT_UNLOCK(mem->am_obj); mem->am_physical = VM_PAGE_TO_PHYS(m); } else { mem->am_physical = 0; } mem->am_offset = 0; mem->am_is_bound = 0; TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link); sc->agp.as_allocated += size; return mem; } static int agp_i810_free_memory(device_t dev, struct agp_memory *mem) { struct agp_i810_softc *sc = device_get_softc(dev); if (mem->am_is_bound) return EBUSY; if (mem->am_type == 2) { /* * Unwire the page which we wired in alloc_memory. */ vm_page_t m; VM_OBJECT_LOCK(mem->am_obj); m = vm_page_lookup(mem->am_obj, 0); VM_OBJECT_UNLOCK(mem->am_obj); vm_page_lock_queues(); vm_page_unwire(m, 0); vm_page_unlock_queues(); } sc->agp.as_allocated -= mem->am_size; TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link); if (mem->am_obj) vm_object_deallocate(mem->am_obj); free(mem, M_AGP); return 0; } static int agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset) { struct agp_i810_softc *sc = device_get_softc(dev); vm_offset_t i; if (mem->am_type != 1) return agp_generic_bind_memory(dev, mem, offset); if ( sc->chiptype != CHIP_I810 ) return EINVAL; for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, i | 3); } return 0; } static int agp_i810_unbind_memory(device_t dev, struct agp_memory *mem) { struct agp_i810_softc *sc = device_get_softc(dev); vm_offset_t i; if (mem->am_type != 1) return agp_generic_unbind_memory(dev, mem); if ( sc->chiptype != CHIP_I810 ) return EINVAL; for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0); return 0; } -static int -agp_i810_print_child(device_t dev, device_t child) -{ - int retval = 0; - - retval += bus_print_child_header(dev, child); - retval += printf(": (child of agp_i810.c)"); - retval += bus_print_child_footer(dev, child); - - return retval; -} - static device_method_t agp_i810_methods[] = { /* Device interface */ DEVMETHOD(device_probe, agp_i810_probe), DEVMETHOD(device_attach, agp_i810_attach), DEVMETHOD(device_detach, agp_i810_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), /* AGP interface */ DEVMETHOD(agp_get_aperture, agp_i810_get_aperture), DEVMETHOD(agp_set_aperture, agp_i810_set_aperture), DEVMETHOD(agp_bind_page, agp_i810_bind_page), DEVMETHOD(agp_unbind_page, agp_i810_unbind_page), DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb), DEVMETHOD(agp_enable, agp_i810_enable), DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory), DEVMETHOD(agp_free_memory, agp_i810_free_memory), DEVMETHOD(agp_bind_memory, agp_i810_bind_memory), DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory), - /* bus methods */ - DEVMETHOD(bus_print_child, agp_i810_print_child), - DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), { 0, 0 } }; static driver_t agp_i810_driver = { "agp", agp_i810_methods, sizeof(struct agp_i810_softc), }; static devclass_t agp_devclass; -DRIVER_MODULE(agp_i810, pci, agp_i810_driver, agp_devclass, 0, 0); +DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0); MODULE_DEPEND(agp_i810, agp, 1, 1, 1); MODULE_DEPEND(agp_i810, pci, 1, 1, 1); Index: head/sys/sys/param.h =================================================================== --- head/sys/sys/param.h (revision 153578) +++ head/sys/sys/param.h (revision 153579) @@ -1,334 +1,334 @@ /*- * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)param.h 8.3 (Berkeley) 4/4/95 * $FreeBSD$ */ #ifndef _SYS_PARAM_H_ #define _SYS_PARAM_H_ #include #define BSD 199506 /* System version (year & month). */ #define BSD4_3 1 #define BSD4_4 1 /* * __FreeBSD_version numbers are documented in the Porter's Handbook. * If you bump the version for any reason, you should update the documentation * there. * Currently this lives here: * * doc/en_US.ISO8859-1/books/porters-handbook/book.sgml * * scheme is: Rxx * 'R' is 0 if release branch or x.0-CURRENT before RELENG_*_0 * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 700009 /* Master, propagated to newvers */ +#define __FreeBSD_version 700010 /* Master, propagated to newvers */ #ifndef LOCORE #include #endif /* * Machine-independent constants (some used in following include files). * Redefined constants are from POSIX 1003.1 limits file. * * MAXCOMLEN should be >= sizeof(ac_comm) (see ) * MAXLOGNAME should be == UT_NAMESIZE+1 (see ) */ #include #define MAXCOMLEN 19 /* max command name remembered */ #define MAXINTERP 32 /* max interpreter file name length */ #define MAXLOGNAME 17 /* max login name length (incl. NUL) */ #define MAXUPRC CHILD_MAX /* max simultaneous processes */ #define NCARGS ARG_MAX /* max bytes for an exec function */ #define NGROUPS NGROUPS_MAX /* max number groups */ #define NOFILE OPEN_MAX /* max open files per process */ #define NOGROUP 65535 /* marker for empty group set member */ #define MAXHOSTNAMELEN 256 /* max hostname size */ #define SPECNAMELEN 63 /* max length of devicename */ /* More types and definitions used throughout the kernel. */ #ifdef _KERNEL #if 0 #if (defined(BURN_BRIDGES) || __FreeBSD_version >= 600000) \ && defined(OBSOLETE_IN_6) #error "This file contains obsolete code to be removed in 6.0-current" #endif #endif #include #include #ifndef LOCORE #include #include #endif #define FALSE 0 #define TRUE 1 #endif #ifndef _KERNEL /* Signals. */ #include #endif /* Machine type dependent parameters. */ #include #ifndef _KERNEL #include #endif #ifndef _NO_NAMESPACE_POLLUTION #ifndef DEV_BSHIFT #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #endif #define DEV_BSIZE (1<>PAGE_SHIFT) #endif /* * btodb() is messy and perhaps slow because `bytes' may be an off_t. We * want to shift an unsigned type to avoid sign extension and we don't * want to widen `bytes' unnecessarily. Assume that the result fits in * a daddr_t. */ #ifndef btodb #define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \ (sizeof (bytes) > sizeof(long) \ ? (daddr_t)((unsigned long long)(bytes) >> DEV_BSHIFT) \ : (daddr_t)((unsigned long)(bytes) >> DEV_BSHIFT)) #endif #ifndef dbtob #define dbtob(db) /* calculates (db * DEV_BSIZE) */ \ ((off_t)(db) << DEV_BSHIFT) #endif #endif /* _NO_NAMESPACE_POLLUTION */ #define PRIMASK 0x0ff #define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ #define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ #define NZERO 0 /* default "nice" */ #define NBBY 8 /* number of bits in a byte */ #define NBPW sizeof(int) /* number of bytes per word (integer) */ #define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */ #define NODEV (dev_t)(-1) /* non-existent device */ #define CBLOCK 128 /* Clist block size, must be a power of 2. */ #define CBQSIZE (CBLOCK/NBBY) /* Quote bytes/cblock - can do better. */ /* Data chars/clist. */ #define CBSIZE (CBLOCK - sizeof(struct cblock *) - CBQSIZE) #define CROUND (CBLOCK - 1) /* Clist rounding. */ /* * File system parameters and macros. * * MAXBSIZE - Filesystems are made out of blocks of at most MAXBSIZE bytes * per block. MAXBSIZE may be made larger without effecting * any existing filesystems as long as it does not exceed MAXPHYS, * and may be made smaller at the risk of not being able to use * filesystems which require a block size exceeding MAXBSIZE. * * BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the * minimum KVM memory reservation the kernel is willing to make. * Filesystems can of course request smaller chunks. Actual * backing memory uses a chunk size of a page (PAGE_SIZE). * * If you make BKVASIZE too small you risk seriously fragmenting * the buffer KVM map which may slow things down a bit. If you * make it too big the kernel will not be able to optimally use * the KVM memory reserved for the buffer cache and will wind * up with too-few buffers. * * The default is 16384, roughly 2x the block size used by a * normal UFS filesystem. */ #define MAXBSIZE 65536 /* must be power of 2 */ #define BKVASIZE 16384 /* must be power of 2 */ #define BKVAMASK (BKVASIZE-1) /* * MAXPATHLEN defines the longest permissible path length after expanding * symbolic links. It is used to allocate a temporary buffer from the buffer * pool in which to do the name expansion, hence should be a power of two, * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the * maximum number of symbolic links that may be expanded in a path name. * It should be set high enough to allow all legitimate uses, but halt * infinite loops reasonably quickly. */ #define MAXPATHLEN PATH_MAX #define MAXSYMLINKS 32 /* Bit map related macros. */ #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) #define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) /* Macros for counting and rounding. */ #ifndef howmany #define howmany(x, y) (((x)+((y)-1))/(y)) #endif #define rounddown(x, y) (((x)/(y))*(y)) #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ #define powerof2(x) ((((x)-1)&(x))==0) /* Macros for min/max. */ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #ifdef _KERNEL /* * Basic byte order function prototypes for non-inline functions. */ #ifndef LOCORE #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED __BEGIN_DECLS __uint32_t htonl(__uint32_t); __uint16_t htons(__uint16_t); __uint32_t ntohl(__uint32_t); __uint16_t ntohs(__uint16_t); __END_DECLS #endif #endif #ifndef lint #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif /* !_BYTEORDER_FUNC_DEFINED */ #endif /* lint */ #endif /* _KERNEL */ /* * Constants for setting the parameters of the kernel memory allocator. * * 2 ** MINBUCKET is the smallest unit of memory that will be * allocated. It must be at least large enough to hold a pointer. * * Units of memory less or equal to MAXALLOCSAVE will permanently * allocate physical memory; requests for these size pieces of * memory are quite fast. Allocations greater than MAXALLOCSAVE must * always allocate and free physical memory; requests for these * size allocations should be done infrequently as they will be slow. * * Constraints: PAGE_SIZE <= MAXALLOCSAVE <= 2 ** (MINBUCKET + 14), and * MAXALLOCSIZE must be a power of two. */ #if defined(__alpha__) || defined(__ia64__) || defined(__sparc64__) #define MINBUCKET 5 /* 5 => min allocation of 32 bytes */ #else #define MINBUCKET 4 /* 4 => min allocation of 16 bytes */ #endif #define MAXALLOCSAVE (2 * PAGE_SIZE) /* * Scale factor for scaled integers used to count %cpu time and load avgs. * * The number of CPU `tick's that map to a unique `%age' can be expressed * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that * can be calculated (assuming 32 bits) can be closely approximated using * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15). * * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age', * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024. */ #define FSHIFT 11 /* bits to right of fixed binary point */ #define FSCALE (1<> (PAGE_SHIFT - DEV_BSHIFT)) #define ctodb(db) /* calculates pages to devblks */ \ ((db) << (PAGE_SHIFT - DEV_BSHIFT)) #endif /* _SYS_PARAM_H_ */