diff options
Diffstat (limited to 'drivers/misc/sgi-xp/xp_sn2.c')
-rw-r--r-- | drivers/misc/sgi-xp/xp_sn2.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/misc/sgi-xp/xp_sn2.c b/drivers/misc/sgi-xp/xp_sn2.c index b92579356a64..3d553fa73f4d 100644 --- a/drivers/misc/sgi-xp/xp_sn2.c +++ b/drivers/misc/sgi-xp/xp_sn2.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <asm/sn/bte.h> | ||
16 | #include <asm/sn/sn_sal.h> | 17 | #include <asm/sn/sn_sal.h> |
17 | #include "xp.h" | 18 | #include "xp.h" |
18 | 19 | ||
@@ -72,6 +73,49 @@ xp_unregister_nofault_code_sn2(void) | |||
72 | err_func_addr, 1, 0); | 73 | err_func_addr, 1, 0); |
73 | } | 74 | } |
74 | 75 | ||
76 | /* | ||
77 | * Wrapper for bte_copy(). | ||
78 | * | ||
79 | * vdst - virtual address of the destination of the transfer. | ||
80 | * psrc - physical address of the source of the transfer. | ||
81 | * len - number of bytes to transfer from source to destination. | ||
82 | * | ||
83 | * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock. | ||
84 | */ | ||
85 | static enum xp_retval | ||
86 | xp_remote_memcpy_sn2(void *vdst, const void *psrc, size_t len) | ||
87 | { | ||
88 | bte_result_t ret; | ||
89 | u64 pdst = ia64_tpa(vdst); | ||
90 | /* >>> What are the rules governing the src and dst addresses passed in? | ||
91 | * >>> Currently we're assuming that dst is a virtual address and src | ||
92 | * >>> is a physical address, is this appropriate? Can we allow them to | ||
93 | * >>> be whatever and we make the change here without damaging the | ||
94 | * >>> addresses? | ||
95 | */ | ||
96 | |||
97 | /* | ||
98 | * Ensure that the physically mapped memory is contiguous. | ||
99 | * | ||
100 | * We do this by ensuring that the memory is from region 7 only. | ||
101 | * If the need should arise to use memory from one of the other | ||
102 | * regions, then modify the BUG_ON() statement to ensure that the | ||
103 | * memory from that region is always physically contiguous. | ||
104 | */ | ||
105 | BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL); | ||
106 | |||
107 | ret = bte_copy((u64)psrc, pdst, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
108 | if (ret == BTE_SUCCESS) | ||
109 | return xpSuccess; | ||
110 | |||
111 | if (is_shub2()) | ||
112 | dev_err(xp, "bte_copy() on shub2 failed, error=0x%x\n", ret); | ||
113 | else | ||
114 | dev_err(xp, "bte_copy() failed, error=%d\n", ret); | ||
115 | |||
116 | return xpBteCopyError; | ||
117 | } | ||
118 | |||
75 | enum xp_retval | 119 | enum xp_retval |
76 | xp_init_sn2(void) | 120 | xp_init_sn2(void) |
77 | { | 121 | { |
@@ -79,6 +123,8 @@ xp_init_sn2(void) | |||
79 | 123 | ||
80 | xp_max_npartitions = XP_MAX_NPARTITIONS_SN2; | 124 | xp_max_npartitions = XP_MAX_NPARTITIONS_SN2; |
81 | 125 | ||
126 | xp_remote_memcpy = xp_remote_memcpy_sn2; | ||
127 | |||
82 | return xp_register_nofault_code_sn2(); | 128 | return xp_register_nofault_code_sn2(); |
83 | } | 129 | } |
84 | 130 | ||