Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107656451
D30038.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D30038.diff
View Options
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -253,6 +253,9 @@
XPT_REPROBE_LUN = 0x38 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
/* Query device capacity and notify GEOM */
+ XPT_MMC_SET_TRAN_SETTINGS = 0x40 | XPT_FC_DEV_QUEUED,
+ XPT_MMC_GET_TRAN_SETTINGS = 0x41 | XPT_FC_DEV_QUEUED,
+
/* Vendor Unique codes: 0x80->0x8F */
XPT_VUNIQUE = 0x80
} xpt_opcode;
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -2702,6 +2702,8 @@
case XPT_NVME_IO:
case XPT_NVME_ADMIN:
case XPT_MMC_IO:
+ case XPT_MMC_GET_TRAN_SETTINGS:
+ case XPT_MMC_SET_TRAN_SETTINGS:
case XPT_RESET_DEV:
case XPT_ENG_EXEC:
case XPT_SMP_IO:
diff --git a/sys/cam/mmc/mmc_sim.h b/sys/cam/mmc/mmc_sim.h
--- a/sys/cam/mmc/mmc_sim.h
+++ b/sys/cam/mmc/mmc_sim.h
@@ -28,12 +28,16 @@
#ifndef __MMC_SIM_H__
#define __MMC_SIM_H__
+#include <sys/taskqueue.h>
+
struct mmc_sim {
struct mmc_cam_sim_softc *sc;
struct mtx mtx;
struct cam_devq *devq;
struct cam_sim *sim;
device_t dev;
+ struct task sim_task;
+ union ccb *ccb;
};
int mmc_cam_sim_alloc(device_t dev, const char *name, struct mmc_sim *mmc_sim);
diff --git a/sys/cam/mmc/mmc_sim.c b/sys/cam/mmc/mmc_sim.c
--- a/sys/cam/mmc/mmc_sim.c
+++ b/sys/cam/mmc/mmc_sim.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2020 Emmanuel Vadot <manu@FreeBSD.org>
+ * Copyright (c) 2020-2021 Emmanuel Vadot <manu@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,6 +50,30 @@
return;
}
+static void
+mmc_sim_task(void *arg, int pending)
+{
+ struct mmc_sim *mmc_sim;
+ struct ccb_trans_settings *cts;
+ int rv;
+
+ mmc_sim = arg;
+
+ if (mmc_sim->ccb == NULL)
+ return;
+
+ cts = &mmc_sim->ccb->cts;
+ rv = MMC_SIM_SET_TRAN_SETTINGS(mmc_sim->dev, &cts->proto_specific.mmc);
+ if (rv != 0)
+ mmc_sim->ccb->ccb_h.status = CAM_REQ_INVALID;
+ else
+ mmc_sim->ccb->ccb_h.status = CAM_REQ_CMP;
+
+ xpt_done(mmc_sim->ccb);
+ mmc_sim->ccb = NULL;
+}
+
+
static void
mmc_cam_sim_default_action(struct cam_sim *sim, union ccb *ccb)
{
@@ -67,6 +91,12 @@
mtx_assert(&mmc_sim->mtx, MA_OWNED);
+ if (mmc_sim->ccb != NULL) {
+ ccb->ccb_h.status = CAM_BUSY;
+ xpt_done(ccb);
+ return;
+ }
+
switch (ccb->ccb_h.func_code) {
case XPT_PATH_INQ:
rv = MMC_SIM_GET_TRAN_SETTINGS(mmc_sim->dev, &mmc);
@@ -78,6 +108,7 @@
}
break;
case XPT_GET_TRAN_SETTINGS:
+ case XPT_MMC_GET_TRAN_SETTINGS:
{
struct ccb_trans_settings *cts = &ccb->cts;
@@ -105,6 +136,15 @@
ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
+ case XPT_MMC_SET_TRAN_SETTINGS:
+ {
+ ccb->ccb_h.status = CAM_SIM_QUEUED;
+ mmc_sim->ccb = ccb;
+ taskqueue_enqueue(taskqueue_thread, &mmc_sim->sim_task);
+ return;
+ /* NOTREACHED */
+ break;
+ }
case XPT_RESET_BUS:
ccb->ccb_h.status = CAM_REQ_CMP;
break;
@@ -112,7 +152,7 @@
{
rv = MMC_SIM_CAM_REQUEST(mmc_sim->dev, ccb);
if (rv != 0)
- ccb->ccb_h.status = CAM_REQ_INPROG;
+ ccb->ccb_h.status = CAM_SIM_QUEUED;
else
ccb->ccb_h.status = CAM_REQ_INVALID;
return;
@@ -163,6 +203,7 @@
}
mtx_unlock(&mmc_sim->mtx);
+ TASK_INIT(&mmc_sim->sim_task, 0, mmc_sim_task, mmc_sim);
return (0);
diff --git a/sys/cam/mmc/mmc_xpt.c b/sys/cam/mmc/mmc_xpt.c
--- a/sys/cam/mmc/mmc_xpt.c
+++ b/sys/cam/mmc/mmc_xpt.c
@@ -90,6 +90,12 @@
typedef enum {
PROBE_RESET,
PROBE_IDENTIFY,
+ PROBE_POWER_OFF,
+ PROBE_GET_HOST_OCR,
+ PROBE_RESET_BUS,
+ PROBE_SET_ID_FREQ,
+ PROBE_SET_CS,
+ PROBE_GO_IDLE_STATE,
PROBE_SDIO_RESET,
PROBE_SEND_IF_COND,
PROBE_SDIO_INIT,
@@ -107,6 +113,12 @@
static char *probe_action_text[] = {
"PROBE_RESET",
"PROBE_IDENTIFY",
+ "PROBE_POWER_OFF",
+ "PROBE_GET_HOST_OCR",
+ "PROBE_RESET_BUS",
+ "PROBE_SET_ID_FREQ",
+ "PROBE_SET_CS",
+ "PROBE_GO_IDLE_STATE",
"PROBE_SDIO_RESET",
"PROBE_SEND_IF_COND",
"PROBE_SDIO_INIT",
@@ -165,6 +177,7 @@
probe_action action;
int restart;
union ccb saved_ccb;
+ uint32_t host_ocr;
uint32_t flags;
#define PROBE_FLAG_ACMD_SENT 0x1 /* CMD55 is sent, card expects ACMD */
#define PROBE_FLAG_HOST_CAN_DO_18V 0x2 /* Host can do 1.8V signaling */
@@ -584,7 +597,6 @@
mmcprobe_softc *softc;
struct cam_path *path;
struct ccb_mmcio *mmcio;
- struct mtx *p_mtx = cam_periph_mtx(periph);
struct ccb_trans_settings_mmc *cts;
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("mmcprobe_start\n"));
@@ -612,25 +624,29 @@
case PROBE_IDENTIFY:
xpt_path_inq(&start_ccb->cpi, periph->path);
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("Start with PROBE_IDENTIFY\n"));
- init_standard_ccb(start_ccb, XPT_GET_TRAN_SETTINGS);
- xpt_action(start_ccb);
- if (cts->ios.power_mode != power_off) {
- init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS);
- cts->ios.power_mode = power_off;
- cts->ios_valid = MMC_PM;
- xpt_action(start_ccb);
- mtx_sleep(periph, p_mtx, 0, "mmcios", 100);
- }
- /* mmc_power_up */
- /* Get the host OCR */
- init_standard_ccb(start_ccb, XPT_GET_TRAN_SETTINGS);
- xpt_action(start_ccb);
+ init_standard_ccb(start_ccb, XPT_MMC_GET_TRAN_SETTINGS);
+ break;
+
+ case PROBE_POWER_OFF:
+ CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("power off the card\n"));
+ init_standard_ccb(start_ccb, XPT_MMC_SET_TRAN_SETTINGS);
+ cts->ios.power_mode = power_off;
+ cts->ios_valid = MMC_PM;
+ break;
+
+ case PROBE_GET_HOST_OCR:
+ CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("get the host ocr\n"));
+ init_standard_ccb(start_ccb, XPT_MMC_GET_TRAN_SETTINGS);
+ break;
+ case PROBE_RESET_BUS:
+ {
uint32_t host_caps = cts->host_caps;
if (host_caps & MMC_CAP_SIGNALING_180)
softc->flags |= PROBE_FLAG_HOST_CAN_DO_18V;
- uint32_t hv = mmc_highest_voltage(cts->host_ocr);
- init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS);
+ uint32_t hv = mmc_highest_voltage(softc->host_ocr);
+ CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("reseting the bus\n"));
+ init_standard_ccb(start_ccb, XPT_MMC_SET_TRAN_SETTINGS);
cts->ios.vdd = hv;
cts->ios.bus_mode = opendrain;
cts->ios.chip_select = cs_dontcare;
@@ -639,25 +655,26 @@
cts->ios.clock = 0;
cts->ios_valid = MMC_VDD | MMC_PM | MMC_BM |
MMC_CS | MMC_BW | MMC_CLK;
- xpt_action(start_ccb);
- mtx_sleep(periph, p_mtx, 0, "mmcios", 100);
+ break;
+ }
- init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS);
+ case PROBE_SET_ID_FREQ:
+ CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("setting the ID freq\n"));
+ init_standard_ccb(start_ccb, XPT_MMC_SET_TRAN_SETTINGS);
cts->ios.power_mode = power_on;
cts->ios.clock = CARD_ID_FREQUENCY;
cts->ios.timing = bus_timing_normal;
cts->ios_valid = MMC_PM | MMC_CLK | MMC_BT;
- xpt_action(start_ccb);
- mtx_sleep(periph, p_mtx, 0, "mmcios", 100);
- /* End for mmc_power_on */
+ break;
+ case PROBE_SET_CS:
/* Begin mmc_idle_cards() */
- init_standard_ccb(start_ccb, XPT_SET_TRAN_SETTINGS);
+ init_standard_ccb(start_ccb, XPT_MMC_SET_TRAN_SETTINGS);
cts->ios.chip_select = cs_high;
cts->ios_valid = MMC_CS;
- xpt_action(start_ccb);
- mtx_sleep(periph, p_mtx, 0, "mmcios", 1);
+ break;
+ case PROBE_GO_IDLE_STATE:
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("Send first XPT_MMC_IO\n"));
init_standard_ccb(start_ccb, XPT_MMC_IO);
mmcio->cmd.opcode = MMC_GO_IDLE_STATE; /* CMD 0 */
@@ -668,6 +685,7 @@
/* XXX Reset I/O portion as well */
break;
+
case PROBE_SDIO_RESET:
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_PROBE,
("Start with PROBE_SDIO_RESET\n"));
@@ -805,7 +823,7 @@
struct ccb_mmcio *mmcio;
u_int32_t priority;
- CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mmcprobe_done\n"));
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("mmcprobe_done\n"));
softc = (mmcprobe_softc *)periph->softc;
path = done_ccb->ccb_h.path;
priority = done_ccb->ccb_h.pinfo.priority;
@@ -816,6 +834,45 @@
case PROBE_IDENTIFY:
{
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_RESET\n"));
+ PROBE_SET_ACTION(softc, PROBE_POWER_OFF);
+ break;
+ }
+ case PROBE_POWER_OFF:
+ {
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_POWER_OFF\n"));
+ PROBE_SET_ACTION(softc, PROBE_GET_HOST_OCR);
+ break;
+ }
+ case PROBE_GET_HOST_OCR:
+ {
+ struct ccb_trans_settings_mmc *cts;
+ cts = &done_ccb->cts.proto_specific.mmc;
+ softc->host_ocr = cts->host_ocr;
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_GET_HOST_OCR (Got OCR=%x\n", softc->host_ocr));
+ PROBE_SET_ACTION(softc, PROBE_RESET_BUS);
+ break;
+ }
+ case PROBE_RESET_BUS:
+ {
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_RESET_BUS\n"));
+ PROBE_SET_ACTION(softc, PROBE_SET_ID_FREQ);
+ break;
+ }
+ case PROBE_SET_ID_FREQ:
+ {
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_SET_ID_FREQ\n"));
+ PROBE_SET_ACTION(softc, PROBE_SET_CS);
+ break;
+ }
+ case PROBE_SET_CS:
+ {
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_SET_CS\n"));
+ PROBE_SET_ACTION(softc, PROBE_GO_IDLE_STATE);
+ break;
+ }
+ case PROBE_GO_IDLE_STATE:
+ {
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_GO_IDLE_STATE\n"));
mmcio = &done_ccb->mmcio;
err = mmcio->cmd.error;
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c
--- a/sys/dev/sdhci/sdhci.c
+++ b/sys/dev/sdhci/sdhci.c
@@ -2537,6 +2537,7 @@
mmc_path_inq(&ccb->cpi, "Deglitch Networks", sim, maxphys);
break;
+ case XPT_MMC_GET_TRAN_SETTINGS:
case XPT_GET_TRAN_SETTINGS:
{
struct ccb_trans_settings *cts = &ccb->cts;
@@ -2571,6 +2572,7 @@
ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
+ case XPT_MMC_SET_TRAN_SETTINGS:
case XPT_SET_TRAN_SETTINGS:
if (sdhci_debug > 1)
slot_printf(slot, "Got XPT_SET_TRAN_SETTINGS\n");
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 18, 6:30 AM (16 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15851379
Default Alt Text
D30038.diff (9 KB)
Attached To
Mode
D30038: mmccam: Add two new XPT for MMC and use them in mmc_sim and sdhci
Attached
Detach File
Event Timeline
Log In to Comment