ia64/xen-unstable

changeset 10339:2db7b3627da4

[LINUX] swiotlb allocates multiple smaller contiguous DMA regions,
rather than a single big one.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Jun 08 16:48:23 2006 +0100 (2006-06-08)
parents a1b83fedc4ed
children 4f1e39ec05d6
files linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Thu Jun 08 11:35:27 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Thu Jun 08 16:48:23 2006 +0100
     1.3 @@ -47,6 +47,9 @@ EXPORT_SYMBOL(swiotlb);
     1.4   */
     1.5  #define IO_TLB_SHIFT 11
     1.6  
     1.7 +/* Width of DMA addresses in the IO TLB. 31 bits is an aacraid limitation. */
     1.8 +#define IO_TLB_DMA_BITS 31
     1.9 +
    1.10  static int swiotlb_force;
    1.11  static char *iotlb_virt_start;
    1.12  static unsigned long iotlb_nslabs;
    1.13 @@ -56,10 +59,16 @@ static unsigned long iotlb_nslabs;
    1.14   * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
    1.15   * API.
    1.16   */
    1.17 -static dma_addr_t iotlb_bus_start, iotlb_bus_end, iotlb_bus_mask;
    1.18 +static unsigned long iotlb_pfn_start, iotlb_pfn_end;
    1.19  
    1.20  /* Does the given dma address reside within the swiotlb aperture? */
    1.21 -#define in_swiotlb_aperture(a) (!(((a) ^ iotlb_bus_start) & iotlb_bus_mask))
    1.22 +static inline int in_swiotlb_aperture(dma_addr_t dev_addr)
    1.23 +{
    1.24 +	unsigned long pfn = mfn_to_local_pfn(dev_addr >> PAGE_SHIFT);
    1.25 +	return (pfn_valid(pfn)
    1.26 +		&& (pfn >= iotlb_pfn_start)
    1.27 +		&& (pfn < iotlb_pfn_end));
    1.28 +}
    1.29  
    1.30  /*
    1.31   * When the IOMMU overflows we return a fallback buffer. This sets the size.
    1.32 @@ -125,7 +134,6 @@ void
    1.33  swiotlb_init_with_default_size (size_t default_size)
    1.34  {
    1.35  	unsigned long i, bytes;
    1.36 -	int rc;
    1.37  
    1.38  	if (!iotlb_nslabs) {
    1.39  		iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
    1.40 @@ -146,10 +154,13 @@ swiotlb_init_with_default_size (size_t d
    1.41  		      "Use dom0_mem Xen boot parameter to reserve\n"
    1.42  		      "some DMA memory (e.g., dom0_mem=-128M).\n");
    1.43  
    1.44 -	/* Hardcode 31 address bits for now: aacraid limitation. */
    1.45 -	rc = xen_create_contiguous_region(
    1.46 -		(unsigned long)iotlb_virt_start, get_order(bytes), 31);
    1.47 -	BUG_ON(rc);
    1.48 +	for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
    1.49 +		int rc = xen_create_contiguous_region(
    1.50 +			(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
    1.51 +			get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
    1.52 +			IO_TLB_DMA_BITS);
    1.53 +		BUG_ON(rc);
    1.54 +	}
    1.55  
    1.56  	/*
    1.57  	 * Allocate and initialize the free list array.  This array is used
    1.58 @@ -167,17 +178,13 @@ swiotlb_init_with_default_size (size_t d
    1.59  	 */
    1.60  	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
    1.61  
    1.62 -	iotlb_bus_start = virt_to_bus(iotlb_virt_start);
    1.63 -	iotlb_bus_end   = iotlb_bus_start + bytes;
    1.64 -	iotlb_bus_mask  = ~(dma_addr_t)(bytes - 1);
    1.65 +	iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
    1.66 +	iotlb_pfn_end   = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
    1.67  
    1.68  	printk(KERN_INFO "Software IO TLB enabled: \n"
    1.69  	       " Aperture:     %lu megabytes\n"
    1.70 -	       " Bus range:    0x%016lx - 0x%016lx\n"
    1.71  	       " Kernel range: 0x%016lx - 0x%016lx\n",
    1.72  	       bytes >> 20,
    1.73 -	       (unsigned long)iotlb_bus_start,
    1.74 -	       (unsigned long)iotlb_bus_end,
    1.75  	       (unsigned long)iotlb_virt_start,
    1.76  	       (unsigned long)iotlb_virt_start + bytes);
    1.77  }
    1.78 @@ -647,7 +654,7 @@ swiotlb_dma_mapping_error(dma_addr_t dma
    1.79  int
    1.80  swiotlb_dma_supported (struct device *hwdev, u64 mask)
    1.81  {
    1.82 -	return (mask >= (iotlb_bus_end - 1));
    1.83 +	return (mask >= ((1UL << IO_TLB_DMA_BITS) - 1));
    1.84  }
    1.85  
    1.86  EXPORT_SYMBOL(swiotlb_init);