diff --git a/sys/dev/ic/aic6360.c b/sys/dev/ic/aic6360.c index 5f7a35fb3887..97cd00adcedf 100644 --- a/sys/dev/ic/aic6360.c +++ b/sys/dev/ic/aic6360.c @@ -1,4 +1,4 @@ -/* $NetBSD: aic6360.c,v 1.61 1998/12/05 19:43:50 mjacob Exp $ */ +/* $NetBSD: aic6360.c,v 1.62 1999/09/26 08:14:57 enami Exp $ */ #include "opt_ddb.h" #ifdef DDB @@ -154,7 +154,6 @@ int aic_debug = 0x00; /* AIC_SHOWSTART|AIC_SHOWMISC|AIC_SHOWTRACE; */ void aicattach __P((struct aic_softc *)); void aic_minphys __P((struct buf *)); -void aic_init __P((struct aic_softc *)); void aic_done __P((struct aic_softc *, struct aic_acb *)); void aic_dequeue __P((struct aic_softc *, struct aic_acb *)); int aic_scsi_cmd __P((struct scsipi_xfer *)); @@ -270,7 +269,7 @@ aicattach(sc) sc->sc_minsync = (2 * 250) / sc->sc_freq; sc->sc_maxsync = (9 * 250) / sc->sc_freq; - aic_init(sc); /* Init chip and driver */ + aic_init(sc, 1); /* Init chip and driver */ /* * Fill in the adapter. @@ -294,9 +293,46 @@ aicattach(sc) /* * ask the adapter what subunits are present */ - config_found(&sc->sc_dev, &sc->sc_link, scsiprint); + sc->sc_child = config_found(&sc->sc_dev, &sc->sc_link, scsiprint); } +int +aic_activate(self, act) + struct device *self; + enum devact act; +{ + struct aic_softc *sc = (struct aic_softc *) self; + int s, rv = 0; + + s = splhigh(); + switch (act) { + case DVACT_ACTIVATE: + rv = EOPNOTSUPP; + break; + + case DVACT_DEACTIVATE: + if (sc->sc_child != NULL) + rv = config_deactivate(sc->sc_child); + break; + } + splx(s); + + return (rv); +} + +int +aic_detach(self, flags) + struct device *self; + int flags; +{ + struct aic_softc *sc = (struct aic_softc *) self; + int rv = 0; + + if (sc->sc_child != NULL) + rv = config_detach(sc->sc_child, flags); + + return (rv); +} /* Initialize AIC6360 chip itself * The following conditions should hold: @@ -367,14 +403,17 @@ aic_scsi_reset(sc) * Initialize aic SCSI driver. */ void -aic_init(sc) +aic_init(sc, bus_reset) struct aic_softc *sc; + int bus_reset; { struct aic_acb *acb; int r; - aic_reset(sc); - aic_scsi_reset(sc); + if (bus_reset) { + aic_reset(sc); + aic_scsi_reset(sc); + } aic_reset(sc); if (sc->sc_state == AIC_INIT) { @@ -1996,7 +2035,7 @@ dophase: printf("%s: unexpected bus phase; resetting\n", sc->sc_dev.dv_xname); AIC_BREAK(); reset: - aic_init(sc); + aic_init(sc, 1); return 1; finish: diff --git a/sys/dev/ic/aic6360var.h b/sys/dev/ic/aic6360var.h index 24a23e9c08d8..3ddb85116dc2 100644 --- a/sys/dev/ic/aic6360var.h +++ b/sys/dev/ic/aic6360var.h @@ -1,4 +1,4 @@ -/* $NetBSD: aic6360var.h,v 1.3 1998/11/19 21:52:59 thorpej Exp $ */ +/* $NetBSD: aic6360var.h,v 1.4 1999/09/26 08:14:57 enami Exp $ */ /* * Copyright (c) 1994, 1995, 1996 Charles M. Hannum. All rights reserved. @@ -173,6 +173,8 @@ struct aic_softc { int sc_freq; /* Clock frequency in MHz */ int sc_minsync; /* Minimum sync period / 4 */ int sc_maxsync; /* Maximum sync period / 4 */ + + struct device *sc_child; /* Our child */ }; #if AIC_DEBUG @@ -203,6 +205,9 @@ extern int aic_debug; /* AIC_SHOWSTART|AIC_SHOWMISC|AIC_SHOWTRACE; */ #define AIC_ISA_IOSIZE 0x20 /* XXX */ void aicattach __P((struct aic_softc *)); +int aic_activate __P((struct device *, enum devact)); +int aic_detach __P((struct device *, int)); int aicintr __P((void *)); int aic_find __P((bus_space_tag_t, bus_space_handle_t)); void aic_isa_attach __P((struct device *, struct device *, void *)); +void aic_init __P((struct aic_softc *, int)); diff --git a/sys/dev/pcmcia/aic_pcmcia.c b/sys/dev/pcmcia/aic_pcmcia.c index d266f1bece81..5f66da674c94 100644 --- a/sys/dev/pcmcia/aic_pcmcia.c +++ b/sys/dev/pcmcia/aic_pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: aic_pcmcia.c,v 1.11 1999/09/07 19:30:10 soren Exp $ */ +/* $NetBSD: aic_pcmcia.c,v 1.12 1999/09/26 08:14:58 enami Exp $ */ /* * Copyright (c) 1997 Marc Horowitz. All rights reserved. @@ -50,6 +50,9 @@ int aic_pcmcia_match __P((struct device *, struct cfdata *, void *)); void aic_pcmcia_attach __P((struct device *, struct device *, void *)); +int aic_pcmcia_detach __P((struct device *, int)); + +int aic_dodetach = 0; struct aic_pcmcia_softc { struct aic_softc sc_aic; /* real "aic" softc */ @@ -62,7 +65,8 @@ struct aic_pcmcia_softc { }; struct cfattach aic_pcmcia_ca = { - sizeof(struct aic_pcmcia_softc), aic_pcmcia_match, aic_pcmcia_attach + sizeof(struct aic_pcmcia_softc), aic_pcmcia_match, aic_pcmcia_attach, + aic_pcmcia_detach, aic_activate }; int aic_pcmcia_enable __P((void *, int)); @@ -180,20 +184,17 @@ aic_pcmcia_attach(parent, self, aux) panic("aic_pcmcia_attach: impossible"); } -#if 0 /* XXX power management broken somehow. */ + printf(": %s\n", app->app_name); + + if (aic_dodetach) { /* XXX temporary */ /* We can enable and disable the controller. */ sc->sc_adapter.scsipi_enable = aic_pcmcia_enable; - - /* - * Disable the pcmcia function now; we will be enbled again - * as the SCSI code adds references to probe for children. - */ - pcmcia_function_disable(pf); - - printf(": %s\n", app->app_name); -#else - printf(": %s\n", app->app_name); - +#ifdef DIAGNOSTIC + if (sc->sc_adapter.scsipi_refcnt != 0) + panic("refcnt isn't 0"); +#endif + sc->sc_adapter.scsipi_refcnt++; + } else { /* XXX temporary */ psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_BIO, aicintr, &psc->sc_aic); if (psc->sc_ih == NULL) { @@ -201,11 +202,37 @@ aic_pcmcia_attach(parent, self, aux) psc->sc_aic.sc_dev.dv_xname); return; } -#endif + } /* XXX temporary */ aicattach(sc); + + if (aic_dodetach) { /* XXX temporary */ + sc->sc_adapter.scsipi_refcnt--; +#ifdef DIAGNOSTIC + if (sc->sc_adapter.scsipi_refcnt != 0) + panic("refcnt isn't 0"); +#endif + pcmcia_function_disable(pf); + } } +int +aic_pcmcia_detach(self, flags) + struct device *self; + int flags; +{ + struct aic_pcmcia_softc *sc = (struct aic_pcmcia_softc *)self; + int error; + + if ((error = aic_detach(self, flags)) != 0) + return (error); + + /* Unmap our i/o window and i/o space. */ + pcmcia_io_unmap(sc->sc_pf, sc->sc_io_window); + pcmcia_io_free(sc->sc_pf, &sc->sc_pcioh); + + return (0); +} int aic_pcmcia_enable(arg, onoff) void *arg; @@ -229,6 +256,9 @@ aic_pcmcia_enable(arg, onoff) pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih); return (EIO); } + + /* Initialize only chip. */ + aic_init(&psc->sc_aic, 0); } else { pcmcia_function_disable(psc->sc_pf); pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);