diff options
author | Geliang Tang <geliangtang@163.com> | 2015-12-07 09:24:24 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2015-12-10 20:38:07 -0500 |
commit | 96ae6469ba16ae502d2b2db4b5c9b7c846262999 (patch) | |
tree | 2b293b96b1a753e9070eccbafc012777c58fc4d4 | |
parent | 8e5a395a040a7c72ec283f844eca679b924f5f01 (diff) |
x86/PCI: Simplify pci_bios_{read,write}
There is some repetitive code in the switch/case statements in
pci_bios_read() and pci_bios_write(). Factor out the BIOS function
IDs and the result widths to simplify the code.
Signed-off-by: Geliang Tang <geliangtang@163.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/pci/pcbios.c | 108 |
1 files changed, 38 insertions, 70 deletions
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 9b83b9051ae7..9770e55e768f 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c | |||
@@ -180,6 +180,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, | |||
180 | unsigned long result = 0; | 180 | unsigned long result = 0; |
181 | unsigned long flags; | 181 | unsigned long flags; |
182 | unsigned long bx = (bus << 8) | devfn; | 182 | unsigned long bx = (bus << 8) | devfn; |
183 | u16 number = 0, mask = 0; | ||
183 | 184 | ||
184 | WARN_ON(seg); | 185 | WARN_ON(seg); |
185 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) | 186 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) |
@@ -189,53 +190,35 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, | |||
189 | 190 | ||
190 | switch (len) { | 191 | switch (len) { |
191 | case 1: | 192 | case 1: |
192 | __asm__("lcall *(%%esi); cld\n\t" | 193 | number = PCIBIOS_READ_CONFIG_BYTE; |
193 | "jc 1f\n\t" | 194 | mask = 0xff; |
194 | "xor %%ah, %%ah\n" | ||
195 | "1:" | ||
196 | : "=c" (*value), | ||
197 | "=a" (result) | ||
198 | : "1" (PCIBIOS_READ_CONFIG_BYTE), | ||
199 | "b" (bx), | ||
200 | "D" ((long)reg), | ||
201 | "S" (&pci_indirect)); | ||
202 | /* | ||
203 | * Zero-extend the result beyond 8 bits, do not trust the | ||
204 | * BIOS having done it: | ||
205 | */ | ||
206 | *value &= 0xff; | ||
207 | break; | 195 | break; |
208 | case 2: | 196 | case 2: |
209 | __asm__("lcall *(%%esi); cld\n\t" | 197 | number = PCIBIOS_READ_CONFIG_WORD; |
210 | "jc 1f\n\t" | 198 | mask = 0xffff; |
211 | "xor %%ah, %%ah\n" | ||
212 | "1:" | ||
213 | : "=c" (*value), | ||
214 | "=a" (result) | ||
215 | : "1" (PCIBIOS_READ_CONFIG_WORD), | ||
216 | "b" (bx), | ||
217 | "D" ((long)reg), | ||
218 | "S" (&pci_indirect)); | ||
219 | /* | ||
220 | * Zero-extend the result beyond 16 bits, do not trust the | ||
221 | * BIOS having done it: | ||
222 | */ | ||
223 | *value &= 0xffff; | ||
224 | break; | 199 | break; |
225 | case 4: | 200 | case 4: |
226 | __asm__("lcall *(%%esi); cld\n\t" | 201 | number = PCIBIOS_READ_CONFIG_DWORD; |
227 | "jc 1f\n\t" | ||
228 | "xor %%ah, %%ah\n" | ||
229 | "1:" | ||
230 | : "=c" (*value), | ||
231 | "=a" (result) | ||
232 | : "1" (PCIBIOS_READ_CONFIG_DWORD), | ||
233 | "b" (bx), | ||
234 | "D" ((long)reg), | ||
235 | "S" (&pci_indirect)); | ||
236 | break; | 202 | break; |
237 | } | 203 | } |
238 | 204 | ||
205 | __asm__("lcall *(%%esi); cld\n\t" | ||
206 | "jc 1f\n\t" | ||
207 | "xor %%ah, %%ah\n" | ||
208 | "1:" | ||
209 | : "=c" (*value), | ||
210 | "=a" (result) | ||
211 | : "1" (number), | ||
212 | "b" (bx), | ||
213 | "D" ((long)reg), | ||
214 | "S" (&pci_indirect)); | ||
215 | /* | ||
216 | * Zero-extend the result beyond 8 or 16 bits, do not trust the | ||
217 | * BIOS having done it: | ||
218 | */ | ||
219 | if (mask) | ||
220 | *value &= mask; | ||
221 | |||
239 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | 222 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
240 | 223 | ||
241 | return (int)((result & 0xff00) >> 8); | 224 | return (int)((result & 0xff00) >> 8); |
@@ -247,6 +230,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, | |||
247 | unsigned long result = 0; | 230 | unsigned long result = 0; |
248 | unsigned long flags; | 231 | unsigned long flags; |
249 | unsigned long bx = (bus << 8) | devfn; | 232 | unsigned long bx = (bus << 8) | devfn; |
233 | u16 number = 0; | ||
250 | 234 | ||
251 | WARN_ON(seg); | 235 | WARN_ON(seg); |
252 | if ((bus > 255) || (devfn > 255) || (reg > 255)) | 236 | if ((bus > 255) || (devfn > 255) || (reg > 255)) |
@@ -256,43 +240,27 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, | |||
256 | 240 | ||
257 | switch (len) { | 241 | switch (len) { |
258 | case 1: | 242 | case 1: |
259 | __asm__("lcall *(%%esi); cld\n\t" | 243 | number = PCIBIOS_WRITE_CONFIG_BYTE; |
260 | "jc 1f\n\t" | ||
261 | "xor %%ah, %%ah\n" | ||
262 | "1:" | ||
263 | : "=a" (result) | ||
264 | : "0" (PCIBIOS_WRITE_CONFIG_BYTE), | ||
265 | "c" (value), | ||
266 | "b" (bx), | ||
267 | "D" ((long)reg), | ||
268 | "S" (&pci_indirect)); | ||
269 | break; | 244 | break; |
270 | case 2: | 245 | case 2: |
271 | __asm__("lcall *(%%esi); cld\n\t" | 246 | number = PCIBIOS_WRITE_CONFIG_WORD; |
272 | "jc 1f\n\t" | ||
273 | "xor %%ah, %%ah\n" | ||
274 | "1:" | ||
275 | : "=a" (result) | ||
276 | : "0" (PCIBIOS_WRITE_CONFIG_WORD), | ||
277 | "c" (value), | ||
278 | "b" (bx), | ||
279 | "D" ((long)reg), | ||
280 | "S" (&pci_indirect)); | ||
281 | break; | 247 | break; |
282 | case 4: | 248 | case 4: |
283 | __asm__("lcall *(%%esi); cld\n\t" | 249 | number = PCIBIOS_WRITE_CONFIG_DWORD; |
284 | "jc 1f\n\t" | ||
285 | "xor %%ah, %%ah\n" | ||
286 | "1:" | ||
287 | : "=a" (result) | ||
288 | : "0" (PCIBIOS_WRITE_CONFIG_DWORD), | ||
289 | "c" (value), | ||
290 | "b" (bx), | ||
291 | "D" ((long)reg), | ||
292 | "S" (&pci_indirect)); | ||
293 | break; | 250 | break; |
294 | } | 251 | } |
295 | 252 | ||
253 | __asm__("lcall *(%%esi); cld\n\t" | ||
254 | "jc 1f\n\t" | ||
255 | "xor %%ah, %%ah\n" | ||
256 | "1:" | ||
257 | : "=a" (result) | ||
258 | : "0" (number), | ||
259 | "c" (value), | ||
260 | "b" (bx), | ||
261 | "D" ((long)reg), | ||
262 | "S" (&pci_indirect)); | ||
263 | |||
296 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | 264 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
297 | 265 | ||
298 | return (int)((result & 0xff00) >> 8); | 266 | return (int)((result & 0xff00) >> 8); |