Skip to content

Commit

Permalink
Convert to support attachment through devprops as well.
Browse files Browse the repository at this point in the history
  • Loading branch information
eeh committed Apr 6, 2002
1 parent 8d851bf commit e41b275
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 12 deletions.
226 changes: 215 additions & 11 deletions sys/dev/isa/isa.c
@@ -1,4 +1,4 @@
/* $NetBSD: isa.c,v 1.110 2002/01/07 21:47:09 thorpej Exp $ */
/* $NetBSD: isa.c,v 1.110.6.1 2002/04/06 16:12:08 eeh Exp $ */

/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -37,13 +37,14 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isa.c,v 1.110 2002/01/07 21:47:09 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: isa.c,v 1.110.6.1 2002/04/06 16:12:08 eeh Exp $");

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/properties.h>

#include <machine/intr.h>

Expand Down Expand Up @@ -89,9 +90,11 @@ isamatch(struct device *parent, struct cfdata *cf, void *aux)
void
isaattach(struct device *parent, struct device *self, void *aux)
{
struct isa_softc *sc = (struct isa_softc *)self;
struct isa_softc *sc = (struct isa_softc *)DEV_PRIVATE(self);
struct isabus_attach_args *iba = aux;

sc->sc_devp = self;

TAILQ_INIT(&sc->sc_knowndevs);
sc->sc_dynamicdevs = 0;

Expand All @@ -101,9 +104,17 @@ isaattach(struct device *parent, struct device *self, void *aux)
/* XXX Add code to fetch known-devices. */

sc->sc_iot = iba->iba_iot;
dev_setprop(self, "io-tag", &sc->sc_iot, sizeof(sc->sc_iot),
PROP_INT, 0);
sc->sc_memt = iba->iba_memt;
dev_setprop(self, "mem-tag", &sc->sc_memt, sizeof(sc->sc_memt),
PROP_INT, 0);
sc->sc_dmat = iba->iba_dmat;
dev_setprop(self, "dma-tag", &sc->sc_dmat, sizeof(sc->sc_dmat),
PROP_INT, 0);
sc->sc_ic = iba->iba_ic;
dev_setprop(self, "chipset-tag", &sc->sc_ic, sizeof(sc->sc_ic),
PROP_INT, 0);

#if NISAPNP > 0
/*
Expand Down Expand Up @@ -138,6 +149,7 @@ isa_attach_knowndevs(struct isa_softc *sc)
{
struct isa_attach_args ia;
struct isa_knowndev *ik;
struct device *child;

if (TAILQ_EMPTY(&sc->sc_knowndevs))
return;
Expand All @@ -146,30 +158,104 @@ isa_attach_knowndevs(struct isa_softc *sc)
if (ik->ik_claimed != NULL)
continue;

if ((child = dev_config_create(sc->sc_devp, 0)) == NULL)
panic("isa_attach_knowndevs: cannot allocate dev");

ia.ia_iot = sc->sc_iot;
ia.ia_memt = sc->sc_memt;
ia.ia_dmat = sc->sc_dmat;
ia.ia_ic = sc->sc_ic;

ia.ia_pnpname = ik->ik_pnpname;
if (ik->ik_pnpname) {
dev_setprop(child, "PNP-name", ik->ik_pnpname,
strlen(ik->ik_pnpname), PROP_STRING, 0);
}
ia.ia_pnpcompatnames = ik->ik_pnpcompatnames;
if (ik->ik_pnpcompatnames) {
struct isa_pnpname *ipn;
char buf[256];
int i = 0;

/*
* Yeech. We need to concatenate all these
* annoying strings into one big one and then
* create a property with it. Good thing nothing
* currently uses this feature. Hope 255 bytes is
* enough.
*/

for (ipn = ik->ik_pnpcompatnames; ipn != NULL;
ipn = ipn->ipn_next) {
strcpy(&buf[i], ipn->ipn_name);
i += strlen(ipn->ipn_name);
buf[i++] = 0;
if (i > 256)
panic("isa_attach_knowndevs: compat");
}
dev_setprop(child, "PNP-compat", buf, i, PROP_STRING,
0);
}

ia.ia_io = ik->ik_io;
ia.ia_nio = ik->ik_nio;
if (ik->ik_nio) {
if (ik->ik_io[0].ir_addr != ISACF_PORT_DEFAULT) {
dev_setprop(child, "port",
&ik->ik_io[0].ir_addr, sizeof(int),
PROP_INT, 0);
}
if (ik->ik_io[0].ir_size != ISACF_SIZE_DEFAULT) {
dev_setprop(child, "size",
&ik->ik_io[0].ir_size, sizeof(int),
PROP_INT, 0);
}
}

ia.ia_iomem = ik->ik_iomem;
ia.ia_niomem = ik->ik_niomem;
if (ik->ik_niomem) {
if (ik->ik_iomem[0].ir_addr != ISACF_IOMEM_DEFAULT) {
dev_setprop(child, "iomem",
&ik->ik_iomem[0].ir_addr, sizeof(int),
PROP_INT, 0);
}
if (ik->ik_iomem[0].ir_size != ISACF_IOSIZ_DEFAULT) {
dev_setprop(child, "iosiz",
&ik->ik_iomem[0].ir_size, sizeof(int),
PROP_INT, 0);
}
}

ia.ia_irq = ik->ik_irq;
ia.ia_nirq = ik->ik_nirq;
if (ik->ik_nirq) {
if (ik->ik_irq[0].ir_irq != ISACF_IRQ_DEFAULT) {
dev_setprop(child, "irq",
&ik->ik_irq[0].ir_irq, sizeof(int),
PROP_INT, 0);
}
}

ia.ia_drq = ik->ik_drq;
ia.ia_ndrq = ik->ik_ndrq;
if (ik->ik_ndrq > 0 &&
ik->ik_drq[0].ir_drq != ISACF_DRQ_DEFAULT) {
dev_setprop(child, "drq",
&ik->ik_drq[0].ir_drq, sizeof(int),
PROP_INT, 0);
}
if (ik->ik_ndrq > 1 &&
ik->ik_drq[1].ir_drq != ISACF_DRQ2_DEFAULT) {
dev_setprop(child, "drq2",
&ik->ik_drq[1].ir_drq, sizeof(int),
PROP_INT, 0);
}

ia.ia_aux = NULL;

ik->ik_claimed = config_found_sm(&sc->sc_dev, &ia,
isaprint, isasubmatch);
ik->ik_claimed = config_found_sad(sc->sc_devp, &ia,
isaprint, isasubmatch, child);
}
}

Expand Down Expand Up @@ -337,29 +423,72 @@ isaprint(void *aux, const char *isa)
int
isasearch(struct device *parent, struct cfdata *cf, void *aux)
{
struct device *child;
struct isa_io res_io[1];
struct isa_iomem res_mem[1];
struct isa_irq res_irq[1];
struct isa_drq res_drq[2];
struct isa_softc *sc = (struct isa_softc *)parent;
struct isa_softc *sc = (struct isa_softc *)DEV_PRIVATE(parent);
struct isa_attach_args ia;
int tryagain;
int tryagain = 1;

do {
while (tryagain && (child = dev_config_create(parent, 0))) {
ia.ia_pnpname = NULL;
ia.ia_pnpcompatnames = NULL;

dev_setprop(child, "cd-name", cf->cf_driver->cd_name,
strlen(cf->cf_driver->cd_name) + 1, PROP_STRING, 0);

/*
* ISA uses a slightly different property protocol for
* locators. Instead of instantiating "loc-foo" properties
* for each locator, we will attach a "foo" property, but
* only if the locator is not wildcarded. When the device
* attaches, if it wants to record or override locator
* information, it creates appropriate properties, overriding
* existing properties created here.
*/
res_io[0].ir_addr = cf->cf_loc[ISACF_PORT];
res_io[0].ir_size = 0;
if (cf->cf_loc[ISACF_PORT] != ISACF_PORT_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_PORT],
&cf->cf_loc[ISACF_PORT], sizeof(int),
PROP_CONST|PROP_INT, 0);
}

res_mem[0].ir_addr = cf->cf_loc[ISACF_IOMEM];
if (cf->cf_loc[ISACF_IOMEM] != ISACF_IOMEM_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_IOMEM],
&cf->cf_loc[ISACF_IOMEM], sizeof(int),
PROP_CONST|PROP_INT, 0);
}
res_mem[0].ir_size = cf->cf_loc[ISACF_IOSIZ];
if (cf->cf_loc[ISACF_IOSIZ] != ISACF_IOSIZ_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_IOSIZ],
&cf->cf_loc[ISACF_IOSIZ], sizeof(int),
PROP_CONST|PROP_INT, 0);
}

res_irq[0].ir_irq =
cf->cf_loc[ISACF_IRQ] == 2 ? 9 : cf->cf_loc[ISACF_IRQ];
if (res_irq[0].ir_irq != ISACF_IRQ_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_IRQ],
&res_irq[0].ir_irq, sizeof(int),
PROP_INT, 0);
}

res_drq[0].ir_drq = cf->cf_loc[ISACF_DRQ];
if (cf->cf_loc[ISACF_DRQ] != ISACF_DRQ_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_DRQ],
&cf->cf_loc[ISACF_DRQ], sizeof(int),
PROP_CONST|PROP_INT, 0);
}
res_drq[1].ir_drq = cf->cf_loc[ISACF_DRQ2];
if (cf->cf_loc[ISACF_DRQ2] != ISACF_DRQ2_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_DRQ2],
&cf->cf_loc[ISACF_DRQ2], sizeof(int),
PROP_CONST|PROP_INT, 0);
}

ia.ia_iot = sc->sc_iot;
ia.ia_memt = sc->sc_memt;
Expand All @@ -379,11 +508,86 @@ isasearch(struct device *parent, struct cfdata *cf, void *aux)
ia.ia_ndrq = 2;

tryagain = 0;
if ((*cf->cf_attach->ca_match)(parent, cf, &ia) > 0) {
config_attach(parent, cf, &ia, isaprint);

/*
* Find out if this is a new driver or old driver and call
* the match function in the correct way.
*/
if ((ssize_t)cf->cf_attach->ca_devsize < 0) {
DEV_PRIVATE(child) = &ia;
if ((*cf->cf_attach->ca_match)(parent, cf, child) > 0) {
config_attach_ad(parent, cf, &ia,
isaprint, child);
tryagain = (cf->cf_fstate == FSTATE_STAR);
} else {
/* Destroy unused device node. */
config_detach(child, 0);
}
} else if ((*cf->cf_attach->ca_match)(parent, cf, &ia) > 0) {

/*
* Old style devices do not update locator
* properties, so we'll do that for them.
*/
if (res_io[0].ir_addr != cf->cf_loc[ISACF_PORT] &&
cf->cf_loc[ISACF_PORT] != ISACF_PORT_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_PORT],
&res_io[0].ir_addr, sizeof(int),
PROP_INT, 0);
}
if (res_io[0].ir_size != 0) {
dev_setprop(child, cf->cf_locnames[ISACF_SIZE],
&res_io[0].ir_size, sizeof(int),
PROP_INT, 0);
}

if (res_mem[0].ir_addr != cf->cf_loc[ISACF_IOMEM] &&
cf->cf_loc[ISACF_IOMEM] !=
ISACF_IOMEM_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_IOMEM],
&res_mem[0].ir_addr, sizeof(int),
PROP_INT, 0);
}

if (res_mem[0].ir_addr != cf->cf_loc[ISACF_IOSIZ] &&
cf->cf_loc[ISACF_IOSIZ] !=
ISACF_IOSIZ_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_IOSIZ],
&res_mem[0].ir_size, sizeof(int),
PROP_INT, 0);
}

/*
* Since this value may have been twiddled by us
* earlier we cannot determine if the value was
* untouched by our child.
*/
if (res_irq[0].ir_irq != cf->cf_loc[ISACF_IRQ]) {
dev_setprop(child, cf->cf_locnames[ISACF_IRQ],
&res_irq[0].ir_irq, sizeof(int),
PROP_INT, 0);
}

if (res_drq[0].ir_drq != cf->cf_loc[ISACF_DRQ] &&
cf->cf_loc[ISACF_DRQ] != ISACF_DRQ_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_DRQ],
&res_drq[0].ir_drq, sizeof(int),
PROP_INT, 0);
}
if (res_drq[0].ir_drq != cf->cf_loc[ISACF_DRQ2] &&
cf->cf_loc[ISACF_DRQ2] != ISACF_DRQ2_DEFAULT) {
dev_setprop(child, cf->cf_locnames[ISACF_DRQ2],
&res_drq[0].ir_drq, sizeof(int),
PROP_INT, 0);
}

config_attach_ad(parent, cf, &ia, isaprint, child);
tryagain = (cf->cf_fstate == FSTATE_STAR);
} else {
/* Destroy unused device node. */
config_detach(child, 0);
}
} while (tryagain);
}

return (0);
}
Expand Down
3 changes: 2 additions & 1 deletion sys/dev/isa/isavar.h
@@ -1,4 +1,4 @@
/* $NetBSD: isavar.h,v 1.39 2002/01/07 21:47:10 thorpej Exp $ */
/* $NetBSD: isavar.h,v 1.39.6.1 2002/04/06 16:12:08 eeh Exp $ */

/*-
* Copyright (c) 1997, 2001 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -218,6 +218,7 @@ struct isa_attach_args {
*/
struct isa_softc {
struct device sc_dev; /* base device */
struct device *sc_devp;

bus_space_tag_t sc_iot; /* isa io space tag */
bus_space_tag_t sc_memt; /* isa mem space tag */
Expand Down

0 comments on commit e41b275

Please sign in to comment.