Commit 96ae6469 authored by Geliang Tang's avatar Geliang Tang Committed by Bjorn Helgaas

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: default avatarGeliang Tang <geliangtang@163.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 8e5a395a
......@@ -180,6 +180,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
unsigned long result = 0;
unsigned long flags;
unsigned long bx = (bus << 8) | devfn;
u16 number = 0, mask = 0;
WARN_ON(seg);
if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
......@@ -189,52 +190,34 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
switch (len) {
case 1:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"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;
number = PCIBIOS_READ_CONFIG_BYTE;
mask = 0xff;
break;
case 2:
number = PCIBIOS_READ_CONFIG_WORD;
mask = 0xffff;
break;
case 4:
number = PCIBIOS_READ_CONFIG_DWORD;
break;
}
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=c" (*value),
"=a" (result)
: "1" (PCIBIOS_READ_CONFIG_WORD),
: "1" (number),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
/*
* Zero-extend the result beyond 16 bits, do not trust the
* Zero-extend the result beyond 8 or 16 bits, do not trust the
* BIOS having done it:
*/
*value &= 0xffff;
break;
case 4:
__asm__("lcall *(%%esi); cld\n\t"
"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;
}
if (mask)
*value &= mask;
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
......@@ -247,6 +230,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
unsigned long result = 0;
unsigned long flags;
unsigned long bx = (bus << 8) | devfn;
u16 number = 0;
WARN_ON(seg);
if ((bus > 255) || (devfn > 255) || (reg > 255))
......@@ -256,42 +240,26 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
switch (len) {
case 1:
__asm__("lcall *(%%esi); cld\n\t"
"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));
number = PCIBIOS_WRITE_CONFIG_BYTE;
break;
case 2:
__asm__("lcall *(%%esi); cld\n\t"
"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));
number = PCIBIOS_WRITE_CONFIG_WORD;
break;
case 4:
number = PCIBIOS_WRITE_CONFIG_DWORD;
break;
}
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (result)
: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
: "0" (number),
"c" (value),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
break;
}
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment