diff options
author | imp <imp@FreeBSD.org> | 2005-09-13 17:56:36 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2005-09-13 17:56:36 +0000 |
commit | adae7de186d65d2df79f712016d4b4bf77f32514 (patch) | |
tree | e2fefa22b1e2c854572f26a6fdea4ce18be34c6d /sys/dev/pccard | |
parent | 18f70966e16b283c5de2a153845883df65c57db5 (diff) | |
download | FreeBSD-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.m | 41 | ||||
-rw-r--r-- | sys/dev/pccard/pccard.c | 90 | ||||
-rw-r--r-- | sys/dev/pccard/pccard_cis.c | 18 | ||||
-rw-r--r-- | sys/dev/pccard/pccardvar.h | 34 |
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 */ |