Module Name:    src
Committed By:   jakllsch
Date:           Thu Dec 20 14:37:00 UTC 2012

Modified Files:
        src/sys/dev/cardbus: sdhc_cardbus.c
        src/sys/dev/sdmmc: sdhc.c sdhcvar.h

Log Message:
Change sdhc_detach so that it detaches all host controllers at once.
This should make multiple slot controllers, for example those with
a controller on more than one PCI/CardBus BAR, detach with fewer bugs.
Tested with as-of-yet-uncommited sdhc_pci changes on a single-host
ExpressCard JMicron JMB38[89].


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/cardbus/sdhc_cardbus.c
cvs rdiff -u -r1.35 -r1.36 src/sys/dev/sdmmc/sdhc.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/sdmmc/sdhcvar.h

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/cardbus/sdhc_cardbus.c
diff -u src/sys/dev/cardbus/sdhc_cardbus.c:1.4 src/sys/dev/cardbus/sdhc_cardbus.c:1.5
--- src/sys/dev/cardbus/sdhc_cardbus.c:1.4	Thu Feb  2 22:49:17 2012
+++ src/sys/dev/cardbus/sdhc_cardbus.c	Thu Dec 20 14:37:00 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sdhc_cardbus.c,v 1.4 2012/02/02 22:49:17 nonaka Exp $	*/
+/*	$NetBSD: sdhc_cardbus.c,v 1.5 2012/12/20 14:37:00 jakllsch Exp $	*/
 
 /*
  * Copyright (c) 2010 NONAKA Kimihiro <non...@netbsd.org>
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdhc_cardbus.c,v 1.4 2012/02/02 22:49:17 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc_cardbus.c,v 1.5 2012/12/20 14:37:00 jakllsch Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -191,7 +191,7 @@ sdhc_cardbus_detach(device_t self, int f
 	struct cardbus_devfunc *ct = sc->sc_ct;
 	int rv;
 
-	rv = sdhc_detach((device_t)sc->sc.sc_host[0], flags);
+	rv = sdhc_detach(&sc->sc, flags);
 	if (rv)
 		return rv;
 	if (sc->sc_ih != NULL) {

Index: src/sys/dev/sdmmc/sdhc.c
diff -u src/sys/dev/sdmmc/sdhc.c:1.35 src/sys/dev/sdmmc/sdhc.c:1.36
--- src/sys/dev/sdmmc/sdhc.c:1.35	Thu Dec 13 06:43:37 2012
+++ src/sys/dev/sdmmc/sdhc.c	Thu Dec 20 14:37:00 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sdhc.c,v 1.35 2012/12/13 06:43:37 riastradh Exp $	*/
+/*	$NetBSD: sdhc.c,v 1.36 2012/12/20 14:37:00 jakllsch Exp $	*/
 /*	$OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $	*/
 
 /*
@@ -23,7 +23,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.35 2012/12/13 06:43:37 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.36 2012/12/20 14:37:00 jakllsch Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -62,6 +62,7 @@ struct sdhc_host {
 
 	bus_space_tag_t iot;		/* host register set tag */
 	bus_space_handle_t ioh;		/* host register set handle */
+	bus_size_t ios;			/* host register space size */
 	bus_dma_tag_t dmat;		/* host DMA tag */
 
 	device_t sdmmc;			/* generic SD/MMC device */
@@ -257,6 +258,7 @@ sdhc_host_found(struct sdhc_softc *sc, b
 	hp->sc = sc;
 	hp->iot = iot;
 	hp->ioh = ioh;
+	hp->ios = iosize;
 	hp->dmat = sc->sc_dmat;
 
 	mutex_init(&hp->host_mtx, MUTEX_DEFAULT, IPL_SDMMC);
@@ -430,20 +432,40 @@ err1:
 }
 
 int
-sdhc_detach(device_t dev, int flags)
+sdhc_detach(struct sdhc_softc *sc, int flags)
 {
-	struct sdhc_host *hp = (struct sdhc_host *)dev;
-	struct sdhc_softc *sc = hp->sc;
+	struct sdhc_host *hp;
 	int rv = 0;
 
-	if (hp->sdmmc)
-		rv = config_detach(hp->sdmmc, flags);
-
-	cv_destroy(&hp->intr_cv);
-	mutex_destroy(&hp->intr_mtx);
-	mutex_destroy(&hp->host_mtx);
-	free(hp, M_DEVBUF);
-	sc->sc_host[--sc->sc_nhosts] = NULL;
+	for (size_t n = 0; n < sc->sc_nhosts; n++) {
+		hp = sc->sc_host[n];
+		if (hp == NULL)
+			continue;
+		if (hp->sdmmc != NULL) {
+			rv = config_detach(hp->sdmmc, flags);
+			if (rv)
+				break;
+			hp->sdmmc = NULL;
+		}
+		/* disable interrupts */
+		if ((flags & DETACH_FORCE) == 0) {
+			if (ISSET(hp->sc->sc_flags, SDHC_FLAG_32BIT_ACCESS)) {
+				HWRITE4(hp, SDHC_NINTR_SIGNAL_EN, 0);
+			} else {
+				HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, 0);
+			}
+			sdhc_soft_reset(hp, SDHC_RESET_ALL);
+		}
+		cv_destroy(&hp->intr_cv);
+		mutex_destroy(&hp->intr_mtx);
+		mutex_destroy(&hp->host_mtx);
+		if (hp->ios > 0) {
+			bus_space_unmap(hp->iot, hp->ioh, hp->ios);
+			hp->ios = 0;
+		}
+		free(hp, M_DEVBUF);
+		sc->sc_host[n] = NULL;
+	}
 
 	return rv;
 }

Index: src/sys/dev/sdmmc/sdhcvar.h
diff -u src/sys/dev/sdmmc/sdhcvar.h:1.11 src/sys/dev/sdmmc/sdhcvar.h:1.12
--- src/sys/dev/sdmmc/sdhcvar.h:1.11	Thu Dec 13 06:43:37 2012
+++ src/sys/dev/sdmmc/sdhcvar.h	Thu Dec 20 14:37:00 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sdhcvar.h,v 1.11 2012/12/13 06:43:37 riastradh Exp $	*/
+/*	$NetBSD: sdhcvar.h,v 1.12 2012/12/20 14:37:00 jakllsch Exp $	*/
 /*	$OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $	*/
 
 /*
@@ -63,7 +63,7 @@ struct sdhc_softc {
 int	sdhc_host_found(struct sdhc_softc *, bus_space_tag_t,
 	    bus_space_handle_t, bus_size_t);
 int	sdhc_intr(void *);
-int	sdhc_detach(device_t, int);
+int	sdhc_detach(struct sdhc_softc *, int);
 bool	sdhc_suspend(device_t, const pmf_qual_t *);
 bool	sdhc_resume(device_t, const pmf_qual_t *);
 bool	sdhc_shutdown(device_t, int);

Reply via email to