summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/files.pci4
-rw-r--r--sys/dev/pci/pci_map.c7
-rw-r--r--sys/dev/pci/pcireg.h7
-rw-r--r--sys/dev/pci/puc.c183
-rw-r--r--sys/dev/pci/pucvar.h48
5 files changed, 147 insertions, 102 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index eebbda8ce90..9169b4a29b5 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.212 2006/07/31 10:03:22 dlg Exp $
+# $OpenBSD: files.pci,v 1.213 2006/07/31 11:06:33 mickey Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -440,7 +440,7 @@ file dev/pci/if_sk.c skc | sk
# PCI "universal" communication device driver, for PCI com, lpt, etc. ports
# (see documentation in the driver for what, exactly, should be supported)
device puc {[port = -1]}
-attach puc at pci
+attach puc at pci with puc_pci
file dev/pci/puc.c puc
file dev/pci/pucdata.c puc
diff --git a/sys/dev/pci/pci_map.c b/sys/dev/pci/pci_map.c
index c95487360bf..c652ebfbf60 100644
--- a/sys/dev/pci/pci_map.c
+++ b/sys/dev/pci/pci_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_map.c,v 1.17 2006/07/04 18:07:29 kettenis Exp $ */
+/* $OpenBSD: pci_map.c,v 1.18 2006/07/31 11:06:33 mickey Exp $ */
/* $NetBSD: pci_map.c,v 1.7 2000/05/10 16:58:42 thorpej Exp $ */
/*-
@@ -252,11 +252,6 @@ pci_mem_find(pci_chipset_tag_t pc, pcitag_t pcitag, int reg,
cacheablep));
}
-#define _PCI_MAPREG_TYPEBITS(reg) \
- (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO ? \
- reg & PCI_MAPREG_TYPE_MASK : \
- reg & (PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK))
-
pcireg_t
pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index b52fe16d20e..a4a5b4ab8e5 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcireg.h,v 1.31 2006/06/01 11:17:31 brad Exp $ */
+/* $OpenBSD: pcireg.h,v 1.32 2006/07/31 11:06:33 mickey Exp $ */
/* $NetBSD: pcireg.h,v 1.26 2000/05/10 16:58:42 thorpej Exp $ */
/*
@@ -406,6 +406,11 @@ typedef u_int8_t pci_revision_t;
#define PCI_MAPREG_MEM_TYPE_32BIT_1M 0x00000002
#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004
+#define _PCI_MAPREG_TYPEBITS(reg) \
+ (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO ? \
+ reg & PCI_MAPREG_TYPE_MASK : \
+ reg & (PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK))
+
#define PCI_MAPREG_MEM_PREFETCHABLE(mr) \
(((mr) & PCI_MAPREG_MEM_PREFETCHABLE_MASK) != 0)
#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008
diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c
index e36da14241e..78454d47abe 100644
--- a/sys/dev/pci/puc.c
+++ b/sys/dev/pci/puc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: puc.c,v 1.8 2003/02/28 15:14:08 mickey Exp $ */
+/* $OpenBSD: puc.c,v 1.9 2006/07/31 11:06:33 mickey Exp $ */
/* $NetBSD: puc.c,v 1.3 1999/02/06 06:29:54 cgd Exp $ */
/*
@@ -61,52 +61,31 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pucvar.h>
-struct puc_softc {
- struct device sc_dev;
-
- /* static configuration data */
- const struct puc_device_description *sc_desc;
-
- /* card-global dynamic data */
- void *sc_ih;
- struct {
- int mapped;
- bus_addr_t a;
- bus_size_t s;
- bus_space_tag_t t;
- bus_space_handle_t h;
- } sc_bar_mappings[6]; /* XXX constant */
-
- /* per-port dynamic data */
- struct {
- struct device *dev;
-
- /* filled in by port attachments */
- int (*ihand)(void *);
- void *ihandarg;
- } sc_ports[PUC_MAX_PORTS];
+struct puc_pci_softc {
+ struct puc_softc sc_psc;
+
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t ih;
};
-int puc_match(struct device *, void *, void *);
-void puc_attach(struct device *, struct device *, void *);
-int puc_print(void *, const char *);
-int puc_submatch(struct device *, void *, void *);
+int puc_pci_match(struct device *, void *, void *);
+void puc_pci_attach(struct device *, struct device *, void *);
+const char *puc_pci_intr_string(struct puc_attach_args *);
+void *puc_pci_intr_establish(struct puc_attach_args *, int,
+ int (*)(void *), void *, char *);
-struct cfattach puc_ca = {
- sizeof(struct puc_softc), puc_match, puc_attach
+struct cfattach puc_pci_ca = {
+ sizeof(struct puc_pci_softc), puc_pci_match, puc_pci_attach
};
struct cfdriver puc_cd = {
NULL, "puc", DV_DULL
};
-static const struct puc_device_description *
- puc_find_description(pcireg_t, pcireg_t, pcireg_t, pcireg_t);
-static const char *
- puc_port_type_name(int);
+const char *puc_port_type_name(int);
int
-puc_match(parent, match, aux)
+puc_pci_match(parent, match, aux)
struct device *parent;
void *match, *aux;
{
@@ -136,17 +115,34 @@ puc_match(parent, match, aux)
return (0);
}
+const char *
+puc_pci_intr_string(struct puc_attach_args *paa)
+{
+ struct puc_pci_softc *sc = paa->puc;
+
+ return (pci_intr_string(sc->pc, sc->ih));
+}
+
+void *
+puc_pci_intr_establish(struct puc_attach_args *paa, int type,
+ int (*func)(void *), void *arg, char *name)
+{
+ struct puc_pci_softc *sc = paa->puc;
+
+ return (pci_intr_establish(sc->pc, sc->ih, type, func, arg, name));
+}
+
void
-puc_attach(parent, self, aux)
+puc_pci_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct puc_softc *sc = (struct puc_softc *)self;
+ struct puc_pci_softc *psc = (struct puc_pci_softc *)self;
+ struct puc_softc *sc = &psc->sc_psc;
struct pci_attach_args *pa = aux;
struct puc_attach_args paa;
- pci_intr_handle_t intrhandle;
pcireg_t subsys;
- int i, barindex;
+ int i;
subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
sc->sc_desc = puc_find_description(PCI_VENDOR(pa->pa_id),
@@ -171,11 +167,7 @@ puc_attach(parent, self, aux)
return;
}
- printf(": ");
- for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++)
- printf("%s%s", i ? ", " : "",
- puc_port_type_name(sc->sc_desc->ports[i].type));
- printf("\n");
+ puc_print_ports(sc->sc_desc);
/*
* XXX This driver assumes that 'com' ports attached to it
@@ -190,35 +182,46 @@ puc_attach(parent, self, aux)
* XXX definition of PCI/communications/serial, and attach 'com'
* XXX directly on PCI.
*/
- for (i = 0; i < 6; i++) {
- pcireg_t bar, type;
+ for (i = 0; i < PUC_NBARS; i++) {
+ pcireg_t type;
+ int bar;
sc->sc_bar_mappings[i].mapped = 0;
-
- bar = pci_conf_read(pa->pa_pc, pa->pa_tag,
- PCI_MAPREG_START + 4 * i); /* XXX const */
- if (bar == 0) /* BAR not implemented(?) */
+ bar = PCI_MAPREG_START + 4 * i;
+ if (!pci_mapreg_probe(pa->pa_pc, pa->pa_tag, bar, &type))
continue;
- type = (PCI_MAPREG_TYPE(bar) == PCI_MAPREG_TYPE_IO ?
- PCI_MAPREG_TYPE_IO : PCI_MAPREG_MEM_TYPE(bar));
- sc->sc_bar_mappings[i].mapped = (pci_mapreg_map(pa,
- PCI_MAPREG_START + 4 * i, type, 0,
- &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
+ sc->sc_bar_mappings[i].mapped = (pci_mapreg_map(pa, bar, type,
+ 0, &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
&sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s, 0)
== 0);
+ sc->sc_bar_mappings[i].type = type;
if (sc->sc_bar_mappings[i].mapped)
continue;
printf("%s: couldn't map BAR at offset 0x%lx\n",
- sc->sc_dev.dv_xname, (long)(PCI_MAPREG_START + 4 * i));
+ sc->sc_dev.dv_xname, (long)bar);
}
/* Map interrupt. */
- if (pci_intr_map(pa, &intrhandle)) {
+ psc->pc = pa->pa_pc;
+ if (pci_intr_map(pa, &psc->ih)) {
printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
return;
}
+
+ paa.puc = sc;
+ paa.hwtype = 0; /* autodetect */
+ paa.intr_string = &puc_pci_intr_string;
+ paa.intr_establish = &puc_pci_intr_establish;
+ puc_common_attach(sc, &paa);
+}
+
+void
+puc_common_attach(struct puc_softc *sc, struct puc_attach_args *paa)
+{
+ int i, bar;
+
/*
* XXX the sub-devices establish the interrupts, for the
* XXX following reasons:
@@ -237,11 +240,9 @@ puc_attach(parent, self, aux)
/* Configure each port. */
for (i = 0; PUC_PORT_VALID(sc->sc_desc, i); i++) {
- bus_space_handle_t subregion_handle;
-
/* make sure the base address register is mapped */
- barindex = PUC_PORT_BAR_INDEX(sc->sc_desc->ports[i].bar);
- if (!sc->sc_bar_mappings[barindex].mapped) {
+ bar = PUC_PORT_BAR_INDEX(sc->sc_desc->ports[i].bar);
+ if (!sc->sc_bar_mappings[bar].mapped) {
printf("%s: %s port uses unmapped BAR (0x%x)\n",
sc->sc_dev.dv_xname,
puc_port_type_name(sc->sc_desc->ports[i].type),
@@ -250,36 +251,32 @@ puc_attach(parent, self, aux)
}
/* set up to configure the child device */
- paa.port = i;
- paa.type = sc->sc_desc->ports[i].type;
- paa.flags = sc->sc_desc->ports[i].flags;
- paa.pc = pa->pa_pc;
- paa.intrhandle = intrhandle;
- paa.a = sc->sc_bar_mappings[barindex].a;
- paa.t = sc->sc_bar_mappings[barindex].t;
-
- if (bus_space_subregion(sc->sc_bar_mappings[barindex].t,
- sc->sc_bar_mappings[barindex].h,
- sc->sc_desc->ports[i].offset,
- sc->sc_bar_mappings[barindex].s -
- sc->sc_desc->ports[i].offset,
- &subregion_handle)) {
+ paa->port = i;
+ paa->type = sc->sc_desc->ports[i].type;
+ paa->flags = sc->sc_desc->ports[i].flags;
+ paa->a = sc->sc_bar_mappings[bar].a;
+ paa->t = sc->sc_bar_mappings[bar].t;
+
+ if (bus_space_subregion(sc->sc_bar_mappings[bar].t,
+ sc->sc_bar_mappings[bar].h, sc->sc_desc->ports[i].offset,
+ sc->sc_bar_mappings[bar].s - sc->sc_desc->ports[i].offset,
+ &paa->h)) {
printf("%s: couldn't get subregion for port %d\n",
sc->sc_dev.dv_xname, i);
continue;
}
- paa.h = subregion_handle;
-#if 0
- printf("%s: port %d: %s @ (index %d) 0x%x (0x%lx, 0x%lx)\n",
- sc->sc_dev.dv_xname, paa.port,
- puc_port_type_name(paa.type), barindex, (int)paa.a,
- (long)paa.t, (long)paa.h);
+#ifndef SMALL_KERNEL
+ if (autoconf_verbose)
+ printf("%s: port %d: %s @ (index %d) 0x%x "
+ "(0x%lx, 0x%lx)\n", sc->sc_dev.dv_xname, paa->port,
+ puc_port_type_name(paa->type), bar, (int)paa->a,
+ (long)paa->t, (long)paa->h);
#endif
/* and configure it */
- sc->sc_ports[i].dev = config_found_sm(self, &paa, puc_print,
- puc_submatch);
+ sc->sc_ports[i].dev = config_found_sm(&sc->sc_dev, paa,
+ puc_print, puc_submatch);
}
}
@@ -309,9 +306,9 @@ puc_submatch(parent, vcf, aux)
return ((*cf->cf_attach->ca_match)(parent, cf, aux));
}
-static const struct puc_device_description *
+const struct puc_device_description *
puc_find_description(vend, prod, svend, sprod)
- pcireg_t vend, prod, svend, sprod;
+ u_long vend, prod, svend, sprod;
{
int i;
@@ -335,7 +332,7 @@ puc_find_description(vend, prod, svend, sprod)
return (NULL);
}
-static const char *
+const char *
puc_port_type_name(type)
int type;
{
@@ -349,3 +346,15 @@ puc_port_type_name(type)
panic("puc_port_type_name %d", type);
}
}
+
+void
+puc_print_ports(const struct puc_device_description *desc)
+{
+ int i;
+
+ printf(": ");
+ for (i = 0; PUC_PORT_VALID(desc, i); i++)
+ printf("%s%s", i ? ", " : "",
+ puc_port_type_name(desc->ports[i].type));
+ printf("\n");
+}
diff --git a/sys/dev/pci/pucvar.h b/sys/dev/pci/pucvar.h
index fcfc550ea11..12fc9f11f85 100644
--- a/sys/dev/pci/pucvar.h
+++ b/sys/dev/pci/pucvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pucvar.h,v 1.4 2002/02/17 19:24:38 deraadt Exp $ */
+/* $OpenBSD: pucvar.h,v 1.5 2006/07/31 11:06:33 mickey Exp $ */
/* $NetBSD: pucvar.h,v 1.2 1999/02/06 06:29:54 cgd Exp $ */
/*
@@ -41,8 +41,8 @@
#define PUC_MAX_PORTS 8
struct puc_device_description {
- pcireg_t rval[4];
- pcireg_t rmask[4];
+ u_long rval[4];
+ u_long rmask[4];
struct {
u_char type;
u_char bar;
@@ -71,14 +71,50 @@ struct puc_device_description {
struct puc_attach_args {
int port;
int type;
-
- pci_chipset_tag_t pc;
- pci_intr_handle_t intrhandle;
+ int hwtype;
+ void *puc;
bus_addr_t a;
bus_space_tag_t t;
bus_space_handle_t h;
int flags;
+
+ const char *(*intr_string)(struct puc_attach_args *);
+ void *(*intr_establish)(struct puc_attach_args *, int, int (*)(void *),
+ void *, char *);
};
extern const struct puc_device_description puc_devices[];
+
+#define PUC_NBARS 6
+struct puc_softc {
+ struct device sc_dev;
+
+ /* static configuration data */
+ const struct puc_device_description *sc_desc;
+
+ /* card-global dynamic data */
+ struct {
+ int mapped;
+ u_long type;
+ bus_addr_t a;
+ bus_size_t s;
+ bus_space_tag_t t;
+ bus_space_handle_t h;
+ } sc_bar_mappings[PUC_NBARS];
+
+ /* per-port dynamic data */
+ struct {
+ struct device *dev;
+ /* filled in by port attachments */
+ int (*ihand)(void *);
+ void *ihandarg;
+ } sc_ports[PUC_MAX_PORTS];
+};
+
+const struct puc_device_description *
+ puc_find_description(u_long, u_long, u_long, u_long);
+void puc_print_ports(const struct puc_device_description *);
+void puc_common_attach(struct puc_softc *, struct puc_attach_args *);
+int puc_print(void *, const char *);
+int puc_submatch(struct device *, void *, void *);