Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+38 −70
Original line number Diff line number Diff line
@@ -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);