From 3a66b9167ff4f4e32cbe7c49239eaa549114ae54 Mon Sep 17 00:00:00 2001 From: dyoung Date: Thu, 10 Jan 2008 07:44:07 +0000 Subject: [PATCH] Let us detach atabus* from wdc*, and wdc* from isa*. Use device_t, device_private(). --- sys/dev/ic/wdc.c | 39 ++++++++++++++++++++++++++++++--------- sys/dev/ic/wdcvar.h | 7 ++++--- sys/dev/isa/wdc_isa.c | 41 ++++++++++++++++++++++++++++++----------- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c index 82e0327b76e0..10c6f89c05d8 100644 --- a/sys/dev/ic/wdc.c +++ b/sys/dev/ic/wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.249 2007/10/19 12:00:04 ad Exp $ */ +/* $NetBSD: wdc.c,v 1.250 2008/01/10 07:44:07 dyoung Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.249 2007/10/19 12:00:04 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.250 2008/01/10 07:44:07 dyoung Exp $"); #include "opt_ata.h" @@ -777,9 +777,10 @@ wdcattach(struct ata_channel *chp) } int -wdcactivate(struct device *self, enum devact act) +wdcactivate(device_t self, enum devact act) { - struct atac_softc *atac = (struct atac_softc *) self; + struct atac_softc *atac = device_private(self); + struct ata_channel *chp; int s, i, error = 0; s = splbio(); @@ -790,8 +791,10 @@ wdcactivate(struct device *self, enum devact act) case DVACT_DEACTIVATE: for (i = 0; i < atac->atac_nchannels; i++) { - error = - config_deactivate(atac->atac_channels[i]->atabus); + chp = atac->atac_channels[i]; + if (chp->atabus == NULL) + continue; + error = config_deactivate(chp->atabus); if (error) break; } @@ -801,16 +804,34 @@ wdcactivate(struct device *self, enum devact act) return (error); } -int -wdcdetach(struct device *self, int flags) +void +wdc_childdetached(device_t self, device_t child) { - struct atac_softc *atac = (struct atac_softc *) self; + struct atac_softc *atac = device_private(self); + struct ata_channel *chp; + int i; + + for (i = 0; i < atac->atac_nchannels; i++) { + chp = atac->atac_channels[i]; + if (child == chp->atabus) { + chp->atabus = NULL; + return; + } + } +} + +int +wdcdetach(device_t self, int flags) +{ + struct atac_softc *atac = device_private(self); struct ata_channel *chp; struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic; int i, error = 0; for (i = 0; i < atac->atac_nchannels; i++) { chp = atac->atac_channels[i]; + if (chp->atabus == NULL) + continue; ATADEBUG_PRINT(("wdcdetach: %s: detaching %s\n", atac->atac_dev.dv_xname, chp->atabus->dv_xname), DEBUG_DETACH); diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h index 35b5356810d5..a0517044990a 100644 --- a/sys/dev/ic/wdcvar.h +++ b/sys/dev/ic/wdcvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: wdcvar.h,v 1.87 2006/10/25 17:33:02 bouyer Exp $ */ +/* $NetBSD: wdcvar.h,v 1.88 2008/01/10 07:44:08 dyoung Exp $ */ /*- * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. @@ -146,8 +146,9 @@ void wdc_init_shadow_regs(struct ata_channel *); int wdcprobe(struct ata_channel *); void wdcattach(struct ata_channel *); -int wdcdetach(struct device *, int); -int wdcactivate(struct device *, enum devact); +int wdcdetach(device_t, int); +void wdc_childdetached(device_t, device_t); +int wdcactivate(device_t, enum devact); int wdcintr(void *); void wdc_sataprobe(struct ata_channel *); diff --git a/sys/dev/isa/wdc_isa.c b/sys/dev/isa/wdc_isa.c index 21c712b8c428..2d1aa3ed0592 100644 --- a/sys/dev/isa/wdc_isa.c +++ b/sys/dev/isa/wdc_isa.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_isa.c,v 1.52 2007/10/19 12:00:24 ad Exp $ */ +/* $NetBSD: wdc_isa.c,v 1.53 2008/01/10 07:44:08 dyoung Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.52 2007/10/19 12:00:24 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.53 2008/01/10 07:44:08 dyoung Exp $"); #include #include @@ -74,11 +74,13 @@ struct wdc_isa_softc { int sc_drq; }; -static int wdc_isa_probe(struct device *, struct cfdata *, void *); -static void wdc_isa_attach(struct device *, struct device *, void *); +static int wdc_isa_probe(device_t , struct cfdata *, void *); +static void wdc_isa_attach(device_t, device_t, void *); +static int wdc_isa_detach(device_t, int); -CFATTACH_DECL(wdc_isa, sizeof(struct wdc_isa_softc), - wdc_isa_probe, wdc_isa_attach, NULL, NULL); +CFATTACH_DECL2(wdc_isa, sizeof(struct wdc_isa_softc), + wdc_isa_probe, wdc_isa_attach, wdc_isa_detach, NULL, NULL, + wdc_childdetached); #if 0 static void wdc_isa_dma_setup(struct wdc_isa_softc *); @@ -88,8 +90,7 @@ static int wdc_isa_dma_finish(void*, int, int, int); #endif static int -wdc_isa_probe(struct device *parent, struct cfdata *match, - void *aux) +wdc_isa_probe(device_t parent, struct cfdata *match, void *aux) { struct ata_channel ch; struct isa_attach_args *ia = aux; @@ -152,10 +153,28 @@ out: return (result); } -static void -wdc_isa_attach(struct device *parent, struct device *self, void *aux) +static int +wdc_isa_detach(device_t self, int flags) { - struct wdc_isa_softc *sc = (void *)self; + struct wdc_isa_softc *sc = device_private(self); + struct wdc_regs *wdr = &sc->wdc_regs; + int rc; + + if ((rc = wdcdetach(self, flags)) != 0) + return rc; + + isa_intr_disestablish(sc->sc_ic, sc->sc_ih); + + bus_space_unmap(wdr->ctl_iot, wdr->ctl_ioh, WDC_ISA_AUXREG_NPORTS); + bus_space_unmap(wdr->cmd_iot, wdr->cmd_baseioh, WDC_ISA_REG_NPORTS); + + return 0; +} + +static void +wdc_isa_attach(device_t parent, device_t self, void *aux) +{ + struct wdc_isa_softc *sc = device_private(self); struct wdc_regs *wdr; struct isa_attach_args *ia = aux; int wdc_cf_flags = device_cfdata(self)->cf_flags;