agp.c (129567) | agp.c (129579) |
---|---|
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> | 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 129567 2004-05-22 00:44:08Z mux $"); | 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> | 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/lockmgr.h> | |
42#include <sys/mutex.h> 43#include <sys/proc.h> 44 45#include <dev/pci/pcivar.h> 46#include <dev/pci/pcireg.h> 47#include <pci/agppriv.h> 48#include <pci/agpvar.h> 49#include <pci/agpreg.h> --- 196 unchanged lines hidden (view full) --- 246 } 247 if (i == agp_max_size) i = agp_max_size - 1; 248 sc->as_maxmem = agp_max[i][1] << 20U; 249 250 /* 251 * The lock is used to prevent re-entry to 252 * agp_generic_bind_memory() since that function can sleep. 253 */ | 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 */ |
254 lockinit(&sc->as_lock, PZERO|PCATCH, "agplk", 0, 0); | 253 mtx_init(&sc->as_lock, "agp lock", NULL, MTX_DEF); |
255 256 /* 257 * Initialise stuff for the userland device. 258 */ 259 agp_devclass = devclass_find("agp"); 260 TAILQ_INIT(&sc->as_memory); 261 sc->as_nextid = 1; 262 --- 7 unchanged lines hidden (view full) --- 270 return 0; 271} 272 273int 274agp_generic_detach(device_t dev) 275{ 276 struct agp_softc *sc = device_get_softc(dev); 277 bus_release_resource(dev, SYS_RES_MEMORY, AGP_APBASE, sc->as_aperture); | 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); |
278 lockmgr(&sc->as_lock, LK_DRAIN, 0, curthread); 279 lockdestroy(&sc->as_lock); | 277 mtx_destroy(&sc->as_lock); |
280 destroy_dev(sc->as_devnode); 281 agp_flush_cache(); 282 return 0; 283} 284 285/* 286 * This does the enable logic for v3, with the same topology 287 * restrictions as in place for v2 -- one bus, one device on the bus. --- 196 unchanged lines hidden (view full) --- 484agp_generic_bind_memory(device_t dev, struct agp_memory *mem, 485 vm_offset_t offset) 486{ 487 struct agp_softc *sc = device_get_softc(dev); 488 vm_offset_t i, j, k; 489 vm_page_t m; 490 int error; 491 | 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 |
492 lockmgr(&sc->as_lock, LK_EXCLUSIVE, 0, curthread); | 490 mtx_lock(&sc->as_lock); |
493 494 if (mem->am_is_bound) { 495 device_printf(dev, "memory already bound\n"); | 491 492 if (mem->am_is_bound) { 493 device_printf(dev, "memory already bound\n"); |
496 lockmgr(&sc->as_lock, LK_RELEASE, 0, curthread); | 494 mtx_unlock(&sc->as_lock); |
497 return EINVAL; 498 } 499 500 if (offset < 0 501 || (offset & (AGP_PAGE_SIZE - 1)) != 0 502 || offset + mem->am_size > AGP_GET_APERTURE(dev)) { 503 device_printf(dev, "binding memory at bad offset %#x\n", 504 (int) offset); | 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); |
505 lockmgr(&sc->as_lock, LK_RELEASE, 0, curthread); | 503 mtx_unlock(&sc->as_lock); |
506 return EINVAL; 507 } 508 509 /* 510 * Bind the individual pages and flush the chipset's 511 * TLB. 512 * 513 * XXX Presumably, this needs to be the pci address on alpha --- 40 unchanged lines hidden (view full) --- 554 for (k = 0; k <= i; k += PAGE_SIZE) { 555 m = vm_page_lookup(mem->am_obj, 556 OFF_TO_IDX(k)); 557 vm_page_lock_queues(); 558 vm_page_unwire(m, 0); 559 vm_page_unlock_queues(); 560 } 561 VM_OBJECT_UNLOCK(mem->am_obj); | 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); |
562 lockmgr(&sc->as_lock, LK_RELEASE, 0, curthread); | 560 mtx_unlock(&sc->as_lock); |
563 return error; 564 } 565 } 566 vm_page_lock_queues(); 567 vm_page_wakeup(m); 568 vm_page_unlock_queues(); 569 } 570 --- 6 unchanged lines hidden (view full) --- 577 /* 578 * Make sure the chipset gets the new mappings. 579 */ 580 AGP_FLUSH_TLB(dev); 581 582 mem->am_offset = offset; 583 mem->am_is_bound = 1; 584 | 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 |
585 lockmgr(&sc->as_lock, LK_RELEASE, 0, curthread); | 583 mtx_unlock(&sc->as_lock); |
586 587 return 0; 588} 589 590int 591agp_generic_unbind_memory(device_t dev, struct agp_memory *mem) 592{ 593 struct agp_softc *sc = device_get_softc(dev); 594 vm_page_t m; 595 int i; 596 | 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 |
597 lockmgr(&sc->as_lock, LK_EXCLUSIVE, 0, curthread); | 595 mtx_lock(&sc->as_lock); |
598 599 if (!mem->am_is_bound) { 600 device_printf(dev, "memory is not bound\n"); | 596 597 if (!mem->am_is_bound) { 598 device_printf(dev, "memory is not bound\n"); |
601 lockmgr(&sc->as_lock, LK_RELEASE, 0, curthread); | 599 mtx_unlock(&sc->as_lock); |
602 return EINVAL; 603 } 604 605 606 /* 607 * Unbind the individual pages and flush the chipset's 608 * TLB. Unwire the pages so they can be swapped. 609 */ --- 9 unchanged lines hidden (view full) --- 619 VM_OBJECT_UNLOCK(mem->am_obj); 620 621 agp_flush_cache(); 622 AGP_FLUSH_TLB(dev); 623 624 mem->am_offset = 0; 625 mem->am_is_bound = 0; 626 | 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 |
627 lockmgr(&sc->as_lock, LK_RELEASE, 0, curthread); | 625 mtx_unlock(&sc->as_lock); |
628 629 return 0; 630} 631 632/* Helper functions for implementing user/kernel api */ 633 634static int 635agp_acquire_helper(device_t dev, enum agp_acquire_state state) --- 283 unchanged lines hidden --- | 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 --- |