forked from Minki/linux
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>
This commit is contained in:
parent
8e5a395a04
commit
96ae6469ba
@ -180,6 +180,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
|
|||||||
unsigned long result = 0;
|
unsigned long result = 0;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long bx = (bus << 8) | devfn;
|
unsigned long bx = (bus << 8) | devfn;
|
||||||
|
u16 number = 0, mask = 0;
|
||||||
|
|
||||||
WARN_ON(seg);
|
WARN_ON(seg);
|
||||||
if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
|
if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
|
||||||
@ -189,53 +190,35 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
|
|||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 1:
|
case 1:
|
||||||
__asm__("lcall *(%%esi); cld\n\t"
|
number = PCIBIOS_READ_CONFIG_BYTE;
|
||||||
"jc 1f\n\t"
|
mask = 0xff;
|
||||||
"xor %%ah, %%ah\n"
|
|
||||||
"1:"
|
|
||||||
: "=c" (*value),
|
|
||||||
"=a" (result)
|
|
||||||
: "1" (PCIBIOS_READ_CONFIG_BYTE),
|
|
||||||
"b" (bx),
|
|
||||||
"D" ((long)reg),
|
|
||||||
"S" (&pci_indirect));
|
|
||||||
/*
|
|
||||||
* Zero-extend the result beyond 8 bits, do not trust the
|
|
||||||
* BIOS having done it:
|
|
||||||
*/
|
|
||||||
*value &= 0xff;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
__asm__("lcall *(%%esi); cld\n\t"
|
number = PCIBIOS_READ_CONFIG_WORD;
|
||||||
"jc 1f\n\t"
|
mask = 0xffff;
|
||||||
"xor %%ah, %%ah\n"
|
|
||||||
"1:"
|
|
||||||
: "=c" (*value),
|
|
||||||
"=a" (result)
|
|
||||||
: "1" (PCIBIOS_READ_CONFIG_WORD),
|
|
||||||
"b" (bx),
|
|
||||||
"D" ((long)reg),
|
|
||||||
"S" (&pci_indirect));
|
|
||||||
/*
|
|
||||||
* Zero-extend the result beyond 16 bits, do not trust the
|
|
||||||
* BIOS having done it:
|
|
||||||
*/
|
|
||||||
*value &= 0xffff;
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
__asm__("lcall *(%%esi); cld\n\t"
|
number = PCIBIOS_READ_CONFIG_DWORD;
|
||||||
"jc 1f\n\t"
|
|
||||||
"xor %%ah, %%ah\n"
|
|
||||||
"1:"
|
|
||||||
: "=c" (*value),
|
|
||||||
"=a" (result)
|
|
||||||
: "1" (PCIBIOS_READ_CONFIG_DWORD),
|
|
||||||
"b" (bx),
|
|
||||||
"D" ((long)reg),
|
|
||||||
"S" (&pci_indirect));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__asm__("lcall *(%%esi); cld\n\t"
|
||||||
|
"jc 1f\n\t"
|
||||||
|
"xor %%ah, %%ah\n"
|
||||||
|
"1:"
|
||||||
|
: "=c" (*value),
|
||||||
|
"=a" (result)
|
||||||
|
: "1" (number),
|
||||||
|
"b" (bx),
|
||||||
|
"D" ((long)reg),
|
||||||
|
"S" (&pci_indirect));
|
||||||
|
/*
|
||||||
|
* Zero-extend the result beyond 8 or 16 bits, do not trust the
|
||||||
|
* BIOS having done it:
|
||||||
|
*/
|
||||||
|
if (mask)
|
||||||
|
*value &= mask;
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
||||||
|
|
||||||
return (int)((result & 0xff00) >> 8);
|
return (int)((result & 0xff00) >> 8);
|
||||||
@ -247,6 +230,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
|
|||||||
unsigned long result = 0;
|
unsigned long result = 0;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long bx = (bus << 8) | devfn;
|
unsigned long bx = (bus << 8) | devfn;
|
||||||
|
u16 number = 0;
|
||||||
|
|
||||||
WARN_ON(seg);
|
WARN_ON(seg);
|
||||||
if ((bus > 255) || (devfn > 255) || (reg > 255))
|
if ((bus > 255) || (devfn > 255) || (reg > 255))
|
||||||
@ -256,43 +240,27 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
|
|||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 1:
|
case 1:
|
||||||
__asm__("lcall *(%%esi); cld\n\t"
|
number = PCIBIOS_WRITE_CONFIG_BYTE;
|
||||||
"jc 1f\n\t"
|
|
||||||
"xor %%ah, %%ah\n"
|
|
||||||
"1:"
|
|
||||||
: "=a" (result)
|
|
||||||
: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
|
|
||||||
"c" (value),
|
|
||||||
"b" (bx),
|
|
||||||
"D" ((long)reg),
|
|
||||||
"S" (&pci_indirect));
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
__asm__("lcall *(%%esi); cld\n\t"
|
number = PCIBIOS_WRITE_CONFIG_WORD;
|
||||||
"jc 1f\n\t"
|
|
||||||
"xor %%ah, %%ah\n"
|
|
||||||
"1:"
|
|
||||||
: "=a" (result)
|
|
||||||
: "0" (PCIBIOS_WRITE_CONFIG_WORD),
|
|
||||||
"c" (value),
|
|
||||||
"b" (bx),
|
|
||||||
"D" ((long)reg),
|
|
||||||
"S" (&pci_indirect));
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
__asm__("lcall *(%%esi); cld\n\t"
|
number = PCIBIOS_WRITE_CONFIG_DWORD;
|
||||||
"jc 1f\n\t"
|
|
||||||
"xor %%ah, %%ah\n"
|
|
||||||
"1:"
|
|
||||||
: "=a" (result)
|
|
||||||
: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
|
|
||||||
"c" (value),
|
|
||||||
"b" (bx),
|
|
||||||
"D" ((long)reg),
|
|
||||||
"S" (&pci_indirect));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__asm__("lcall *(%%esi); cld\n\t"
|
||||||
|
"jc 1f\n\t"
|
||||||
|
"xor %%ah, %%ah\n"
|
||||||
|
"1:"
|
||||||
|
: "=a" (result)
|
||||||
|
: "0" (number),
|
||||||
|
"c" (value),
|
||||||
|
"b" (bx),
|
||||||
|
"D" ((long)reg),
|
||||||
|
"S" (&pci_indirect));
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
||||||
|
|
||||||
return (int)((result & 0xff00) >> 8);
|
return (int)((result & 0xff00) >> 8);
|
||||||
|
Loading…
Reference in New Issue
Block a user