diff options
Diffstat (limited to 'sys/dev/sdmmc/sdmmc.c')
-rw-r--r-- | sys/dev/sdmmc/sdmmc.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/sys/dev/sdmmc/sdmmc.c b/sys/dev/sdmmc/sdmmc.c index 6a7fac743a8..9b46846eac0 100644 --- a/sys/dev/sdmmc/sdmmc.c +++ b/sys/dev/sdmmc/sdmmc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sdmmc.c,v 1.14 2007/09/11 13:39:34 gilles Exp $ */ +/* $OpenBSD: sdmmc.c,v 1.15 2008/11/24 07:32:08 blambert Exp $ */ /* * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> @@ -108,7 +108,7 @@ sdmmc_attach(struct device *parent, struct device *self, void *aux) TAILQ_INIT(&sc->sc_intrq); sdmmc_init_task(&sc->sc_discover_task, sdmmc_discover_task, sc); sdmmc_init_task(&sc->sc_intr_task, sdmmc_intr_task, sc); - lockinit(&sc->sc_lock, PRIBIO, DEVNAME(sc), 0, LK_CANRECURSE); + lockinit(&sc->sc_lock, PRIBIO, DEVNAME(sc), 0, 0); #ifdef SDMMC_IOCTL if (bio_register(self, sdmmc_ioctl) != 0) @@ -174,8 +174,11 @@ sdmmc_task_thread(void *arg) } splx(s); - if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) + if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) { + SDMMC_LOCK(sc); sdmmc_card_detach(sc, DETACH_FORCE); + SDMMC_UNLOCK(sc); + } sc->sc_task_thread = NULL; wakeup(sc); @@ -233,7 +236,9 @@ sdmmc_discover_task(void *arg) } else { if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) { CLR(sc->sc_flags, SMF_CARD_PRESENT); + SDMMC_LOCK(sc); sdmmc_card_detach(sc, DETACH_FORCE); + SDMMC_UNLOCK(sc); } } } @@ -299,6 +304,8 @@ sdmmc_card_detach(struct sdmmc_softc *sc, int flags) { struct sdmmc_function *sf, *sfnext; + SDMMC_ASSERT_LOCKED(sc); + DPRINTF(1,("%s: detach card\n", DEVNAME(sc))); if (ISSET(sc->sc_flags, SMF_CARD_ATTACHED)) { @@ -332,6 +339,8 @@ sdmmc_enable(struct sdmmc_softc *sc) u_int32_t host_ocr; int error; + SDMMC_ASSERT_LOCKED(sc); + /* * Calculate the equivalent of the card OCR from the host * capabilities and select the maximum supported bus voltage. @@ -372,6 +381,7 @@ sdmmc_enable(struct sdmmc_softc *sc) err: if (error != 0) sdmmc_disable(sc); + return error; } @@ -442,6 +452,9 @@ sdmmc_function_free(struct sdmmc_function *sf) int sdmmc_scan(struct sdmmc_softc *sc) { + + SDMMC_ASSERT_LOCKED(sc); + /* Scan for I/O functions. */ if (ISSET(sc->sc_flags, SMF_IO_MODE)) sdmmc_io_scan(sc); @@ -504,7 +517,7 @@ sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd) struct sdmmc_command acmd; int error; - SDMMC_LOCK(sc); + SDMMC_ASSERT_LOCKED(sc); bzero(&acmd, sizeof acmd); acmd.c_opcode = MMC_APP_CMD; @@ -513,18 +526,15 @@ sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd) error = sdmmc_mmc_command(sc, &acmd); if (error != 0) { - SDMMC_UNLOCK(sc); return error; } if (!ISSET(MMC_R1(acmd.c_resp), MMC_R1_APP_CMD)) { /* Card does not support application commands. */ - SDMMC_UNLOCK(sc); return ENODEV; } error = sdmmc_mmc_command(sc, cmd); - SDMMC_UNLOCK(sc); return error; } @@ -538,7 +548,7 @@ sdmmc_mmc_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd) { int error; - SDMMC_LOCK(sc); + SDMMC_ASSERT_LOCKED(sc); sdmmc_chip_exec_command(sc->sct, sc->sch, cmd); @@ -549,7 +559,6 @@ sdmmc_mmc_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd) error = cmd->c_error; wakeup(cmd); - SDMMC_UNLOCK(sc); return error; } @@ -561,6 +570,8 @@ sdmmc_go_idle_state(struct sdmmc_softc *sc) { struct sdmmc_command cmd; + SDMMC_ASSERT_LOCKED(sc); + bzero(&cmd, sizeof cmd); cmd.c_opcode = MMC_GO_IDLE_STATE; cmd.c_flags = SCF_CMD_BC | SCF_RSP_R0; @@ -577,6 +588,8 @@ sdmmc_set_relative_addr(struct sdmmc_softc *sc, { struct sdmmc_command cmd; + SDMMC_ASSERT_LOCKED(sc); + bzero(&cmd, sizeof cmd); if (ISSET(sc->sc_flags, SMF_SD_MODE)) { @@ -699,12 +712,14 @@ sdmmc_ioctl(struct device *self, u_long request, caddr_t addr) cmd.c_datalen = ucmd->c_datalen; } + SDMMC_LOCK(sc); if (request == SDIOCEXECMMC) error = sdmmc_mmc_command(sc, &cmd); else error = sdmmc_app_command(sc, &cmd); if (error && !cmd.c_error) cmd.c_error = error; + SDMMC_UNLOCK(sc); bcopy(&cmd.c_resp, ucmd->c_resp, sizeof cmd.c_resp); ucmd->c_flags = cmd.c_flags; |