diff options
| author | David S. Miller <davem@davemloft.net> | 2009-05-18 21:08:20 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-05-18 21:08:20 -0700 | 
| commit | bb803cfbecb03a0cf8dc7e1864f18dda6631af00 (patch) | |
| tree | 6c0989693bea6f50cfa5c6bb14f52ec19668def3 /arch/x86/mm/pageattr.c | |
| parent | 3878fb6fdbceecca20b15748f807340854220f06 (diff) | |
| parent | 511e11e396dc596825ce04d53d7f6d579404bc01 (diff) | |
| download | olio-linux-3.10-bb803cfbecb03a0cf8dc7e1864f18dda6631af00.tar.xz olio-linux-3.10-bb803cfbecb03a0cf8dc7e1864f18dda6631af00.zip  | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
	drivers/scsi/fcoe/fcoe.c
Diffstat (limited to 'arch/x86/mm/pageattr.c')
| -rw-r--r-- | arch/x86/mm/pageattr.c | 125 | 
1 files changed, 76 insertions, 49 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index d71e1b636ce..797f9f107cb 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -945,71 +945,94 @@ int _set_memory_uc(unsigned long addr, int numpages)  int set_memory_uc(unsigned long addr, int numpages)  { +	int ret; +  	/*  	 * for now UC MINUS. see comments in ioremap_nocache()  	 */ -	if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE, -			    _PAGE_CACHE_UC_MINUS, NULL)) -		return -EINVAL; +	ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE, +			    _PAGE_CACHE_UC_MINUS, NULL); +	if (ret) +		goto out_err; + +	ret = _set_memory_uc(addr, numpages); +	if (ret) +		goto out_free; -	return _set_memory_uc(addr, numpages); +	return 0; + +out_free: +	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); +out_err: +	return ret;  }  EXPORT_SYMBOL(set_memory_uc);  int set_memory_array_uc(unsigned long *addr, int addrinarray)  { -	unsigned long start; -	unsigned long end; -	int i; +	int i, j; +	int ret; +  	/*  	 * for now UC MINUS. see comments in ioremap_nocache()  	 */  	for (i = 0; i < addrinarray; i++) { -		start = __pa(addr[i]); -		for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) { -			if (end != __pa(addr[i + 1])) -				break; -			i++; -		} -		if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) -			goto out; +		ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE, +					_PAGE_CACHE_UC_MINUS, NULL); +		if (ret) +			goto out_free;  	} -	return change_page_attr_set(addr, addrinarray, +	ret = change_page_attr_set(addr, addrinarray,  				    __pgprot(_PAGE_CACHE_UC_MINUS), 1); -out: -	for (i = 0; i < addrinarray; i++) { -		unsigned long tmp = __pa(addr[i]); +	if (ret) +		goto out_free; -		if (tmp == start) -			break; -		for (end = tmp + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) { -			if (end != __pa(addr[i + 1])) -				break; -			i++; -		} -		free_memtype(tmp, end); -	} -	return -EINVAL; +	return 0; + +out_free: +	for (j = 0; j < i; j++) +		free_memtype(__pa(addr[j]), __pa(addr[j]) + PAGE_SIZE); + +	return ret;  }  EXPORT_SYMBOL(set_memory_array_uc);  int _set_memory_wc(unsigned long addr, int numpages)  { -	return change_page_attr_set(&addr, numpages, +	int ret; +	ret = change_page_attr_set(&addr, numpages, +				    __pgprot(_PAGE_CACHE_UC_MINUS), 0); + +	if (!ret) { +		ret = change_page_attr_set(&addr, numpages,  				    __pgprot(_PAGE_CACHE_WC), 0); +	} +	return ret;  }  int set_memory_wc(unsigned long addr, int numpages)  { +	int ret; +  	if (!pat_enabled)  		return set_memory_uc(addr, numpages); -	if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE, -		_PAGE_CACHE_WC, NULL)) -		return -EINVAL; +	ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE, +		_PAGE_CACHE_WC, NULL); +	if (ret) +		goto out_err; + +	ret = _set_memory_wc(addr, numpages); +	if (ret) +		goto out_free; + +	return 0; -	return _set_memory_wc(addr, numpages); +out_free: +	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); +out_err: +	return ret;  }  EXPORT_SYMBOL(set_memory_wc); @@ -1021,29 +1044,31 @@ int _set_memory_wb(unsigned long addr, int numpages)  int set_memory_wb(unsigned long addr, int numpages)  { -	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); +	int ret; + +	ret = _set_memory_wb(addr, numpages); +	if (ret) +		return ret; -	return _set_memory_wb(addr, numpages); +	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE); +	return 0;  }  EXPORT_SYMBOL(set_memory_wb);  int set_memory_array_wb(unsigned long *addr, int addrinarray)  {  	int i; +	int ret; -	for (i = 0; i < addrinarray; i++) { -		unsigned long start = __pa(addr[i]); -		unsigned long end; - -		for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) { -			if (end != __pa(addr[i + 1])) -				break; -			i++; -		} -		free_memtype(start, end); -	} -	return change_page_attr_clear(addr, addrinarray, +	ret = change_page_attr_clear(addr, addrinarray,  				      __pgprot(_PAGE_CACHE_MASK), 1); +	if (ret) +		return ret; + +	for (i = 0; i < addrinarray; i++) +		free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE); + +	return 0;  }  EXPORT_SYMBOL(set_memory_array_wb); @@ -1136,6 +1161,8 @@ int set_pages_array_wb(struct page **pages, int addrinarray)  	retval = cpa_clear_pages_array(pages, addrinarray,  			__pgprot(_PAGE_CACHE_MASK)); +	if (retval) +		return retval;  	for (i = 0; i < addrinarray; i++) {  		start = (unsigned long)page_address(pages[i]); @@ -1143,7 +1170,7 @@ int set_pages_array_wb(struct page **pages, int addrinarray)  		free_memtype(start, end);  	} -	return retval; +	return 0;  }  EXPORT_SYMBOL(set_pages_array_wb);  |