detach the controller itself on shutdown; adjust to not detach already
detached atabus/channel
This commit is contained in:
parent
a5b154d28f
commit
654326fabc
@ -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
|
||||
|
@ -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 *chp)
|
||||
return;
|
||||
|
||||
ata_channel_destroy(chp);
|
||||
|
||||
chp->ch_flags |= ATACH_DETACHED;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 flags)
|
||||
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 flags)
|
||||
bus_dmamem_free(sc->sc_dmat, &achp->ahcic_cmd_tbl_seg,
|
||||
achp->ahcic_cmd_tbl_nseg);
|
||||
|
||||
chp->atabus = NULL;
|
||||
|
||||
ata_channel_detach(chp);
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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 *sc, int port)
|
||||
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, int flags)
|
||||
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, int flags)
|
||||
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);
|
||||
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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_vendor_id_t, pci_product_id_t);
|
||||
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_t self, void *aux)
|
||||
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)
|
||||
{
|
||||
|
@ -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 siisata_pci_boards[] = {
|
||||
},
|
||||
};
|
||||
|
||||
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 flags)
|
||||
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user