static int check_pages_physically_contiguous(unsigned long pfn, unsigned int offset, size_t length) { unsigned long next_bfn; int i; int nr_pages; next_bfn = pfn_to_bfn(pfn); nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT; for (i = 1; i < nr_pages; i++) { if (pfn_to_bfn(++pfn) != ++next_bfn) return 0; } return 1; }
bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, const struct bio_vec *vec2) { #if XEN_PAGE_SIZE == PAGE_SIZE unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page)); unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page)); return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && ((bfn1 == bfn2) || ((bfn1+1) == bfn2)); #else /* * XXX: Add support for merging bio_vec when using different page * size in Xen and Linux. */ return 0; #endif }
/* * Both of these functions should avoid PFN_PHYS because phys_addr_t * can be 32bit when dma_addr_t is 64bit leading to a loss in * information if the shift is done before casting to 64bit. */ static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr) { unsigned long bfn = pfn_to_bfn(PFN_DOWN(paddr)); dma_addr_t dma = (dma_addr_t)bfn << PAGE_SHIFT; dma |= paddr & ~PAGE_MASK; return dma; }