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
This commit is contained in:
Ilya Bakulin 2017-09-15 19:47:44 +00:00
parent bba52ecadd
commit 02c474b481
8 changed files with 34 additions and 221 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -1,126 +0,0 @@
/*-
* Copyright (c) 2015 Ilya Bakulin <ilya@bakulin.de>
* 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/time.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/interrupt.h>
#include <sys/sbuf.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
#include <sys/condvar.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_queue.h>
#include <cam/cam_periph.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt.h>
#include <cam/cam_xpt_sim.h>
#include <cam/cam_xpt_periph.h>
#include <cam/cam_xpt_internal.h>
#include <cam/cam_debug.h>
#include <cam/mmc/mmc.h>
#include <cam/mmc/mmc_bus.h>
#include <cam/mmc/mmc_sdio.h>
#include <machine/stdarg.h> /* for xpt_print below */
#include <machine/_inttypes.h> /* 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);
}

View File

@ -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

View File

@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <cam/mmc/mmc.h>
#include <cam/mmc/mmc_bus.h>
#include <cam/mmc/mmc_sdio.h>
#include <machine/stdarg.h> /* for xpt_print below */
#include <machine/_inttypes.h> /* 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);

View File

@ -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

View File

@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$");
#include <dev/mmc/host/dwmmc_reg.h>
#include <dev/mmc/host/dwmmc_var.h>
#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