Implement the pci device.

Not sure if we want this. We have pci. OTOH,
ls /dev/pci

is a more unix approach than
lspci

Signed-off-by: Ron Minnich <rminnich@gmail.com>
diff --git a/kern/arch/x86/pci.c b/kern/arch/x86/pci.c
index 0871507..32e7e8e 100644
--- a/kern/arch/x86/pci.c
+++ b/kern/arch/x86/pci.c
@@ -492,6 +492,30 @@
 	return NULL;
 }
 
+// The plan 9 semantics we use here are actually very handy for iterators on
+// pci devices.
+struct pci_device *pci_match_vd(struct pci_device *start, int ven_id, int dev_id)
+{
+	struct pci_device *search;
+	struct pcidev_stailq *first = &pci_devices;
+	int bus, dev, func;
+	
+	// TODO: teach ron about these macros.
+	if (start) {
+		first = (struct pcidev_stailq *)(&start->all_dev);
+	}
+
+	STAILQ_FOREACH(search, first, all_dev) {
+		if (ven_id == 0 && dev_id == 0)
+			return search;
+
+		if ((search->ven_id == ven_id) &&
+		    (search->dev_id == dev_id))
+			return search;
+	}
+	return NULL;
+}
+
 /* Helper to get the membar value for BAR index bir */
 uintptr_t pci_get_membar(struct pci_device *pcidev, int bir)
 {
diff --git a/kern/arch/x86/pci.h b/kern/arch/x86/pci.h
index 6d18084..28bca17 100644
--- a/kern/arch/x86/pci.h
+++ b/kern/arch/x86/pci.h
@@ -253,6 +253,7 @@
 void pci_set_bus_master(struct pci_device *pcidev);
 void pci_clr_bus_master(struct pci_device *pcidev);
 struct pci_device *pci_match_tbdf(int tbdf);
+struct pci_device *pci_match_vd(struct pci_device *start, int ven_id, int dev_id);
 uintptr_t pci_get_membar(struct pci_device *pcidev, int bir);
 uintptr_t pci_get_iobar(struct pci_device *pcidev, int bir);
 uint32_t pci_get_membar_sz(struct pci_device *pcidev, int bir);
@@ -282,6 +283,14 @@
 #define explode_tbdf(tbdf) {pcidev.bus = tbdf >> 16;\
 		pcidev.dev = (tbdf>>11)&0x1f;\
 		pcidev.func = (tbdf>>8)&3;}
+/* Other plan 9 functions to compose and decompose */
+#define MKBUS(t,b,d,f)	(((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
+#define BUSFNO(tbdf)	(((tbdf)>>8)&0x07)
+#define BUSDNO(tbdf)	(((tbdf)>>11)&0x1F)
+#define BUSBNO(tbdf)	(((tbdf)>>16)&0xFF)
+#define BUSTYPE(tbdf)	((tbdf)>>24)
+#define BUSBDF(tbdf)	((tbdf)&0x00FFFF00)
+
 
 static inline void pci_set_drvdata(struct pci_device *pcidev, void *data)
 {
diff --git a/kern/drivers/dev/Kbuild b/kern/drivers/dev/Kbuild
index 0b9dd7a..057adf4 100644
--- a/kern/drivers/dev/Kbuild
+++ b/kern/drivers/dev/Kbuild
@@ -5,7 +5,7 @@
 obj-y						+= ether.o
 obj-y						+= kprof.o
 obj-y						+= mnt.o
-#obj-y						+= pci.o
+obj-y						+= pci.o
 obj-y						+= pipe.o
 obj-y						+= proc.o
 obj-$(CONFIG_REGRESS)				+= regress.o
diff --git a/kern/drivers/dev/pci.c b/kern/drivers/dev/pci.c
index 74c635a..6f41af5 100644
--- a/kern/drivers/dev/pci.c
+++ b/kern/drivers/dev/pci.c
@@ -62,11 +62,11 @@
 }
 
 static int
-pcigen(struct chan *c, char *, struct dirtab *, int unused_int, int s,
+pcigen(struct chan *c, char *unused, struct dirtab *unuseddirtab, int unused_int, int s,
 	   struct dir *dp)
 {
 	int tbdf;
-	Pcidev *p;
+	struct pci_device *p = NULL;
 	struct qid q;
 
 	switch (TYPE(c->qid)) {
@@ -87,18 +87,18 @@
 				devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
 				return 1;
 			}
-			p = pcimatch(NULL, 0, 0);
+			p = pci_match_vd(NULL, 0, 0);
 			while (s >= 2 && p != NULL) {
-				p = pcimatch(p, 0, 0);
+				p = pci_match_vd(p, 0, 0);
 				s -= 2;
 			}
 			if (p == NULL)
 				return -1;
-			return pcidirgen(c, s + Qpcictl, p->tbdf, dp);
+			return pcidirgen(c, s + Qpcictl, MKBUS(0,p->bus,p->dev,p->func), dp);
 		case Qpcictl:
 		case Qpciraw:
 			tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
-			p = pcimatchtbdf(tbdf);
+			p = pci_match_tbdf(tbdf);
 			if (p == NULL)
 				return -1;
 			return pcidirgen(c, TYPE(c->qid), tbdf, dp);
@@ -118,7 +118,7 @@
 	return devwalk(c, nc, name, nname, (struct dirtab *)0, 0, pcigen);
 }
 
-static long pcistat(struct chan *c, uint8_t * dp, long n)
+static int pcistat(struct chan *c, uint8_t * dp, int n)
 {
 	return devstat(c, dp, n, (struct dirtab *)0, 0L, pcigen);
 }
@@ -133,7 +133,7 @@
 	return c;
 }
 
-static void pciclose(struct chan *)
+static void pciclose(struct chan *unused)
 {
 }
 
@@ -142,7 +142,7 @@
 	char buf[256], *ebuf, *w, *a;
 	int i, tbdf, r;
 	uint32_t x;
-	Pcidev *p;
+	struct pci_device *p;
 
 	a = va;
 	switch (TYPE(c->qid)) {
@@ -151,24 +151,22 @@
 			return devdirread(c, a, n, (struct dirtab *)0, 0L, pcigen);
 		case Qpcictl:
 			tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
-			p = pcimatchtbdf(tbdf);
+			p = pci_match_tbdf(tbdf);
 			if (p == NULL)
 				error(Egreg);
 			ebuf = buf + sizeof buf - 1;	/* -1 for newline */
 			w = seprintf(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
-						 p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl);
-			for (i = 0; i < ARRAY_SIZE(p->mem); i++) {
-				if (p->mem[i].size == 0)
-					continue;
-				w = seprintf(w, ebuf, " %d:%.8lux %d", i, p->mem[i].bar,
-							 p->mem[i].size);
+						 p->class, p->subclass, p->progif, p->ven_id, p->dev_id, p->irqline);
+			for (i = 0; i < p->nr_bars; i++) {
+				w = seprintf(w, ebuf, " %d:%.8lux %d", i, p->bar[i].raw_bar,
+					     p->bar[i].mmio_sz);
 			}
 			*w++ = '\n';
 			*w = '\0';
 			return readstr(offset, a, n, buf);
 		case Qpciraw:
 			tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
-			p = pcimatchtbdf(tbdf);
+			p = pci_match_tbdf(tbdf);
 			if (p == NULL)
 				error(Egreg);
 			if (n + offset > 256)
@@ -177,17 +175,17 @@
 				return 0;
 			r = offset;
 			if (!(r & 3) && n == 4) {
-				x = pcicfgr32(p, r);
+				x = pcidev_read32(p, r);
 				PBIT32(a, x);
 				return 4;
 			}
 			if (!(r & 1) && n == 2) {
-				x = pcicfgr16(p, r);
+				x = pcidev_read16(p, r);
 				PBIT16(a, x);
 				return 2;
 			}
 			for (i = 0; i < n; i++) {
-				x = pcicfgr8(p, r);
+				x = pcidev_read8(p, r);
 				PBIT8(a, x);
 				a++;
 				r++;
@@ -205,18 +203,18 @@
 	uint8_t *a;
 	int i, r, tbdf;
 	uint32_t x;
-	Pcidev *p;
+	struct pci_device *p;
 
 	if (n >= sizeof(buf))
 		n = sizeof(buf) - 1;
 	a = va;
-	strncpy(buf, (char *unused_char_p_t)a, n);
+	strncpy(buf, (char *)a, n);
 	buf[n] = 0;
 
 	switch (TYPE(c->qid)) {
 		case Qpciraw:
 			tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
-			p = pcimatchtbdf(tbdf);
+			p = pci_match_tbdf(tbdf);
 			if (p == NULL)
 				error(Egreg);
 			if (offset > 256)
@@ -226,17 +224,17 @@
 			r = offset;
 			if (!(r & 3) && n == 4) {
 				x = GBIT32(a);
-				pcicfgw32(p, r, x);
+				pcidev_write32(p, r, x);
 				return 4;
 			}
 			if (!(r & 1) && n == 2) {
 				x = GBIT16(a);
-				pcicfgw16(p, r, x);
+				pcidev_write16(p, r, x);
 				return 2;
 			}
 			for (i = 0; i < n; i++) {
 				x = GBIT8(a);
-				pcicfgw8(p, r, x);
+				pcidev_write8(p, r, x);
 				a++;
 				r++;
 			}
@@ -247,7 +245,7 @@
 	return n;
 }
 
-struct dev pcidevtab = {
+struct dev pcidevtab __devtab = {
 	'$',
 	"pci",