From owner-svn-src-all@freebsd.org Wed Oct 14 23:41:42 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6C914A15A43; Wed, 14 Oct 2015 23:41:42 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2B0C91E84; Wed, 14 Oct 2015 23:41:42 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t9ENffle050024; Wed, 14 Oct 2015 23:41:41 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9ENffmn050023; Wed, 14 Oct 2015 23:41:41 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201510142341.t9ENffmn050023@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Wed, 14 Oct 2015 23:41:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r289339 - stable/10/sys/dev/mmc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Oct 2015 23:41:42 -0000 Author: ian Date: Wed Oct 14 23:41:41 2015 New Revision: 289339 URL: https://svnweb.freebsd.org/changeset/base/289339 Log: MFC r261994, r275905, r275951, r276106, r283128, r285678: MMC driver fixes... If no compatible cards were found after probing the bus, say so. Don't deselect the card too soon. To set the block size or switch the function parameters, the card has to be in transfer state. If it is in the idle state, the commands are ignored. This caused us not to set the proper parameters that we later assume to be present, leading to downstream failures of the card / interface as our state machine mismatches the card's. Log mmc and sd command failures. Reporting of routine expected errors, such as timeouts while probing a bus or testing for a feature, is squelched. Also, error reporting is limited to 5 events per second, because when an sdcard goes bad on a low-end embedded board, flooding the console at high speed isn't helpful. Always select the card before we do the 4.x specific stuff and deselect it after setting the block size. This is a similar bug that was fixed elsewhere, but not here. This makes sure that we leave the card deselected at the end of the loop, and we don't send any commands to the card without it selected. Re-select the SD card before getting the SD status. On a couple Atmel boards, this prevents some error messages during enumeration and also gives us the correct erase block size. They appear to be harmless elsewhere. Deselect the sd card before re-selecting it when working around a problem with some cards that causes them to become deselected after probing for switch capabilities. The old workaround fixes the behavior with some cards, but causes problems with the cards the behave correctly and don't become deselected. Forcing a deselect then reselect appears to work correctly with all cards in initial testing. Modified: stable/10/sys/dev/mmc/mmc.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/mmc/mmc.c ============================================================================== --- stable/10/sys/dev/mmc/mmc.c Wed Oct 14 23:29:19 2015 (r289338) +++ stable/10/sys/dev/mmc/mmc.c Wed Oct 14 23:41:41 2015 (r289339) @@ -1379,6 +1379,21 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->hs_tran_speed = SD_MAX_HS; } } + + /* + * We deselect then reselect the card here. Some cards + * become unselected and timeout with the above two + * commands, although the state tables / diagrams in the + * standard suggest they go back to the transfer state. + * Other cards don't become deselected, and if we + * atttempt to blindly re-select them, we get timeout + * errors from some controllers. So we deselect then + * reselect to handle all situations. The only thing we + * use from the sd_status is the erase sector size, but + * it is still nice to get that right. + */ + mmc_select_card(sc, 0); + mmc_select_card(sc, ivar->rca); mmc_app_sd_status(sc, ivar->rca, ivar->raw_sd_status); mmc_app_decode_sd_status(ivar->raw_sd_status, &ivar->sd_status); @@ -1386,7 +1401,6 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->erase_sector = 16 << ivar->sd_status.au_size; } - mmc_select_card(sc, 0); /* Find max supported bus width. */ if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) && (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) @@ -1414,6 +1428,7 @@ mmc_discover_cards(struct mmc_softc *sc) child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); } + mmc_select_card(sc, 0); return; } mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid); @@ -1446,10 +1461,10 @@ mmc_discover_cards(struct mmc_softc *sc) break; } + mmc_select_card(sc, ivar->rca); + /* Only MMC >= 4.x cards support EXT_CSD. */ if (ivar->csd.spec_vers >= 4) { - /* Card must be selected to fetch EXT_CSD. */ - mmc_select_card(sc, ivar->rca); mmc_send_ext_csd(sc, ivar->raw_ext_csd); /* Handle extended capacity from EXT_CSD */ sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] + @@ -1472,7 +1487,6 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->hs_tran_speed = ivar->tran_speed; /* Find max supported bus width. */ ivar->bus_width = mmc_test_bus_width(sc); - mmc_select_card(sc, 0); /* Handle HC erase sector size. */ if (ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE] != 0) { ivar->erase_sector = 1024 * @@ -1506,6 +1520,7 @@ mmc_discover_cards(struct mmc_softc *sc) child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); } + mmc_select_card(sc, 0); } }