Module Name: src Committed By: jdolecek Date: Wed Oct 24 19:38:00 UTC 2018
Modified Files: src/sys/dev/ata: TODO.ncq ata.c atavar.h src/sys/dev/ic: ahcisata_core.c ahcisatavar.h siisata.c siisatavar.h src/sys/dev/pci: ahcisata_pci.c siisata_pci.c Log Message: detach the controller itself on shutdown; adjust to not detach already detached atabus/channel To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.142 -r1.143 src/sys/dev/ata/ata.c cvs rdiff -u -r1.100 -r1.101 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.64 -r1.65 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.19 -r1.20 src/sys/dev/ic/ahcisatavar.h cvs rdiff -u -r1.36 -r1.37 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.8 -r1.9 src/sys/dev/ic/siisatavar.h cvs rdiff -u -r1.40 -r1.41 src/sys/dev/pci/ahcisata_pci.c cvs rdiff -u -r1.18 -r1.19 src/sys/dev/pci/siisata_pci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.10 src/sys/dev/ata/TODO.ncq:1.11 --- src/sys/dev/ata/TODO.ncq:1.10 Tue Oct 23 22:05:01 2018 +++ src/sys/dev/ata/TODO.ncq Wed Oct 24 19:38:00 2018 @@ -14,6 +14,3 @@ set - old bug - kern/16789 add support for the NCQ TRIM if supported by device? - -ahcisata(4)/siisata(4) - enable detach on shutdown, and fix the issue -with atabus being detached several times Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.142 src/sys/dev/ata/ata.c:1.143 --- src/sys/dev/ata/ata.c:1.142 Mon Oct 22 20:13:47 2018 +++ src/sys/dev/ata/ata.c Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.142 2018/10/22 20:13:47 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.143 2018/10/24 19:38:00 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.142 2018/10/22 20:13:47 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.143 2018/10/24 19:38:00 jdolecek Exp $"); #include "opt_ata.h" @@ -216,6 +216,8 @@ ata_channel_detach(struct ata_channel *c return; ata_channel_destroy(chp); + + chp->ch_flags |= ATACH_DETACHED; } static void Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.100 src/sys/dev/ata/atavar.h:1.101 --- src/sys/dev/ata/atavar.h:1.100 Mon Oct 22 20:13:47 2018 +++ src/sys/dev/ata/atavar.h Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.100 2018/10/22 20:13:47 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.101 2018/10/24 19:38:00 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -410,10 +410,11 @@ struct ata_channel { #define ATACH_TH_RESET 0x200 /* someone ask the thread to reset */ #define ATACH_TH_RESCAN 0x400 /* rescan requested */ #define ATACH_NCQ 0x800 /* channel executing NCQ commands */ -#define ATACH_DMA_BEFORE_CMD 0x1000 /* start DMA first */ -#define ATACH_TH_DRIVE_RESET 0x2000 /* asked thread to drive(s) reset */ -#define ATACH_RECOVERING 0x4000 /* channel is recovering */ -#define ATACH_TH_RECOVERY 0x8000 /* asked thread to run recovery */ +#define ATACH_DMA_BEFORE_CMD 0x01000 /* start DMA first */ +#define ATACH_TH_DRIVE_RESET 0x02000 /* asked thread to drive(s) reset */ +#define ATACH_RECOVERING 0x04000 /* channel is recovering */ +#define ATACH_TH_RECOVERY 0x08000 /* asked thread to run recovery */ +#define ATACH_DETACHED 0x10000 /* channel was destroyed */ #define ATACH_NODRIVE 0xff /* no drive selected for reset */ Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.64 src/sys/dev/ic/ahcisata_core.c:1.65 --- src/sys/dev/ic/ahcisata_core.c:1.64 Mon Oct 22 20:13:47 2018 +++ src/sys/dev/ic/ahcisata_core.c Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.64 2018/10/22 20:13:47 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.65 2018/10/24 19:38:00 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.64 2018/10/22 20:13:47 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.65 2018/10/24 19:38:00 jdolecek Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -477,6 +477,24 @@ end: } } +void +ahci_childdetached(struct ahci_softc *sc, device_t child) +{ + struct ahci_channel *achp; + struct ata_channel *chp; + + for (int i = 0; i < AHCI_MAX_PORTS; i++) { + achp = &sc->sc_channels[i]; + chp = &achp->ata_channel; + + if ((sc->sc_ahci_ports & (1U << i)) == 0) + continue; + + if (child == chp->atabus) + chp->atabus = NULL; + } +} + int ahci_detach(struct ahci_softc *sc, int flags) { @@ -502,10 +520,15 @@ ahci_detach(struct ahci_softc *sc, int f break; } - if (chp->atabus == NULL) + if (chp->atabus != NULL) { + if ((error = config_detach(chp->atabus, flags)) != 0) + return error; + + KASSERT(chp->atabus == NULL); + } + + if (chp->ch_flags & ATACH_DETACHED) continue; - if ((error = config_detach(chp->atabus, flags)) != 0) - return error; for (j = 0; j < sc->sc_ncmds; j++) bus_dmamap_destroy(sc->sc_dmat, achp->ahcic_datad[j]); @@ -517,8 +540,6 @@ ahci_detach(struct ahci_softc *sc, int f bus_dmamem_free(sc->sc_dmat, &achp->ahcic_cmd_tbl_seg, achp->ahcic_cmd_tbl_nseg); - chp->atabus = NULL; - ata_channel_detach(chp); } Index: src/sys/dev/ic/ahcisatavar.h diff -u src/sys/dev/ic/ahcisatavar.h:1.19 src/sys/dev/ic/ahcisatavar.h:1.20 --- src/sys/dev/ic/ahcisatavar.h:1.19 Mon Oct 22 20:13:47 2018 +++ src/sys/dev/ic/ahcisatavar.h Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisatavar.h,v 1.19 2018/10/22 20:13:47 jdolecek Exp $ */ +/* $NetBSD: ahcisatavar.h,v 1.20 2018/10/24 19:38:00 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -117,6 +117,7 @@ struct ahci_softc { void ahci_attach(struct ahci_softc *); int ahci_detach(struct ahci_softc *, int); +void ahci_childdetached(struct ahci_softc *, device_t); void ahci_resume(struct ahci_softc *); int ahci_intr(void *); Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.36 src/sys/dev/ic/siisata.c:1.37 --- src/sys/dev/ic/siisata.c:1.36 Mon Oct 22 20:13:47 2018 +++ src/sys/dev/ic/siisata.c Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.36 2018/10/22 20:13:47 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.37 2018/10/24 19:38:00 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.36 2018/10/22 20:13:47 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.37 2018/10/24 19:38:00 jdolecek Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -408,6 +408,19 @@ siisata_attach_port(struct siisata_softc return; } +void +siisata_childdetached(struct siisata_softc *sc, device_t child) +{ + struct ata_channel *chp; + + for (int i = 0; i < sc->sc_atac.atac_nchannels; i++) { + chp = sc->sc_chanarray[i]; + + if (child == chp->atabus) + chp->atabus = NULL; + } +} + int siisata_detach(struct siisata_softc *sc, int flags) { @@ -417,14 +430,22 @@ siisata_detach(struct siisata_softc *sc, struct ata_channel *chp; int i, j, error; + if (adapt->adapt_refcnt != 0) + return EBUSY; + for (i = 0; i < sc->sc_atac.atac_nchannels; i++) { schp = &sc->sc_channels[i]; chp = sc->sc_chanarray[i]; - if (chp->atabus == NULL) + if (chp->atabus != NULL) { + if ((error = config_detach(chp->atabus, flags)) != 0) + return error; + + KASSERT(chp->atabus == NULL); + } + + if (chp->ch_flags & ATACH_DETACHED) continue; - if ((error = config_detach(chp->atabus, flags)) != 0) - return error; for (j = 0; j < SIISATA_MAX_SLOTS; j++) bus_dmamap_destroy(sc->sc_dmat, schp->sch_datad[j]); @@ -436,14 +457,9 @@ siisata_detach(struct siisata_softc *sc, bus_dmamem_free(sc->sc_dmat, &schp->sch_prb_seg, schp->sch_prb_nseg); - chp->atabus = NULL; - ata_channel_detach(chp); } - if (adapt->adapt_refcnt != 0) - return EBUSY; - /* leave the chip in reset */ GRWRITE(sc, GR_GC, GR_GC_GLBLRST); Index: src/sys/dev/ic/siisatavar.h diff -u src/sys/dev/ic/siisatavar.h:1.8 src/sys/dev/ic/siisatavar.h:1.9 --- src/sys/dev/ic/siisatavar.h:1.8 Mon Oct 22 20:13:47 2018 +++ src/sys/dev/ic/siisatavar.h Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisatavar.h,v 1.8 2018/10/22 20:13:47 jdolecek Exp $ */ +/* $NetBSD: siisatavar.h,v 1.9 2018/10/24 19:38:00 jdolecek Exp $ */ /* from ahcisatavar.h */ @@ -114,6 +114,7 @@ struct siisata_softc { void siisata_attach(struct siisata_softc *); int siisata_detach(struct siisata_softc *, int); +void siisata_childdetached(struct siisata_softc *, device_t); void siisata_resume(struct siisata_softc *); int siisata_intr(void *); Index: src/sys/dev/pci/ahcisata_pci.c diff -u src/sys/dev/pci/ahcisata_pci.c:1.40 src/sys/dev/pci/ahcisata_pci.c:1.41 --- src/sys/dev/pci/ahcisata_pci.c:1.40 Mon Oct 22 21:40:45 2018 +++ src/sys/dev/pci/ahcisata_pci.c Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_pci.c,v 1.40 2018/10/22 21:40:45 jdolecek Exp $ */ +/* $NetBSD: ahcisata_pci.c,v 1.41 2018/10/24 19:38:00 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.40 2018/10/22 21:40:45 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.41 2018/10/24 19:38:00 jdolecek Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -208,11 +208,13 @@ static int ahci_pci_has_quirk(pci_vendo static int ahci_pci_match(device_t, cfdata_t, void *); static void ahci_pci_attach(device_t, device_t, void *); static int ahci_pci_detach(device_t, int); +static void ahci_pci_childdetached(device_t, device_t); static bool ahci_pci_resume(device_t, const pmf_qual_t *); -CFATTACH_DECL_NEW(ahcisata_pci, sizeof(struct ahci_pci_softc), - ahci_pci_match, ahci_pci_attach, ahci_pci_detach, NULL); +CFATTACH_DECL3_NEW(ahcisata_pci, sizeof(struct ahci_pci_softc), + ahci_pci_match, ahci_pci_attach, ahci_pci_detach, NULL, + NULL, ahci_pci_childdetached, DVF_DETACH_SHUTDOWN); static int ahci_pci_has_quirk(pci_vendor_id_t vendor, pci_product_id_t product) @@ -328,6 +330,15 @@ ahci_pci_attach(device_t parent, device_ aprint_error_dev(self, "couldn't establish power handler\n"); } +static void +ahci_pci_childdetached(device_t dv, device_t child) +{ + struct ahci_pci_softc *psc = device_private(dv); + struct ahci_softc *sc = &psc->ah_sc; + + ahci_childdetached(sc, child); +} + static int ahci_pci_detach(device_t dv, int flags) { Index: src/sys/dev/pci/siisata_pci.c diff -u src/sys/dev/pci/siisata_pci.c:1.18 src/sys/dev/pci/siisata_pci.c:1.19 --- src/sys/dev/pci/siisata_pci.c:1.18 Mon Oct 22 21:40:45 2018 +++ src/sys/dev/pci/siisata_pci.c Wed Oct 24 19:38:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata_pci.c,v 1.18 2018/10/22 21:40:45 jdolecek Exp $ */ +/* $NetBSD: siisata_pci.c,v 1.19 2018/10/24 19:38:00 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -51,7 +51,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: siisata_pci.c,v 1.18 2018/10/22 21:40:45 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata_pci.c,v 1.19 2018/10/24 19:38:00 jdolecek Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -74,6 +74,7 @@ struct siisata_pci_softc { static int siisata_pci_match(device_t, cfdata_t, void *); static void siisata_pci_attach(device_t, device_t, void *); static int siisata_pci_detach(device_t, int); +static void siisata_pci_childdetached(device_t, device_t); static bool siisata_pci_resume(device_t, const pmf_qual_t *); struct siisata_pci_board { @@ -110,8 +111,9 @@ static const struct siisata_pci_board si }, }; -CFATTACH_DECL_NEW(siisata_pci, sizeof(struct siisata_pci_softc), - siisata_pci_match, siisata_pci_attach, siisata_pci_detach, NULL); +CFATTACH_DECL3_NEW(siisata_pci, sizeof(struct siisata_pci_softc), + siisata_pci_match, siisata_pci_attach, siisata_pci_detach, NULL, + NULL, siisata_pci_childdetached, DVF_DETACH_SHUTDOWN); static const struct siisata_pci_board * siisata_pci_lookup(const struct pci_attach_args * pa) @@ -306,6 +308,15 @@ siisata_pci_detach(device_t dv, int flag return 0; } +static void +siisata_pci_childdetached(device_t dv, device_t child) +{ + struct siisata_pci_softc *psc = device_private(dv); + struct siisata_softc *sc = &psc->si_sc; + + siisata_childdetached(sc, child); +} + static bool siisata_pci_resume(device_t dv, const pmf_qual_t *qual) {