static void via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) { struct page *page; int i; switch(vsg->state) { case dr_via_device_mapped: via_unmap_blit_from_device(pdev, vsg); case dr_via_desc_pages_alloc: for (i=0; i<vsg->num_desc_pages; ++i) { if (vsg->desc_pages[i] != NULL) free_page((unsigned long)vsg->desc_pages[i]); } kfree(vsg->desc_pages); case dr_via_pages_locked: for (i=0; i<vsg->num_pages; ++i) { if ( NULL != (page = vsg->pages[i])) { if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) SetPageDirty(page); page_cache_release(page); } } case dr_via_pages_alloc: vfree(vsg->pages); default: vsg->state = dr_via_sg_init; } if (vsg->bounce_buffer) { vfree(vsg->bounce_buffer); vsg->bounce_buffer = NULL; } vsg->free_on_sequence = 0; }
/* * Function that frees up all resources for a blit. It is usable even if the * blit info has only been partially built as long as the status enum is consistent * with the actual status of the used resources. */ static void via_free_sg_info(drm_via_sg_info_t *vsg) { vm_page_t page; int i; switch(vsg->state) { case dr_via_device_mapped: via_unmap_blit_from_device(vsg); case dr_via_desc_pages_alloc: for (i=0; i<vsg->num_desc_pages; ++i) { if (vsg->desc_pages[i] != NULL) free(vsg->desc_pages[i], DRM_MEM_PAGES); } free(vsg->desc_pages, DRM_MEM_DRIVER); case dr_via_pages_locked: for (i=0; i < vsg->num_pages; ++i) { page = vsg->pages[i]; vm_page_lock(page); vm_page_unwire(page, 0); vm_page_unlock(page); } case dr_via_pages_alloc: free(vsg->pages, DRM_MEM_DRIVER); default: vsg->state = dr_via_sg_init; } free(vsg->bounce_buffer, DRM_MEM_DRIVER); vsg->bounce_buffer = NULL; vsg->free_on_sequence = 0; }