summaryrefslogtreecommitdiffstats
path: root/sys/dev/pccard
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-09-13 17:56:36 +0000
committerimp <imp@FreeBSD.org>2005-09-13 17:56:36 +0000
commitadae7de186d65d2df79f712016d4b4bf77f32514 (patch)
treee2fefa22b1e2c854572f26a6fdea4ce18be34c6d /sys/dev/pccard
parent18f70966e16b283c5de2a153845883df65c57db5 (diff)
downloadFreeBSD-src-adae7de186d65d2df79f712016d4b4bf77f32514.zip
FreeBSD-src-adae7de186d65d2df79f712016d4b4bf77f32514.tar.gz
Add a few new functions interfaces to allow reading/writing attribute
memory, the CCR and a tweak to cis_scan.
Diffstat (limited to 'sys/dev/pccard')
-rw-r--r--sys/dev/pccard/card_if.m41
-rw-r--r--sys/dev/pccard/pccard.c90
-rw-r--r--sys/dev/pccard/pccard_cis.c18
-rw-r--r--sys/dev/pccard/pccardvar.h34
4 files changed, 172 insertions, 11 deletions
diff --git a/sys/dev/pccard/card_if.m b/sys/dev/pccard/card_if.m
index 51977cc..434389e 100644
--- a/sys/dev/pccard/card_if.m
+++ b/sys/dev/pccard/card_if.m
@@ -175,6 +175,47 @@ METHOD int compat_match {
#
METHOD int cis_scan {
device_t bus;
+ device_t dev;
pccard_scan_t fnp;
void *argp;
};
+
+#
+# Convenience function to read attribute memory.
+#
+METHOD int attr_read {
+ device_t bus;
+ device_t dev;
+ uint32_t offset;
+ uint8_t *val;
+}
+
+#
+# Convenience function to write attribute memory.
+#
+METHOD int attr_write {
+ device_t bus;
+ device_t dev;
+ uint32_t offset;
+ uint8_t val;
+}
+
+#
+# Read the CCR register
+#
+METHOD int ccr_read {
+ device_t bus;
+ device_t dev;
+ uint32_t offset;
+ uint8_t *val;
+}
+
+#
+# Write the CCR register
+#
+METHOD int ccr_write {
+ device_t bus;
+ device_t dev;
+ uint32_t offset;
+ uint8_t val;
+}
diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c
index 6bd7d7d..309d407 100644
--- a/sys/dev/pccard/pccard.c
+++ b/sys/dev/pccard/pccard.c
@@ -1314,6 +1314,90 @@ pccard_deactivate_resource(device_t brdev, device_t child, int type,
return (bus_generic_deactivate_resource(brdev, child, type, rid, r));
}
+static int
+pccard_attr_read_impl(device_t brdev, device_t child, uint32_t offset,
+ uint8_t *val)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *pf = devi->pf;
+
+ /*
+ * Optimization. Most of the time, devices want to access
+ * the same page of the attribute memory that the CCR is in.
+ * We take advantage of this fact here.
+ */
+ if (offset / PCCARD_MEM_PAGE_SIZE ==
+ pf->ccr_base / PCCARD_MEM_PAGE_SIZE)
+ *val = bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh,
+ offset % PCCARD_MEM_PAGE_SIZE);
+ else {
+ CARD_SET_MEMORY_OFFSET(brdev, child, pf->ccr_rid, offset,
+ &offset);
+ *val = bus_space_read_1(pf->pf_ccrt, pf->pf_ccrh, offset);
+ CARD_SET_MEMORY_OFFSET(brdev, child, pf->ccr_rid, pf->ccr_base,
+ &offset);
+ }
+ return 0;
+}
+
+static int
+pccard_attr_write_impl(device_t brdev, device_t child, uint32_t offset,
+ uint8_t val)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *pf = devi->pf;
+
+ /*
+ * Optimization. Most of the time, devices want to access
+ * the same page of the attribute memory that the CCR is in.
+ * We take advantage of this fact here.
+ */
+ if (offset / PCCARD_MEM_PAGE_SIZE ==
+ pf->ccr_base / PCCARD_MEM_PAGE_SIZE)
+ bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh,
+ offset % PCCARD_MEM_PAGE_SIZE, val);
+ else {
+ CARD_SET_MEMORY_OFFSET(brdev, child, pf->ccr_rid, offset,
+ &offset);
+ bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh, offset, val);
+ CARD_SET_MEMORY_OFFSET(brdev, child, pf->ccr_rid, pf->ccr_base,
+ &offset);
+ }
+
+ return 0;
+}
+
+static int
+pccard_ccr_read_impl(device_t brdev, device_t child, uint32_t offset,
+ uint8_t *val)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+
+ *val = pccard_ccr_read(devi->pf, offset);
+ device_printf(child, "ccr_read of %#x (%#x) is %#x\n", offset,
+ devi->pf->pf_ccr_offset, *val);
+ return 0;
+}
+
+static int
+pccard_ccr_write_impl(device_t brdev, device_t child, uint32_t offset,
+ uint8_t val)
+{
+ struct pccard_ivar *devi = PCCARD_IVAR(child);
+ struct pccard_function *pf = devi->pf;
+
+ /*
+ * Can't use pccard_ccr_write since client drivers may access
+ * registers not contained in the 'mask' if they are non-standard.
+ */
+ device_printf(child, "ccr_write of %#x to %#x (%#x)\n", val, offset,
+ devi->pf->pf_ccr_offset);
+ bus_space_write_1(pf->pf_ccrt, pf->pf_ccrh, pf->pf_ccr_offset + offset,
+ val);
+ return 0;
+}
+
+
static device_method_t pccard_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pccard_probe),
@@ -1346,10 +1430,14 @@ static device_method_t pccard_methods[] = {
DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset),
DEVMETHOD(card_attach_card, pccard_attach_card),
DEVMETHOD(card_detach_card, pccard_detach_card),
+ DEVMETHOD(card_do_product_lookup, pccard_do_product_lookup),
DEVMETHOD(card_compat_do_probe, pccard_compat_do_probe),
DEVMETHOD(card_compat_do_attach, pccard_compat_do_attach),
- DEVMETHOD(card_do_product_lookup, pccard_do_product_lookup),
DEVMETHOD(card_cis_scan, pccard_scan_cis),
+ DEVMETHOD(card_attr_read, pccard_attr_read_impl),
+ DEVMETHOD(card_attr_write, pccard_attr_write_impl),
+ DEVMETHOD(card_ccr_read, pccard_ccr_read_impl),
+ DEVMETHOD(card_ccr_write, pccard_ccr_write_impl),
{ 0, 0 }
};
diff --git a/sys/dev/pccard/pccard_cis.c b/sys/dev/pccard/pccard_cis.c
index fe6d513..357f205 100644
--- a/sys/dev/pccard/pccard_cis.c
+++ b/sys/dev/pccard/pccard_cis.c
@@ -93,12 +93,13 @@ pccard_read_cis(struct pccard_softc *sc)
STAILQ_INIT(&state.card->pf_head);
state.pf = NULL;
- if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple, &state) == -1)
+ if (pccard_scan_cis(device_get_parent(sc->dev), sc->dev,
+ pccard_parse_cis_tuple, &state) == -1)
state.card->error++;
}
int
-pccard_scan_cis(device_t dev, pccard_scan_t fct, void *arg)
+pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg)
{
struct resource *res;
int rid;
@@ -134,8 +135,7 @@ pccard_scan_cis(device_t dev, pccard_scan_t fct, void *arg)
device_printf(dev, "can't alloc memory to read attributes\n");
return -1;
}
- CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
- rid, PCCARD_A_MEM_ATTR);
+ CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR);
tuple.memt = rman_get_bustag(res);
tuple.memh = rman_get_bushandle(res);
tuple.ptr = 0;
@@ -386,8 +386,8 @@ pccard_scan_cis(device_t dev, pccard_scan_t fct, void *arg)
*/
while (1) {
if (longlink_present) {
- CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
- SYS_RES_MEMORY, rid, longlink_common ?
+ CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY,
+ rid, longlink_common ?
PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
DPRINTF(("cis mem map %x\n",
(unsigned int) tuple.memh));
@@ -397,9 +397,9 @@ pccard_scan_cis(device_t dev, pccard_scan_t fct, void *arg)
longlink_common = 1;
longlink_addr = 0;
} else if (mfc_count && (mfc_index < mfc_count)) {
- CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
- SYS_RES_MEMORY, rid, mfc[mfc_index].common
- ? PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
+ CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY,
+ rid, mfc[mfc_index].common ?
+ PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
DPRINTF(("cis mem map %x\n",
(unsigned int) tuple.memh));
/* set parse state, and point at the next one */
diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h
index ee385cd..a4a2f79 100644
--- a/sys/dev/pccard/pccardvar.h
+++ b/sys/dev/pccard/pccardvar.h
@@ -254,7 +254,7 @@ pccard_product_lookup(device_t dev, const struct pccard_product *tab,
void pccard_read_cis(struct pccard_softc *);
void pccard_check_cis_quirks(device_t);
void pccard_print_cis(device_t);
-int pccard_scan_cis(device_t, pccard_scan_t, void *);
+int pccard_scan_cis(device_t, device_t, pccard_scan_t, void *);
#define pccard_cis_read_1(tuple, idx0) \
(bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0)))
@@ -303,6 +303,38 @@ pccard_compat_attach(device_t dev)
return (CARD_COMPAT_DO_ATTACH(device_get_parent(dev), dev));
}
+/* Convenience functions */
+
+static __inline int
+pccard_cis_scan(device_t dev, pccard_scan_t fct, void *arg)
+{
+ return (CARD_CIS_SCAN(device_get_parent(dev), dev, fct, arg));
+}
+
+static __inline int
+pccard_attr_read_1(device_t dev, uint32_t offset, uint8_t *val)
+{
+ return (CARD_ATTR_READ(device_get_parent(dev), dev, offset, val));
+}
+
+static __inline int
+pccard_attr_write_1(device_t dev, uint32_t offset, uint8_t val)
+{
+ return (CARD_ATTR_WRITE(device_get_parent(dev), dev, offset, val));
+}
+
+static __inline int
+pccard_ccr_read_1(device_t dev, uint32_t offset, uint8_t *val)
+{
+ return (CARD_CCR_READ(device_get_parent(dev), dev, offset, val));
+}
+
+static __inline int
+pccard_ccr_write_1(device_t dev, uint32_t offset, uint8_t val)
+{
+ return (CARD_CCR_WRITE(device_get_parent(dev), dev, offset, val));
+}
+
/* ivar interface */
enum {
PCCARD_IVAR_ETHADDR, /* read ethernet address from CIS tupple */
OpenPOWER on IntegriCloud