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:
parent
bba52ecadd
commit
02c474b481
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user