agp.c (d9a447559bc04121f7c6682e64abe67efa154864) | agp.c (89f6b8632cc94bca2738b4fcc26e1189ef4f5dde) |
---|---|
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 --- 27 unchanged lines hidden (view full) --- 36#include <sys/module.h> 37#include <sys/bus.h> 38#include <sys/conf.h> 39#include <sys/ioccom.h> 40#include <sys/agpio.h> 41#include <sys/lock.h> 42#include <sys/mutex.h> 43#include <sys/proc.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 --- 27 unchanged lines hidden (view full) --- 36#include <sys/module.h> 37#include <sys/bus.h> 38#include <sys/conf.h> 39#include <sys/ioccom.h> 40#include <sys/agpio.h> 41#include <sys/lock.h> 42#include <sys/mutex.h> 43#include <sys/proc.h> |
44#include <sys/rwlock.h> |
|
44 45#include <dev/agp/agppriv.h> 46#include <dev/agp/agpvar.h> 47#include <dev/agp/agpreg.h> 48#include <dev/pci/pcivar.h> 49#include <dev/pci/pcireg.h> 50 51#include <vm/vm.h> --- 487 unchanged lines hidden (view full) --- 539 return EINVAL; 540 } 541 542 /* 543 * Allocate the pages early, before acquiring the lock, 544 * because vm_page_grab() may sleep and we can't hold a mutex 545 * while sleeping. 546 */ | 45 46#include <dev/agp/agppriv.h> 47#include <dev/agp/agpvar.h> 48#include <dev/agp/agpreg.h> 49#include <dev/pci/pcivar.h> 50#include <dev/pci/pcireg.h> 51 52#include <vm/vm.h> --- 487 unchanged lines hidden (view full) --- 540 return EINVAL; 541 } 542 543 /* 544 * Allocate the pages early, before acquiring the lock, 545 * because vm_page_grab() may sleep and we can't hold a mutex 546 * while sleeping. 547 */ |
547 VM_OBJECT_LOCK(mem->am_obj); | 548 VM_OBJECT_WLOCK(mem->am_obj); |
548 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 549 /* 550 * Find a page from the object and wire it 551 * down. This page will be mapped using one or more 552 * entries in the GATT (assuming that PAGE_SIZE >= 553 * AGP_PAGE_SIZE. If this is the first call to bind, 554 * the pages will be allocated and zeroed. 555 */ 556 m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i), 557 VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); 558 AGP_DPF("found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m)); 559 } | 549 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 550 /* 551 * Find a page from the object and wire it 552 * down. This page will be mapped using one or more 553 * entries in the GATT (assuming that PAGE_SIZE >= 554 * AGP_PAGE_SIZE. If this is the first call to bind, 555 * the pages will be allocated and zeroed. 556 */ 557 m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i), 558 VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); 559 AGP_DPF("found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m)); 560 } |
560 VM_OBJECT_UNLOCK(mem->am_obj); | 561 VM_OBJECT_WUNLOCK(mem->am_obj); |
561 562 mtx_lock(&sc->as_lock); 563 564 if (mem->am_is_bound) { 565 device_printf(dev, "memory already bound\n"); 566 error = EINVAL; | 562 563 mtx_lock(&sc->as_lock); 564 565 if (mem->am_is_bound) { 566 device_printf(dev, "memory already bound\n"); 567 error = EINVAL; |
567 VM_OBJECT_LOCK(mem->am_obj); | 568 VM_OBJECT_WLOCK(mem->am_obj); |
568 i = 0; 569 goto bad; 570 } 571 572 /* 573 * Bind the individual pages and flush the chipset's 574 * TLB. 575 */ | 569 i = 0; 570 goto bad; 571 } 572 573 /* 574 * Bind the individual pages and flush the chipset's 575 * TLB. 576 */ |
576 VM_OBJECT_LOCK(mem->am_obj); | 577 VM_OBJECT_WLOCK(mem->am_obj); |
577 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 578 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i)); 579 580 /* 581 * Install entries in the GATT, making sure that if 582 * AGP_PAGE_SIZE < PAGE_SIZE and mem->am_size is not 583 * aligned to PAGE_SIZE, we don't modify too many GATT 584 * entries. --- 11 unchanged lines hidden (view full) --- 596 */ 597 for (k = 0; k < i + j; k += AGP_PAGE_SIZE) 598 AGP_UNBIND_PAGE(dev, offset + k); 599 goto bad; 600 } 601 } 602 vm_page_wakeup(m); 603 } | 578 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 579 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i)); 580 581 /* 582 * Install entries in the GATT, making sure that if 583 * AGP_PAGE_SIZE < PAGE_SIZE and mem->am_size is not 584 * aligned to PAGE_SIZE, we don't modify too many GATT 585 * entries. --- 11 unchanged lines hidden (view full) --- 597 */ 598 for (k = 0; k < i + j; k += AGP_PAGE_SIZE) 599 AGP_UNBIND_PAGE(dev, offset + k); 600 goto bad; 601 } 602 } 603 vm_page_wakeup(m); 604 } |
604 VM_OBJECT_UNLOCK(mem->am_obj); | 605 VM_OBJECT_WUNLOCK(mem->am_obj); |
605 606 /* 607 * Flush the cpu cache since we are providing a new mapping 608 * for these pages. 609 */ 610 agp_flush_cache(); 611 612 /* --- 4 unchanged lines hidden (view full) --- 617 mem->am_offset = offset; 618 mem->am_is_bound = 1; 619 620 mtx_unlock(&sc->as_lock); 621 622 return 0; 623bad: 624 mtx_unlock(&sc->as_lock); | 606 607 /* 608 * Flush the cpu cache since we are providing a new mapping 609 * for these pages. 610 */ 611 agp_flush_cache(); 612 613 /* --- 4 unchanged lines hidden (view full) --- 618 mem->am_offset = offset; 619 mem->am_is_bound = 1; 620 621 mtx_unlock(&sc->as_lock); 622 623 return 0; 624bad: 625 mtx_unlock(&sc->as_lock); |
625 VM_OBJECT_LOCK_ASSERT(mem->am_obj, MA_OWNED); | 626 VM_OBJECT_ASSERT_WLOCKED(mem->am_obj); |
626 for (k = 0; k < mem->am_size; k += PAGE_SIZE) { 627 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(k)); 628 if (k >= i) 629 vm_page_wakeup(m); 630 vm_page_lock(m); 631 vm_page_unwire(m, 0); 632 vm_page_unlock(m); 633 } | 627 for (k = 0; k < mem->am_size; k += PAGE_SIZE) { 628 m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(k)); 629 if (k >= i) 630 vm_page_wakeup(m); 631 vm_page_lock(m); 632 vm_page_unwire(m, 0); 633 vm_page_unlock(m); 634 } |
634 VM_OBJECT_UNLOCK(mem->am_obj); | 635 VM_OBJECT_WUNLOCK(mem->am_obj); |
635 636 return error; 637} 638 639int 640agp_generic_unbind_memory(device_t dev, struct agp_memory *mem) 641{ 642 struct agp_softc *sc = device_get_softc(dev); --- 10 unchanged lines hidden (view full) --- 653 654 655 /* 656 * Unbind the individual pages and flush the chipset's 657 * TLB. Unwire the pages so they can be swapped. 658 */ 659 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 660 AGP_UNBIND_PAGE(dev, mem->am_offset + i); | 636 637 return error; 638} 639 640int 641agp_generic_unbind_memory(device_t dev, struct agp_memory *mem) 642{ 643 struct agp_softc *sc = device_get_softc(dev); --- 10 unchanged lines hidden (view full) --- 654 655 656 /* 657 * Unbind the individual pages and flush the chipset's 658 * TLB. Unwire the pages so they can be swapped. 659 */ 660 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) 661 AGP_UNBIND_PAGE(dev, mem->am_offset + i); |
661 VM_OBJECT_LOCK(mem->am_obj); | 662 VM_OBJECT_WLOCK(mem->am_obj); |
662 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 663 m = vm_page_lookup(mem->am_obj, atop(i)); 664 vm_page_lock(m); 665 vm_page_unwire(m, 0); 666 vm_page_unlock(m); 667 } | 663 for (i = 0; i < mem->am_size; i += PAGE_SIZE) { 664 m = vm_page_lookup(mem->am_obj, atop(i)); 665 vm_page_lock(m); 666 vm_page_unwire(m, 0); 667 vm_page_unlock(m); 668 } |
668 VM_OBJECT_UNLOCK(mem->am_obj); | 669 VM_OBJECT_WUNLOCK(mem->am_obj); |
669 670 agp_flush_cache(); 671 AGP_FLUSH_TLB(dev); 672 673 mem->am_offset = 0; 674 mem->am_is_bound = 0; 675 676 mtx_unlock(&sc->as_lock); --- 321 unchanged lines hidden --- | 670 671 agp_flush_cache(); 672 AGP_FLUSH_TLB(dev); 673 674 mem->am_offset = 0; 675 mem->am_is_bound = 0; 676 677 mtx_unlock(&sc->as_lock); --- 321 unchanged lines hidden --- |