aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/kernel/pci_iommu.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index bbf9990cd23..e54f829528c 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -132,12 +132,15 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
132{ 132{
133 unsigned long *ptes; 133 unsigned long *ptes;
134 long i, p, nent; 134 long i, p, nent;
135 int pass = 0;
135 136
136 /* Search forward for the first mask-aligned sequence of N free ptes */ 137 /* Search forward for the first mask-aligned sequence of N free ptes */
137 ptes = arena->ptes; 138 ptes = arena->ptes;
138 nent = arena->size >> PAGE_SHIFT; 139 nent = arena->size >> PAGE_SHIFT;
139 p = ALIGN(arena->next_entry, mask + 1); 140 p = ALIGN(arena->next_entry, mask + 1);
140 i = 0; 141 i = 0;
142
143again:
141 while (i < n && p+i < nent) { 144 while (i < n && p+i < nent) {
142 if (ptes[p+i]) 145 if (ptes[p+i])
143 p = ALIGN(p + i + 1, mask + 1), i = 0; 146 p = ALIGN(p + i + 1, mask + 1), i = 0;
@@ -146,19 +149,18 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
146 } 149 }
147 150
148 if (i < n) { 151 if (i < n) {
149 /* Reached the end. Flush the TLB and restart the 152 if (pass < 1) {
150 search from the beginning. */ 153 /*
151 alpha_mv.mv_pci_tbi(arena->hose, 0, -1); 154 * Reached the end. Flush the TLB and restart
152 155 * the search from the beginning.
153 p = 0, i = 0; 156 */
154 while (i < n && p+i < nent) { 157 alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
155 if (ptes[p+i]) 158
156 p = ALIGN(p + i + 1, mask + 1), i = 0; 159 pass++;
157 else 160 p = 0;
158 i = i + 1; 161 i = 0;
159 } 162 goto again;
160 163 } else
161 if (i < n)
162 return -1; 164 return -1;
163 } 165 }
164 166