Module Name:    src
Committed By:   dyoung
Date:           Tue Feb 16 19:29:40 UTC 2010

Modified Files:
        src/sys/arch/x86/pci: pci_machdep.c

Log Message:
PCI Configuration Mechanisms #1 and #2 are controlled by two to
three registers.  Let us think of the kernel operating the registers
in two steps:

1) Select: enable configuration cycles and select a range of
   configuration-space addresses.

2) Access: read or write a word in PCI configuration space.

To make the steps more explicit, extract some helper subroutines
from pci_conf_read(9) and pci_conf_write(9):

pci_conf_selector(tag, reg): from a pcitag_t and a register offset,
    create a word that enables configuration cycles and selects a
    configuration address range.

pci_conf_select(w): for `w' a word created by pci_conf_selector(),
    enable configuration cycles and select the address range indicated
    by `w'.

pci_conf_select(0): disable configuration cycles.

pci_conf_port(tag, reg): map a pcitag_t and a register offset to an I/O
    port where the configuration access should occur.

While I'm in here, change the panic(9) calls to panic("%s: ...",
__func__) instead of hard-coding a subroutine name.


To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/x86/pci/pci_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/pci/pci_machdep.c
diff -u src/sys/arch/x86/pci/pci_machdep.c:1.38 src/sys/arch/x86/pci/pci_machdep.c:1.39
--- src/sys/arch/x86/pci/pci_machdep.c:1.38	Tue Feb 16 00:03:47 2010
+++ src/sys/arch/x86/pci/pci_machdep.c	Tue Feb 16 19:29:40 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_machdep.c,v 1.38 2010/02/16 00:03:47 dyoung Exp $	*/
+/*	$NetBSD: pci_machdep.c,v 1.39 2010/02/16 19:29:40 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.38 2010/02/16 00:03:47 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.39 2010/02/16 19:29:40 dyoung Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -135,7 +135,6 @@
 	void *arg; 
 }; 
 
-
 __cpu_simple_lock_t pci_conf_lock = __SIMPLELOCK_UNLOCKED;
 
 #define	PCI_CONF_LOCK(s)						\
@@ -244,6 +243,59 @@
 };
 #endif
 
+static uint32_t
+pci_conf_selector(pcitag_t tag, int reg)
+{
+	static const pcitag_t mode2_mask = {
+		.mode2 = {
+			  .enable = 0xff
+			, .forward = 0xff
+		}
+	};
+
+	switch (pci_mode) {
+	case 1:
+		return tag.mode1 | reg;
+	case 2:
+		return tag.mode1 & mode2_mask.mode1;
+	default:
+		panic("%s: mode not configured", __func__);
+	}
+}
+
+static unsigned int
+pci_conf_port(pcitag_t tag, int reg)
+{
+	switch (pci_mode) {
+	case 1:
+		return PCI_MODE1_DATA_REG;
+	case 2:
+		return tag.mode2.port | reg;
+	default:
+		panic("%s: mode not configured", __func__);
+	}
+}
+
+static void
+pci_conf_select(uint32_t addr)
+{
+	pcitag_t tag;
+
+	switch (pci_mode) {
+	case 1:
+		outl(PCI_MODE1_ADDRESS_REG, addr);
+		return;
+	case 2:
+		tag.mode1 = addr;
+		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
+		if (tag.mode2.enable != 0)
+			outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
+		return;
+	default:
+		panic("%s: mode not configured", __func__);
+	}
+}
+
 void
 pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
 {
@@ -295,21 +347,21 @@
 	switch (pci_mode) {
 	case 1:
 		if (bus >= 256 || device >= 32 || function >= 8)
-			panic("pci_make_tag: bad request");
+			panic("%s: bad request", __func__);
 
 		tag.mode1 = PCI_MODE1_ENABLE |
 			    (bus << 16) | (device << 11) | (function << 8);
 		return tag;
 	case 2:
 		if (bus >= 256 || device >= 16 || function >= 8)
-			panic("pci_make_tag: bad request");
+			panic("%s: bad request", __func__);
 
 		tag.mode2.port = 0xc000 | (device << 8);
 		tag.mode2.enable = 0xf0 | (function << 1);
 		tag.mode2.forward = bus;
 		return tag;
 	default:
-		panic("pci_make_tag: mode not configured");
+		panic("%s: mode not configured", __func__);
 	}
 }
 
@@ -336,7 +388,7 @@
 			*fp = (tag.mode2.enable >> 1) & 0x7;
 		return;
 	default:
-		panic("pci_decompose_tag: mode not configured");
+		panic("%s: mode not configured", __func__);
 	}
 }
 
@@ -357,25 +409,12 @@
 	}
 #endif
 
-	switch (pci_mode) {
-	case 1:
-		PCI_CONF_LOCK(s);
-		outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
-		data = inl(PCI_MODE1_DATA_REG);
-		outl(PCI_MODE1_ADDRESS_REG, 0);
-		PCI_CONF_UNLOCK(s);
-		return data;
-	case 2:
-		PCI_CONF_LOCK(s);
-		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
-		outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
-		data = inl(tag.mode2.port | reg);
-		outb(PCI_MODE2_ENABLE_REG, 0);
-		PCI_CONF_UNLOCK(s);
-		return data;
-	default:
-		panic("pci_conf_read: mode not configured");
-	}
+	PCI_CONF_LOCK(s);
+	pci_conf_select(pci_conf_selector(tag, reg));
+	data = inl(pci_conf_port(tag, reg));
+	pci_conf_select(0);
+	PCI_CONF_UNLOCK(s);
+	return data;
 }
 
 void
@@ -394,25 +433,11 @@
 	}
 #endif
 
-	switch (pci_mode) {
-	case 1:
-		PCI_CONF_LOCK(s);
-		outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
-		outl(PCI_MODE1_DATA_REG, data);
-		outl(PCI_MODE1_ADDRESS_REG, 0);
-		PCI_CONF_UNLOCK(s);
-		return;
-	case 2:
-		PCI_CONF_LOCK(s);
-		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
-		outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
-		outl(tag.mode2.port | reg, data);
-		outb(PCI_MODE2_ENABLE_REG, 0);
-		PCI_CONF_UNLOCK(s);
-		return;
-	default:
-		panic("pci_conf_write: mode not configured");
-	}
+	PCI_CONF_LOCK(s);
+	pci_conf_select(pci_conf_selector(tag, reg));
+	outl(pci_conf_port(tag, reg), data);
+	pci_conf_select(0);
+	PCI_CONF_UNLOCK(s);
 }
 
 void

Reply via email to