arch/x86/pci/olpc.c

Source file repositories/reference/linux-study-clean/arch/x86/pci/olpc.c

File Facts

System
Linux kernel
Corpus path
arch/x86/pci/olpc.c
Extension
.c
Size
9329 bytes
Lines
309
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (devfn) {
		case  0x8:
			addr = hdr_addr(is_lx ? lxnb_hdr : gxnb_hdr, reg);
			break;
		case  0x9:
			addr = hdr_addr(is_lx ? lxfb_hdr : gxfb_hdr, reg);
			break;
		case  0xa:
			addr = is_lx ? hdr_addr(aes_hdr, reg) : &ff_loc;
			break;
		case 0x78:
			addr = hdr_addr(isa_hdr, reg);
			break;
		case 0x7b:
			addr = hdr_addr(ac97_hdr, reg);
			break;
		case 0x7c:
			addr = hdr_addr(ohci_hdr, reg);
			break;
		case 0x7d:
			addr = hdr_addr(ehci_hdr, reg);
			break;
		default:
			addr = &ff_loc;
			break;
		}
	}
	switch (len) {
	case 1:
		*value = *(uint8_t *)addr;
		break;
	case 2:
		*value = *(uint16_t *)addr;
		break;
	case 4:
		*value = *addr;
		break;
	default:
		BUG();
	}

	return 0;
}

static int pci_olpc_write(unsigned int seg, unsigned int bus,
		unsigned int devfn, int reg, int len, uint32_t value)
{
	WARN_ON(seg);

	/* Use the hardware mechanism for non-simulated devices */
	if (!is_simulated(bus, devfn))
		return pci_direct_conf1.write(seg, bus, devfn, reg, len, value);

	/* XXX we may want to extend this to simulate EHCI power management */

	/*
	 * Mostly we just discard writes, but if the write is a size probe
	 * (i.e. writing ~0 to a BAR), we remember it and arrange to return
	 * the appropriate size mask on the next read.  This is cheating
	 * to some extent, because it depends on the fact that the next
	 * access after such a write will always be a read to the same BAR.
	 */

	if ((reg >= 0x10) && (reg < 0x2c)) {
		/* write is to a BAR */
		if (value == ~0)
			bar_probing = 1;
	} else {
		/*
		 * No warning on writes to ROM BAR, CMD, LATENCY_TIMER,
		 * CACHE_LINE_SIZE, or PM registers.
		 */
		if ((reg != PCI_ROM_ADDRESS) && (reg != PCI_COMMAND_MASTER) &&
				(reg != PCI_LATENCY_TIMER) &&
				(reg != PCI_CACHE_LINE_SIZE) && (reg != 0x44))
			printk(KERN_WARNING "OLPC PCI: Config write to devfn"
				" %x reg %x value %x\n", devfn, reg, value);
	}

	return 0;
}

static const struct pci_raw_ops pci_olpc_conf = {
	.read =	pci_olpc_read,
	.write = pci_olpc_write,
};

int __init pci_olpc_init(void)
{
	printk(KERN_INFO "PCI: Using configuration type OLPC XO-1\n");

Annotation

Implementation Notes