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:
parent
395fee2331
commit
fe364ce963
@ -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;
|
||||
}
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user