1/*- 2 * Copyright (c) 2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/agp/agp.c 129579 2004-05-22 13:06:38Z mux $"); |
29 30#include "opt_bus.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/malloc.h> 35#include <sys/kernel.h> 36#include <sys/bus.h> 37#include <sys/conf.h> 38#include <sys/ioccom.h> 39#include <sys/agpio.h> 40#include <sys/lock.h> |
41#include <sys/mutex.h> 42#include <sys/proc.h> 43 44#include <dev/pci/pcivar.h> 45#include <dev/pci/pcireg.h> 46#include <pci/agppriv.h> 47#include <pci/agpvar.h> 48#include <pci/agpreg.h> --- 196 unchanged lines hidden (view full) --- 245 } 246 if (i == agp_max_size) i = agp_max_size - 1; 247 sc->as_maxmem = agp_max[i][1] << 20U; 248 249 /* 250 * The lock is used to prevent re-entry to 251 * agp_generic_bind_memory() since that function can sleep. 252 */ |
253 mtx_init(&sc->as_lock, "agp lock", NULL, MTX_DEF); |
254 255 /* 256 * Initialise stuff for the userland device. 257 */ 258 agp_devclass = devclass_find("agp"); 259 TAILQ_INIT(&sc->as_memory); 260 sc->as_nextid = 1; 261 --- 7 unchanged lines hidden (view full) --- 269 return 0; 270} 271 272int 273agp_generic_detach(device_t dev) 274{ 275 struct agp_softc *sc = device_get_softc(dev); 276 bus_release_resource(dev, SYS_RES_MEMORY, AGP_APBASE, sc->as_aperture); |
277 mtx_destroy(&sc->as_lock); |
278 destroy_dev(sc->as_devnode); 279 agp_flush_cache(); 280 return 0; 281} 282 283/* 284 * This does the enable logic for v3, with the same topology 285 * restrictions as in place for v2 -- one bus, one device on the bus. --- 196 unchanged lines hidden (view full) --- 482agp_generic_bind_memory(device_t dev, struct agp_memory *mem, 483 vm_offset_t offset) 484{ 485 struct agp_softc *sc = device_get_softc(dev); 486 vm_offset_t i, j, k; 487 vm_page_t m; 488 int error; 489 |
490 mtx_lock(&sc->as_lock); |
491 492 if (mem->am_is_bound) { 493 device_printf(dev, "memory already bound\n"); |
494 mtx_unlock(&sc->as_lock); |
495 return EINVAL; 496 } 497 498 if (offset < 0 499 || (offset & (AGP_PAGE_SIZE - 1)) != 0 500 || offset + mem->am_size > AGP_GET_APERTURE(dev)) { 501 device_printf(dev, "binding memory at bad offset %#x\n", 502 (int) offset); |
503 mtx_unlock(&sc->as_lock); |
504 return EINVAL; 505 } 506 507 /* 508 * Bind the individual pages and flush the chipset's 509 * TLB. 510 * 511 * XXX Presumably, this needs to be the pci address on alpha --- 40 unchanged lines hidden (view full) --- 552 for (k = 0; k <= i; k += PAGE_SIZE) { 553 m = vm_page_lookup(mem->am_obj, 554 OFF_TO_IDX(k)); 555 vm_page_lock_queues(); 556 vm_page_unwire(m, 0); 557 vm_page_unlock_queues(); 558 } 559 VM_OBJECT_UNLOCK(mem->am_obj); |
560 mtx_unlock(&sc->as_lock); |
561 return error; 562 } 563 } 564 vm_page_lock_queues(); 565 vm_page_wakeup(m); 566 vm_page_unlock_queues(); 567 } 568 --- 6 unchanged lines hidden (view full) --- 575 /* 576 * Make sure the chipset gets the new mappings. 577 */ 578 AGP_FLUSH_TLB(dev); 579 580 mem->am_offset = offset; 581 mem->am_is_bound = 1; 582 |
583 mtx_unlock(&sc->as_lock); |
584 585 return 0; 586} 587 588int 589agp_generic_unbind_memory(device_t dev, struct agp_memory *mem) 590{ 591 struct agp_softc *sc = device_get_softc(dev); 592 vm_page_t m; 593 int i; 594 |
595 mtx_lock(&sc->as_lock); |
596 597 if (!mem->am_is_bound) { 598 device_printf(dev, "memory is not bound\n"); |
599 mtx_unlock(&sc->as_lock); |
600 return EINVAL; 601 } 602 603 604 /* 605 * Unbind the individual pages and flush the chipset's 606 * TLB. Unwire the pages so they can be swapped. 607 */ --- 9 unchanged lines hidden (view full) --- 617 VM_OBJECT_UNLOCK(mem->am_obj); 618 619 agp_flush_cache(); 620 AGP_FLUSH_TLB(dev); 621 622 mem->am_offset = 0; 623 mem->am_is_bound = 0; 624 |
625 mtx_unlock(&sc->as_lock); |
626 627 return 0; 628} 629 630/* Helper functions for implementing user/kernel api */ 631 632static int 633agp_acquire_helper(device_t dev, enum agp_acquire_state state) --- 283 unchanged lines hidden --- |