static int vtblk_detach(device_t dev) { struct vtblk_softc *sc; sc = device_get_softc(dev); VTBLK_LOCK(sc); sc->vtblk_flags |= VTBLK_FLAG_DETACH; if (device_is_attached(dev)) vtblk_stop(sc); VTBLK_UNLOCK(sc); if (sc->vtblk_tq != NULL) { taskqueue_drain(sc->vtblk_tq, &sc->vtblk_intr_task); taskqueue_free(sc->vtblk_tq); sc->vtblk_tq = NULL; } vtblk_drain(sc); if (sc->vtblk_disk != NULL) { disk_destroy(sc->vtblk_disk); sc->vtblk_disk = NULL; } if (sc->vtblk_sglist != NULL) { sglist_free(sc->vtblk_sglist); sc->vtblk_sglist = NULL; } VTBLK_LOCK_DESTROY(sc); return (0); }
static int vtblk_detach(device_t dev) { struct vtblk_softc *sc; sc = device_get_softc(dev); lwkt_serialize_enter(&sc->vtblk_slz); sc->vtblk_flags |= VTBLK_FLAG_DETACH; if (device_is_attached(dev)) vtblk_stop(sc); lwkt_serialize_exit(&sc->vtblk_slz); vtblk_drain(sc); if (sc->cdev != NULL) { disk_destroy(&sc->vtblk_disk); sc->cdev = NULL; } if (sc->vtblk_sglist != NULL) { sglist_free(sc->vtblk_sglist); sc->vtblk_sglist = NULL; } return (0); }
vm_object_t vmm_mmio_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, vm_paddr_t hpa) { int error; vm_object_t obj; struct sglist *sg; sg = sglist_alloc(1, M_WAITOK); error = sglist_append_phys(sg, hpa, len); KASSERT(error == 0, ("error %d appending physaddr to sglist", error)); obj = vm_pager_allocate(OBJT_SG, sg, len, VM_PROT_RW, 0, NULL); if (obj != NULL) { /* * VT-x ignores the MTRR settings when figuring out the * memory type for translations obtained through EPT. * * Therefore we explicitly force the pages provided by * this object to be mapped as uncacheable. */ VM_OBJECT_WLOCK(obj); error = vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); VM_OBJECT_WUNLOCK(obj); if (error != KERN_SUCCESS) { panic("vmm_mmio_alloc: vm_object_set_memattr error %d", error); } error = vm_map_find(&vmspace->vm_map, obj, 0, &gpa, len, 0, VMFS_NO_SPACE, VM_PROT_RW, VM_PROT_RW, 0); if (error != KERN_SUCCESS) { vm_object_deallocate(obj); obj = NULL; } } /* * Drop the reference on the sglist. * * If the scatter/gather object was successfully allocated then it * has incremented the reference count on the sglist. Dropping the * initial reference count ensures that the sglist will be freed * when the object is deallocated. * * If the object could not be allocated then we end up freeing the * sglist. */ sglist_free(sg); return (obj); }
static void sg_pager_dealloc(vm_object_t object) { struct sglist *sg; vm_page_t m; /* * Free up our fake pages. */ while ((m = TAILQ_FIRST(&object->un_pager.sgp.sgp_pglist)) != 0) { TAILQ_REMOVE(&object->un_pager.sgp.sgp_pglist, m, plinks.q); vm_page_putfake(m); } sg = object->handle; sglist_free(sg); }