/* * mspec_close * * Called when unmapping a device mapping. Frees all mspec pages * belonging to all the vma's sharing this vma_data structure. */ static void mspec_close(struct vm_area_struct *vma) { struct vma_data *vdata; int index, last_index; unsigned long my_page; vdata = vma->vm_private_data; if (!atomic_dec_and_test(&vdata->refcnt)) return; last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT; for (index = 0; index < last_index; index++) { if (vdata->maddr[index] == 0) continue; /* * Clear the page before sticking it back * into the pool. */ my_page = vdata->maddr[index]; vdata->maddr[index] = 0; if (!mspec_zero_block(my_page, PAGE_SIZE)) uncached_free_page(my_page, 1); else printk(KERN_WARNING "mspec_close(): " "failed to zero page %ld\n", my_page); } kvfree(vdata); }
/* * mspec_close * * Called when unmapping a device mapping. Frees all mspec pages * belonging to the vma. */ static void mspec_close(struct vm_area_struct *vma) { struct vma_data *vdata; int i, pages, result, vdata_size; vdata = vma->vm_private_data; if (!atomic_dec_and_test(&vdata->refcnt)) return; pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; vdata_size = sizeof(struct vma_data) + pages * sizeof(long); for (i = 0; i < pages; i++) { if (vdata->maddr[i] == 0) continue; /* * Clear the page before sticking it back * into the pool. */ result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE); if (!result) uncached_free_page(vdata->maddr[i]); else printk(KERN_WARNING "mspec_close(): " "failed to zero page %i\n", result); } if (vdata_size <= PAGE_SIZE) kfree(vdata); else vfree(vdata); }