Add a few new functions interfaces to allow reading/writing attribute

memory, the CCR and a tweak to cis_scan.
This commit is contained in:
Warner Losh 2005-09-13 17:56:36 +00:00
parent 395fee2331
commit fe364ce963
4 changed files with 172 additions and 11 deletions

View File

@ -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;
}

View File

@ -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 }
};

View File

@ -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 */

View File

@ -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 */