From 02c474b481af5efa9cc8104177669ebaec34e003 Mon Sep 17 00:00:00 2001 From: Ilya Bakulin Date: Fri, 15 Sep 2017 19:47:44 +0000 Subject: [PATCH] Miscellaneous fixes and improvements to MMCCAM stack * Demote the level of several debug messages to CAM_DEBUG_TRACE * Add detection for SDHC cards that can do 1.8V. No voltage switch sequence is issued yet; * Don't create a separate LUN for each SDIO function. We need just one to make pass(4) attach; * Remove obsolete mmc_sdio* files. SDIO functionality will be moved into the separate device that will manage a new sdio(4) bus; * Terminate probing if got no reply to CMD0; * Make bcm2835 SDHCI host controller driver compile with 'option MMCCAM'. Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D12109 --- sys/arm/broadcom/bcm2835/bcm2835_sdhci.c | 2 + sys/cam/mmc/mmc.h | 1 + sys/cam/mmc/mmc_da.c | 6 +- sys/cam/mmc/mmc_sdio.c | 126 ----------------------- sys/cam/mmc/mmc_sdio.h | 64 ------------ sys/cam/mmc/mmc_xpt.c | 51 +++++---- sys/conf/files | 1 - sys/dev/mmc/host/dwmmc.c | 4 + 8 files changed, 34 insertions(+), 221 deletions(-) delete mode 100644 sys/cam/mmc/mmc_sdio.c delete mode 100644 sys/cam/mmc/mmc_sdio.h diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 0471d42ad452..c2f752447358 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -685,4 +685,6 @@ static driver_t bcm_sdhci_driver = { DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass, NULL, NULL); MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1); +#ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_bcm); +#endif diff --git a/sys/cam/mmc/mmc.h b/sys/cam/mmc/mmc.h index 9fae837e9e03..2e31f029000b 100644 --- a/sys/cam/mmc/mmc.h +++ b/sys/cam/mmc/mmc.h @@ -87,6 +87,7 @@ struct mmc_params { #define CARD_FEATURE_SDIO 0x1 << 2 #define CARD_FEATURE_SD20 0x1 << 3 #define CARD_FEATURE_MMC 0x1 << 4 +#define CARD_FEATURE_18V 0x1 << 5 uint8_t sdio_func_count; } __packed; diff --git a/sys/cam/mmc/mmc_da.c b/sys/cam/mmc/mmc_da.c index 31bbf000e14c..6969e26c70bd 100644 --- a/sys/cam/mmc/mmc_da.c +++ b/sys/cam/mmc/mmc_da.c @@ -378,8 +378,7 @@ sddaopen(struct disk *dp) return (error); } - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, - ("sddaopen\n")); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaopen\n")); softc = (struct sdda_softc *)periph->softc; softc->flags |= SDDA_FLAG_OPEN; @@ -403,8 +402,7 @@ sddaclose(struct disk *dp) cam_periph_lock(periph); - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, - ("sddaclose\n")); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaclose\n")); while (softc->refcount != 0) cam_periph_sleep(periph, &softc->refcount, PRIBIO, "sddaclose", 1); diff --git a/sys/cam/mmc/mmc_sdio.c b/sys/cam/mmc/mmc_sdio.c deleted file mode 100644 index 093da15d6fac..000000000000 --- a/sys/cam/mmc/mmc_sdio.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2015 Ilya Bakulin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include /* for xpt_print below */ -#include /* for PRIu64 */ -#include "opt_cam.h" - - -void -sdio_print_stupid_message(struct cam_periph *periph) { - - CAM_DEBUG(periph->path, CAM_DEBUG_INFO, - ("%s\n", __func__)); -} - -/* - * f - function to read from / write to - * wr - is write - * adr - address to r/w - * data - actual data to write - */ -void sdio_fill_mmcio_rw_direct(union ccb *ccb, uint8_t f, uint8_t wr, uint32_t adr, uint8_t *data) { - struct ccb_mmcio *mmcio; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("sdio_fill_mmcio(f=%d, wr=%d, adr=%02x, data=%02x)\n", f, wr, adr, (data == NULL ? 0 : *data))); - mmcio = &ccb->mmcio; - - mmcio->cmd.opcode = SD_IO_RW_DIRECT; - mmcio->cmd.arg = SD_IO_RW_FUNC(f) | SD_IO_RW_ADR(adr); - if (wr) - mmcio->cmd.arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(*data); - mmcio->cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; - mmcio->cmd.data->len = 0; -} - -uint8_t sdio_parse_mmcio_rw_direct(union ccb *ccb, uint8_t *data) { - struct ccb_mmcio *mmcio; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("sdio_parse_mmcio(datap=%p)\n", data)); - mmcio = &ccb->mmcio; - - if (mmcio->cmd.error) - return (mmcio->cmd.error); - if (mmcio->cmd.resp[0] & R5_COM_CRC_ERROR) - return (MMC_ERR_BADCRC); - if (mmcio->cmd.resp[0] & (R5_ILLEGAL_COMMAND | R5_FUNCTION_NUMBER)) - return (MMC_ERR_INVALID); - if (mmcio->cmd.resp[0] & R5_OUT_OF_RANGE) - return (MMC_ERR_FAILED); - - /* Just for information... */ - if (R5_IO_CURRENT_STATE(mmcio->cmd.resp[0]) != 1) - printf("!!! SDIO state %d\n", R5_IO_CURRENT_STATE(mmcio->cmd.resp[0])); - - if (mmcio->cmd.resp[0] & R5_ERROR) - printf("An error was detected!\n"); - - if (mmcio->cmd.resp[0] & R5_COM_CRC_ERROR) - printf("A CRC error was detected!\n"); - - if (data != NULL) - *data = (uint8_t) (mmcio->cmd.resp[0] & 0xff); - return (MMC_ERR_NONE); - -} diff --git a/sys/cam/mmc/mmc_sdio.h b/sys/cam/mmc/mmc_sdio.h deleted file mode 100644 index 6d22ffc02c13..000000000000 --- a/sys/cam/mmc/mmc_sdio.h +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2014 Ilya Bakulin. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Portions of this software may have been developed with reference to - * the SD Simplified Specification. The following disclaimer may apply: - * - * The following conditions apply to the release of the simplified - * specification ("Simplified Specification") by the SD Card Association and - * the SD Group. The Simplified Specification is a subset of the complete SD - * Specification which is owned by the SD Card Association and the SD - * Group. This Simplified Specification is provided on a non-confidential - * basis subject to the disclaimers below. Any implementation of the - * Simplified Specification may require a license from the SD Card - * Association, SD Group, SD-3C LLC or other third parties. - * - * Disclaimers: - * - * The information contained in the Simplified Specification is presented only - * as a standard specification for SD Cards and SD Host/Ancillary products and - * is provided "AS-IS" without any representations or warranties of any - * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD - * Card Association for any damages, any infringements of patents or other - * right of the SD Group, SD-3C LLC, the SD Card Association or any third - * parties, which may result from its use. No license is granted by - * implication, estoppel or otherwise under any patent or other rights of the - * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing - * herein shall be construed as an obligation by the SD Group, the SD-3C LLC - * or the SD Card Association to disclose or distribute any technical - * information, know-how or other confidential information to any third party. - * - * $FreeBSD$ - */ - -/* - * Various SDIO-related stuff - */ - -#ifndef CAM_MMC_SDIO_H -#define CAM_MMC_SDIO_H - -void sdio_print_stupid_message(struct cam_periph *periph); -void sdio_fill_mmcio_rw_direct(union ccb *ccb, uint8_t f, uint8_t wr, uint32_t adr, uint8_t *data); -uint8_t sdio_parse_mmcio_rw_direct(union ccb *ccb, uint8_t *data); -#endif diff --git a/sys/cam/mmc/mmc_xpt.c b/sys/cam/mmc/mmc_xpt.c index 0142a6f07916..696cff384993 100644 --- a/sys/cam/mmc/mmc_xpt.c +++ b/sys/cam/mmc/mmc_xpt.c @@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include /* for xpt_print below */ #include /* for PRIu64 */ @@ -162,6 +161,7 @@ typedef struct { union ccb saved_ccb; uint32_t flags; #define PROBE_FLAG_ACMD_SENT 0x1 /* CMD55 is sent, card expects ACMD */ + uint8_t acmd41_count; /* how many times ACMD41 has been issued */ struct cam_periph *periph; } mmcprobe_softc; @@ -219,6 +219,8 @@ mmc_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, printf("Got AC_PATH_REGISTERED -- whatever...\n"); } else if (async_code == AC_PATH_DEREGISTERED ) { printf("Got AC_PATH_DEREGISTERED -- whatever...\n"); + } else if (async_code == AC_UNIT_ATTENTION) { + printf("Got interrupt generated by the card and ignored it\n"); } else panic("Unknown async code\n"); } @@ -299,9 +301,9 @@ mmc_scan_lun(struct cam_periph *periph, struct cam_path *path, static void mmc_action(union ccb *start_ccb) { - CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, + CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mmc_action! func_code=%x, action %s\n", start_ccb->ccb_h.func_code, - xpt_action_name(start_ccb->ccb_h.func_code))); + xpt_action_name(start_ccb->ccb_h.func_code))); switch (start_ccb->ccb_h.func_code) { case XPT_SCAN_BUS: @@ -486,6 +488,7 @@ mmcprobe_register(struct cam_periph *periph, void *arg) } softc->flags = 0; + softc->acmd41_count = 0; periph->softc = softc; softc->periph = periph; softc->action = PROBE_INVALID; @@ -672,8 +675,12 @@ mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb) * We set CCS bit because we do support SDHC cards. * XXX: Don't set CCS if no response to CMD8. */ - mmcio->cmd.arg = MMC_OCR_CCS | mmcp->card_ocr; /* CCS + ocr */ + uint32_t cmd_arg = MMC_OCR_CCS | mmcp->card_ocr; /* CCS + ocr */ + if (softc->acmd41_count < 10 && mmcp->card_ocr != 0 ) + cmd_arg |= MMC_OCR_S18R; + mmcio->cmd.arg = cmd_arg; mmcio->cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; + softc->acmd41_count++; } else { mmcio->cmd.opcode = MMC_APP_CMD; /* CMD 55 */ mmcio->cmd.arg = 0; /* rca << 16 */ @@ -769,8 +776,9 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) /* There was a device there, but now it's gone... */ if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { xpt_async(AC_LOST_DEVICE, path, NULL); - PROBE_SET_ACTION(softc, PROBE_INVALID); } + PROBE_SET_ACTION(softc, PROBE_INVALID); + break; } path->device->protocol = PROTO_MMCSD; PROBE_SET_ACTION(softc, PROBE_SEND_IF_COND); @@ -936,12 +944,18 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) mmcp->card_features |= CARD_FEATURE_SDHC; } - } else { - CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, - ("Card not ready: %08x\n", mmcio->cmd.resp[0])); - /* Send CMD55+ACMD41 once again */ - PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); - } + /* Whether the card supports 1.8V signaling */ + if (mmcio->cmd.resp[0] & MMC_OCR_S18A) { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card supports 1.8V signaling\n")); + mmcp->card_features |= CARD_FEATURE_18V; + } + } else { + CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, + ("Card not ready: %08x\n", mmcio->cmd.resp[0])); + /* Send CMD55+ACMD41 once again */ + PROBE_SET_ACTION(softc, PROBE_SEND_APP_OP_COND); + } break; } @@ -1054,21 +1068,6 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb) xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); } - - /* Also announce each SDIO function */ - struct mmc_params *mmcp = &path->device->mmc_ident_data; - - for (int i = 0; i < mmcp->sdio_func_count; i++) { - struct cam_path *newpath; - cam_status status; - status = xpt_create_path(&newpath, NULL, - done_ccb->ccb_h.path_id, 0, i + 1); - if (status != CAM_REQ_CMP) - printf("xpt_create_path failed" - " with status %#x\n", - status); - xpt_async(AC_FOUND_DEVICE, newpath, done_ccb); - } } if (softc->action == PROBE_DONE || softc->action == PROBE_INVALID) { cam_periph_invalidate(periph); diff --git a/sys/conf/files b/sys/conf/files index 08ed66825622..099b65d5817a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -112,7 +112,6 @@ cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl cam/mmc/mmc_xpt.c optional scbus mmccam cam/mmc/mmc_da.c optional scbus mmccam da -cam/mmc/mmc_sdio.c optional scbus mmccam cam/scsi/scsi_da.c optional da cam/scsi/scsi_low.c optional ncv | nsp | stg cam/scsi/scsi_pass.c optional pass diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c index 18b6dee4dad6..cb374a0e240e 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_mmccam.h" + #include "mmcbr_if.h" #define dprintf(x, arg...) @@ -1181,4 +1183,6 @@ static devclass_t dwmmc_devclass; DRIVER_MODULE(dwmmc, simplebus, dwmmc_driver, dwmmc_devclass, NULL, NULL); DRIVER_MODULE(dwmmc, ofwbus, dwmmc_driver, dwmmc_devclass, NULL, NULL); +#ifndef MMCCAM MMC_DECLARE_BRIDGE(dwmmc); +#endif