aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Vadot <manu@FreeBSD.org>2021-04-21 11:52:29 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2021-04-27 17:00:38 +0000
commit47bde7925b41887cb639e651289bc96ccb5b1c24 (patch)
tree8b0def9b964e1649886d4cabc1ea30b00ee35f15
parent4c1ecf5502e1b4b20553a2f996b73794cc7e6454 (diff)
downloadsrc-47bde7925b41887cb639e651289bc96ccb5b1c24.tar.gz
src-47bde7925b41887cb639e651289bc96ccb5b1c24.zip
mmccam: Add mmc_sim, a generic sim for mmc driver to use
This adds a generic sim that abstract a lot of what needs to be implemented in a driver for mmccam support. A new interface with three methods is added : - mmc_sim_get_tran_settings: Use to get what the controller supports in term of capabilities, freq etc ... - mmc_sim_set_tran_settings: Use to change the speed/freq/etc of the sdcard host controller - mmc_sim_cam_request: Used for MMCIO requests Differential Revision: https://reviews.freebsd.org/D27485 Reviewed by: kibab
-rw-r--r--sys/cam/mmc/mmc_sim.c194
-rw-r--r--sys/cam/mmc/mmc_sim.h43
-rw-r--r--sys/cam/mmc/mmc_sim_if.m54
-rw-r--r--sys/conf/files2
4 files changed, 293 insertions, 0 deletions
diff --git a/sys/cam/mmc/mmc_sim.c b/sys/cam/mmc/mmc_sim.c
new file mode 100644
index 000000000000..03269a0b3d4d
--- /dev/null
+++ b/sys/cam/mmc/mmc_sim.c
@@ -0,0 +1,194 @@
+/*-
+ * Copyright (c) 2020 Emmanuel Vadot <manu@FreeBSD.org>
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_sim.h>
+#include <cam/cam_xpt_sim.h>
+#include <cam/mmc/mmc_sim.h>
+
+#include "mmc_sim_if.h"
+
+static void
+mmc_cam_default_poll(struct cam_sim *sim)
+{
+
+ return;
+}
+
+static void
+mmc_cam_sim_default_action(struct cam_sim *sim, union ccb *ccb)
+{
+ struct mmc_sim *mmc_sim;
+ struct ccb_trans_settings_mmc mmc;
+ int rv;
+
+ mmc_sim = cam_sim_softc(sim);
+
+ if (mmc_sim == NULL) {
+ ccb->ccb_h.status = CAM_SEL_TIMEOUT;
+ xpt_done(ccb);
+ return;
+ }
+
+ mtx_assert(&mmc_sim->mtx, MA_OWNED);
+
+ switch (ccb->ccb_h.func_code) {
+ case XPT_PATH_INQ:
+ rv = MMC_SIM_GET_TRAN_SETTINGS(mmc_sim->dev, &mmc);
+ if (rv != 0) {
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ } else {
+ mmc_path_inq(&ccb->cpi, "Deglitch Networks",
+ sim, mmc.host_max_data);
+ }
+ break;
+ case XPT_GET_TRAN_SETTINGS:
+ {
+ struct ccb_trans_settings *cts = &ccb->cts;
+
+ rv = MMC_SIM_GET_TRAN_SETTINGS(mmc_sim->dev, &cts->proto_specific.mmc);
+ if (rv != 0)
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ else {
+ cts->protocol = PROTO_MMCSD;
+ cts->protocol_version = 1;
+ cts->transport = XPORT_MMCSD;
+ cts->transport_version = 1;
+ cts->xport_specific.valid = 0;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ }
+ break;
+ }
+ case XPT_SET_TRAN_SETTINGS:
+ {
+ struct ccb_trans_settings *cts = &ccb->cts;
+
+ rv = MMC_SIM_SET_TRAN_SETTINGS(mmc_sim->dev, &cts->proto_specific.mmc);
+ if (rv != 0)
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ else
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ break;
+ }
+ case XPT_RESET_BUS:
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ break;
+ case XPT_MMC_IO:
+ {
+ rv = MMC_SIM_CAM_REQUEST(mmc_sim->dev, ccb);
+ if (rv != 0)
+ ccb->ccb_h.status = CAM_REQ_INPROG;
+ else
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ return;
+ /* NOTREACHED */
+ break;
+ }
+ default:
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ break;
+ }
+ xpt_done(ccb);
+ return;
+}
+
+int
+mmc_cam_sim_alloc(device_t dev, const char *name, struct mmc_sim *mmc_sim)
+{
+ char sim_name[64], mtx_name[64];
+
+ mmc_sim->dev = dev;
+
+ if ((mmc_sim->devq = cam_simq_alloc(1)) == NULL) {
+ goto fail;
+ }
+
+ snprintf(sim_name, sizeof(sim_name), "%s_sim", name);
+ snprintf(mtx_name, sizeof(mtx_name), "%s_mtx", name);
+
+ mtx_init(&mmc_sim->mtx, sim_name, NULL, MTX_DEF);
+ mmc_sim->sim = cam_sim_alloc_dev(mmc_cam_sim_default_action,
+ mmc_cam_default_poll,
+ name, mmc_sim, dev,
+ &mmc_sim->mtx, 1, 1, mmc_sim->devq);
+
+ if (mmc_sim->sim == NULL) {
+ cam_simq_free(mmc_sim->devq);
+ device_printf(dev, "cannot allocate CAM SIM\n");
+ goto fail;
+ }
+
+ mtx_lock(&mmc_sim->mtx);
+ if (xpt_bus_register(mmc_sim->sim, dev, 0) != 0) {
+ device_printf(dev, "cannot register SCSI pass-through bus\n");
+ cam_sim_free(mmc_sim->sim, FALSE);
+ cam_simq_free(mmc_sim->devq);
+ mtx_unlock(&mmc_sim->mtx);
+ goto fail;
+ }
+
+ mtx_unlock(&mmc_sim->mtx);
+
+ return (0);
+
+fail:
+ mmc_cam_sim_free(mmc_sim);
+ return (1);
+}
+
+void
+mmc_cam_sim_free(struct mmc_sim *mmc_sim)
+{
+
+ if (mmc_sim->sim != NULL) {
+ mtx_lock(&mmc_sim->mtx);
+ xpt_bus_deregister(cam_sim_path(mmc_sim->sim));
+ cam_sim_free(mmc_sim->sim, FALSE);
+ mtx_unlock(&mmc_sim->mtx);
+ }
+
+ if (mmc_sim->devq != NULL)
+ cam_simq_free(mmc_sim->devq);
+}
+
+void
+mmc_cam_sim_discover(struct mmc_sim *mmc_sim)
+{
+
+ mmccam_start_discovery(mmc_sim->sim);
+}
diff --git a/sys/cam/mmc/mmc_sim.h b/sys/cam/mmc/mmc_sim.h
new file mode 100644
index 000000000000..629144656e51
--- /dev/null
+++ b/sys/cam/mmc/mmc_sim.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2020 Emmanuel Vadot <manu@FreeBSD.org>
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __MMC_SIM_H__
+#define __MMC_SIM_H__
+
+struct mmc_sim {
+ struct mmc_cam_sim_softc *sc;
+ struct mtx mtx;
+ struct cam_devq *devq;
+ struct cam_sim *sim;
+ device_t dev;
+};
+
+int mmc_cam_sim_alloc(device_t dev, const char *name, struct mmc_sim *mmc_sim);
+void mmc_cam_sim_free(struct mmc_sim *sim);
+void mmc_cam_sim_discover(struct mmc_sim *mmc_sim);
+
+#endif /* __MMC_SIM_H__ */
diff --git a/sys/cam/mmc/mmc_sim_if.m b/sys/cam/mmc/mmc_sim_if.m
new file mode 100644
index 000000000000..f1b88fc05ef5
--- /dev/null
+++ b/sys/cam/mmc/mmc_sim_if.m
@@ -0,0 +1,54 @@
+#-
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2020 Emmanuel Vadot <manu@FreeBSD.org>
+#
+# 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+# $FreeBSD$
+
+#include <sys/types.h>
+#include <sys/callout.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_sim.h>
+#include <cam/cam_xpt_sim.h>
+#include <cam/mmc/mmc_sim.h>
+
+INTERFACE mmc_sim;
+
+METHOD int get_tran_settings {
+ device_t dev;
+ struct ccb_trans_settings_mmc *cts;
+};
+
+METHOD int set_tran_settings {
+ device_t dev;
+ struct ccb_trans_settings_mmc *cts;
+};
+
+METHOD int cam_request {
+ device_t dev;
+ union ccb *ccb;
+};
diff --git a/sys/conf/files b/sys/conf/files
index 6d7f185e79fe..40b02aba28d6 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -121,6 +121,8 @@ cam/ctl/ctl_error.c optional ctl
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_sim.c optional scbus mmccam
+cam/mmc/mmc_sim_if.m optional scbus mmccam
cam/mmc/mmc_da.c optional scbus mmccam da
cam/scsi/scsi_da.c optional da
cam/scsi/scsi_pass.c optional pass