34#include <sys/endian.h>
37#include <sys/malloc.h>
38#include <sys/kernel.h>
42#include <sys/interrupt.h>
47#include <sys/sysctl.h>
48#include <sys/condvar.h>
64#include <machine/stdarg.h>
65#include <machine/_inttypes.h>
68FEATURE(mmccam,
"CAM-based MMC/SD/SDIO stack");
117 "PROBE_GET_HOST_OCR",
121 "PROBE_GO_IDLE_STATE",
123 "PROBE_SEND_IF_COND",
126 "PROBE_SEND_APP_OP_COND",
129 "PROBE_SEND_RELATIVE_ADDR",
130 "PROBE_MMC_SET_RELATIVE_ADDR",
136#define PROBE_SET_ACTION(softc, newaction) \
139 text = probe_action_text; \
140 CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE, \
141 ("Probe %s to %s\n", text[(softc)->action], \
142 text[(newaction)])); \
143 (softc)->action = (newaction); \
153#define MMC_XPT_XPORT(x, X) \
154 static struct xpt_xport mmc_xport_ ## x = { \
155 .xport = XPORT_ ## X, \
157 .ops = &mmc_xport_ops, \
159 CAM_XPT_XPORT(mmc_xport_ ## x);
181#define PROBE_FLAG_ACMD_SENT 0x1
182#define PROBE_FLAG_HOST_CAN_DO_18V 0x2
198 device->
quirk = NULL;
211 struct cam_ed *device,
void *async_arg)
243 if (request_ccb != NULL) {
270 (
"Got scan request, but mmcprobe already exists\n"));
279 (
" Set up the mmcprobe device...\n"));
290 "returned an error, can't continue probe\n");
304 (
"mmc_action! func_code=%x, action %s\n", start_ccb->
ccb_h.
func_code,
313 (
"XPT_SCAN_{BUS,TGT,LUN}\n"));
341 cdai = &start_ccb->
cdai;
343 (
"%s: request %x\n", __func__, cdai->
buftype));
347 panic(
"Attempt to store data?!");
373 panic(
"Unknown buftype");
390 memset(&
cts, 0,
sizeof(
cts));
399 (
"XPT info: CLK %04d, ...\n",
cts.proto_specific.mmc.
ios.clock));
422 (
"%s(%s): device is not initialized on sim's path",
433 sbuf_printf(sb,
"Relative addr: %08x\n", ident_data->
card_rca);
434 sbuf_printf(sb,
"Card features: <");
436 sbuf_printf(sb,
"MMC");
440 sbuf_printf(sb,
"%sMemory", space ?
" " :
"");
444 sbuf_printf(sb,
"%sHigh-Capacity", space ?
" " :
"");
448 sbuf_printf(sb,
"%sSD2.0-Conditions", space ?
" " :
"");
452 sbuf_printf(sb,
"%sSDIO", space ?
" " :
"");
456 sbuf_printf(sb,
"%s1.8-Signaling", space ?
" " :
"");
458 sbuf_printf(sb,
">\n");
461 sbuf_printf(sb,
"Card memory OCR: %08x\n",
465 sbuf_printf(sb,
"Card IO OCR: %08x\n", ident_data->
io_ocr);
466 sbuf_printf(sb,
"Number of functions: %u\n",
471 printf(
"%s", sbuf_data(sb));
481 sbuf_new(&sb, buffer,
sizeof(buffer), SBUF_FIXEDLEN);
515#define CARD_ID_FREQUENCY 400000
526 union ccb *request_ccb;
531 request_ccb = (
union ccb *)arg;
532 if (request_ccb == NULL) {
533 printf(
"mmcprobe_register: no probe CCB, "
534 "can't register device\n");
538 softc = (
mmcprobe_softc *)malloc(
sizeof(*softc), M_CAMXPT, M_NOWAIT);
541 printf(
"proberegister: Unable to probe new device. "
542 "Unable to allocate softc\n");
548 periph->
softc = softc;
556 printf(
"proberegister: cam_periph_acquire failed (status=%d)\n",
578 for (i = MMC_OCR_MAX_VOLTAGE_SHIFT;
579 i >= MMC_OCR_MIN_VOLTAGE_SHIFT; i--)
606 mmcio = &start_ccb->
mmcio;
610 memset(&mmcio->
cmd, 0,
sizeof(
struct mmc_command));
634 cts->
ios.power_mode = power_off;
652 cts->
ios.bus_mode = opendrain;
653 cts->
ios.chip_select = cs_dontcare;
654 cts->
ios.power_mode = power_up;
655 cts->
ios.bus_width = bus_width_1;
665 cts->
ios.power_mode = power_on;
667 cts->
ios.timing = bus_timing_normal;
674 cts->
ios.chip_select = cs_high;
681 mmcio->
cmd.opcode = MMC_GO_IDLE_STATE;
683 mmcio->
cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
684 mmcio->
cmd.data = NULL;
685 mmcio->
stop.opcode = 0;
692 (
"Start with PROBE_SDIO_RESET\n"));
693 uint32_t mmc_arg = SD_IO_RW_ADR(SD_IO_CCCR_CTL)
694 | SD_IO_RW_DAT(CCCR_CTL_RES) | SD_IO_RW_WR | SD_IO_RW_RAW;
701 MMC_RSP_R5 | MMC_CMD_AC,
707 (
"Start with PROBE_SEND_IF_COND\n"));
709 mmcio->
cmd.opcode = SD_SEND_IF_COND;
710 mmcio->
cmd.arg = (1 << 8) + 0xAA;
711 mmcio->
cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
712 mmcio->
stop.opcode = 0;
717 (
"Start with PROBE_SDIO_INIT\n"));
719 mmcio->
cmd.opcode = IO_SEND_OP_COND;
720 mmcio->
cmd.arg = mmcp->io_ocr;
721 mmcio->
cmd.flags = MMC_RSP_R4;
722 mmcio->
stop.opcode = 0;
727 (
"Start with PROBE_MMC_INIT\n"));
729 mmcio->
cmd.opcode = MMC_SEND_OP_COND;
730 mmcio->
cmd.arg = MMC_OCR_CCS | mmcp->card_ocr; ;
731 mmcio->
cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
732 mmcio->
stop.opcode = 0;
738 mmcio->
cmd.opcode = ACMD_SD_SEND_OP_COND;
743 uint32_t cmd_arg = MMC_OCR_CCS | mmcp->card_ocr;
745 cmd_arg |= MMC_OCR_S18R;
746 mmcio->
cmd.arg = cmd_arg;
747 mmcio->
cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
750 mmcio->
cmd.opcode = MMC_APP_CMD;
752 mmcio->
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
754 mmcio->
stop.opcode = 0;
759 mmcio->
cmd.opcode = MMC_ALL_SEND_CID;
761 mmcio->
cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
762 mmcio->
stop.opcode = 0;
766 mmcio->
cmd.opcode = SD_SEND_RELATIVE_ADDR;
768 mmcio->
cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
769 mmcio->
stop.opcode = 0;
773 mmcio->
cmd.opcode = MMC_SET_RELATIVE_ADDR;
775 mmcio->
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
776 mmcio->
stop.opcode = 0;
780 mmcio->
cmd.opcode = MMC_SELECT_CARD;
782 mmcio->
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
783 mmcio->
stop.opcode = 0;
787 mmcio->
cmd.opcode = MMC_SEND_CSD;
789 mmcio->
cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
790 mmcio->
stop.opcode = 0;
795 cts->
ios.bus_mode = pushpull;
805 panic(
"default: case in mmc_probe_start()");
814 free(periph->
softc, M_CAMXPT);
877 mmcio = &done_ccb->
mmcio;
878 err = mmcio->
cmd.error;
880 if (err != MMC_ERR_NONE) {
882 (
"GO_IDLE_STATE failed with error %d\n",
901 mmcio = &done_ccb->
mmcio;
902 err = mmcio->
cmd.error;
905 if (err != MMC_ERR_NONE || mmcio->
cmd.resp[0] != 0x1AA) {
907 (
"IF_COND: error %d, pattern %08x\n",
908 err, mmcio->
cmd.resp[0]));
912 (
"SD 2.0 interface conditions: OK\n"));
919 mmcio = &done_ccb->
mmcio;
920 err = mmcio->
cmd.error;
923 (
"SDIO_RESET: error %d, CCCR CTL register: %08x\n",
924 err, mmcio->
cmd.resp[0]));
930 mmcio = &done_ccb->
mmcio;
931 err = mmcio->
cmd.error;
935 (
"SDIO_INIT: error %d, %08x %08x %08x %08x\n",
936 err, mmcio->
cmd.resp[0],
939 mmcio->
cmd.resp[3]));
945 if (err != MMC_ERR_NONE) {
950 uint32_t ioifcond = mmcio->
cmd.resp[0];
951 uint32_t
io_ocr = ioifcond & R4_IO_OCR_MASK;
958 (
"SDIO OCR invalid, retrying\n"));
967 (
"SDIO OCR: %08x\n", mmcp->
io_ocr));
969 if (ioifcond & R4_IO_MEM_PRESENT) {
980 mmcio = &done_ccb->
mmcio;
981 err = mmcio->
cmd.error;
984 if (err != MMC_ERR_NONE) {
986 (
"MMC_INIT: error %d, resp %08x\n",
987 err, mmcio->
cmd.resp[0]));
992 (
"MMC card, OCR %08x\n", mmcio->
cmd.resp[0]));
998 (
"-> sending OCR to card\n"));
1002 if (!(mmcio->
cmd.resp[0] & MMC_OCR_CARD_BUSY)) {
1004 (
"Card is still powering up\n"));
1014 mmcio = &done_ccb->
mmcio;
1015 err = mmcio->
cmd.error;
1017 if (err != MMC_ERR_NONE) {
1019 (
"APP_OP_COND: error %d, resp %08x\n",
1020 err, mmcio->
cmd.resp[0]));
1031 softc->
flags &= ~PROBE_FLAG_ACMD_SENT;
1032 if ((mmcio->
cmd.resp[0] & MMC_OCR_CARD_BUSY) ||
1033 (mmcio->
cmd.arg & MMC_OCR_VOLTAGE) == 0) {
1036 (
"Card OCR: %08x\n", mmcio->
cmd.resp[0]));
1041 (
"-> sending OCR to card\n"));
1052 if (mmcio->
cmd.resp[0] & MMC_OCR_CCS) {
1054 (
"Card is SDHC\n"));
1059 if (mmcio->
cmd.resp[0] & MMC_OCR_S18A) {
1061 (
"Card supports 1.8V signaling\n"));
1065 (
"Host supports 1.8V signaling. Switch voltage!\n"));
1078 (
"Card not ready: %08x\n", mmcio->
cmd.resp[0]));
1087 mmcio = &done_ccb->
mmcio;
1088 err = mmcio->
cmd.error;
1090 if (err != MMC_ERR_NONE) {
1092 (
"PROBE_GET_CID: error %d\n", err));
1098 memcpy(mmcp->
card_cid, mmcio->
cmd.resp, 4 *
sizeof(uint32_t));
1100 (
"CID %08x%08x%08x%08x\n",
1112 mmcio = &done_ccb->
mmcio;
1113 err = mmcio->
cmd.error;
1115 uint16_t rca = mmcio->
cmd.resp[0] >> 16;
1117 (
"Card published RCA: %u\n", rca));
1119 if (err != MMC_ERR_NONE) {
1121 (
"PROBE_SEND_RELATIVE_ADDR: error %d\n", err));
1134 mmcio = &done_ccb->
mmcio;
1135 err = mmcio->
cmd.error;
1136 if (err != MMC_ERR_NONE) {
1138 (
"PROBE_MMC_SET_RELATIVE_ADDR: error %d\n", err));
1146 mmcio = &done_ccb->
mmcio;
1147 err = mmcio->
cmd.error;
1149 if (err != MMC_ERR_NONE) {
1151 (
"PROBE_GET_CSD: error %d\n", err));
1157 memcpy(mmcp->
card_csd, mmcio->
cmd.resp, 4 *
sizeof(uint32_t));
1159 (
"CSD %08x%08x%08x%08x\n",
1168 mmcio = &done_ccb->
mmcio;
1169 err = mmcio->
cmd.error;
1170 if (err != MMC_ERR_NONE) {
1172 (
"PROBE_SEND_RELATIVE_ADDR: error %d\n", err));
1182 (
"mmcprobe_done: invalid action state 0x%x\n", softc->
action));
1183 panic(
"default: case in mmc_probe_done()");
1196 (
"mmcprobe_done: remaining freeze count %d\n", frozen));
1217 const struct cam_sim *sim,
size_t maxio)
#define CAM_TARGET_WILDCARD
#define CAM_PRIORITY_NORMAL
@ CTS_TYPE_CURRENT_SETTINGS
static __inline void cam_fill_mmcio(struct ccb_mmcio *mmcio, uint32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, uint32_t mmc_opcode, uint32_t mmc_arg, uint32_t mmc_flags, struct mmc_data *mmc_d, uint32_t timeout)
#define MMC_CAP_SIGNALING_180
#define CDAI_TYPE_MMC_PARAMS
@ XPT_MMC_GET_TRAN_SETTINGS
@ XPT_MMC_SET_TRAN_SETTINGS
#define CDAI_TYPE_SERIAL_NUM
#define CDAI_TYPE_PHYS_PATH
#define CDAI_TYPE_SCSI_DEVID
#define CAM_DEBUG(path, flag, printfargs)
void cam_periph_release_locked(struct cam_periph *periph)
struct cam_periph * cam_periph_find(struct cam_path *path, char *name)
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t openings, u_int32_t arg, int getcount_only)
int cam_periph_acquire(struct cam_periph *periph)
void cam_periph_invalidate(struct cam_periph *periph)
cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, periph_oninv_t *periph_oninvalidate, periph_dtor_t *periph_dtor, periph_start_t *periph_start, char *name, cam_periph_type type, struct cam_path *path, ac_callback_t *ac_callback, ac_code code, void *arg)
#define CAM_PERIPH_INVALID
#define cam_periph_assert(periph, what)
#define CAM_PERIPH_DRV_EARLY
void() periph_init_t(void)
static __inline u_int32_t cam_sim_path(const struct cam_sim *sim)
static __inline u_int32_t cam_sim_unit(const struct cam_sim *sim)
static __inline u_int32_t cam_sim_bus(const struct cam_sim *sim)
static __inline const char * cam_sim_name(const struct cam_sim *sim)
void xpt_acquire_device(struct cam_ed *device)
union ccb * xpt_alloc_ccb(void)
void xpt_schedule(struct cam_periph *periph, u_int32_t new_priority)
cam_status xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph, path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
void xpt_release_device(struct cam_ed *device)
void xpt_print(struct cam_path *path, const char *fmt,...)
void xpt_rescan(union ccb *ccb)
void xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
void xpt_action(union ccb *start_ccb)
void xpt_done(union ccb *done_ccb)
lun_id_t xpt_path_lun_id(struct cam_path *path)
void xpt_action_default(union ccb *start_ccb)
void xpt_release_ccb(union ccb *free_ccb)
struct cam_ed * xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
const char * xpt_action_name(uint32_t action)
device_t xpt_path_sim_device(const struct cam_path *path)
Return the device_t associated with the path.
void xpt_free_ccb(union ccb *free_ccb)
#define xpt_path_unlock(path)
#define xpt_path_owned(path)
#define xpt_path_lock(path)
#define xpt_path_assert(path, what)
static void xpt_path_inq(struct ccb_pathinq *cpi, struct cam_path *path)
#define CAM_DEV_UNCONFIGURED
#define CARD_FEATURE_SDHC
#define CARD_FEATURE_MEMORY
#define CARD_FEATURE_SD20
#define CARD_FEATURE_SDIO
struct ccb_trans_settings_mmc * cts
void mmc_path_inq(struct ccb_pathinq *cpi, const char *hba, const struct cam_sim *sim, size_t maxio)
static void mmc_action(union ccb *start_ccb)
static void mmc_print_ident(struct mmc_params *ident_data, struct sbuf *sb)
static char * probe_action_text[]
static void mmc_proto_denounce(struct cam_ed *device)
static void mmc_scan_lun(struct cam_periph *periph, struct cam_path *path, cam_flags flags, union ccb *ccb)
static int mmc_highest_voltage(uint32_t ocr)
static struct cam_ed * mmc_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
static void mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb)
@ PROBE_MMC_SET_RELATIVE_ADDR
@ PROBE_SEND_RELATIVE_ADDR
#define MMC_XPT_XPORT(x, X)
#define CARD_ID_FREQUENCY
static void init_standard_ccb(union ccb *ccb, uint32_t cmd)
static void mmc_proto_debug_out(union ccb *ccb)
PERIPHDRIVER_DECLARE(mmcprobe, probe_driver)
static struct xpt_proto_ops mmc_proto_ops
static periph_init_t probe_periph_init
static struct periph_driver probe_driver
void mmccam_start_discovery(struct cam_sim *sim)
static void mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb)
static cam_status mmcprobe_register(struct cam_periph *periph, void *arg)
#define PROBE_FLAG_HOST_CAN_DO_18V
static void mmc_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, struct cam_ed *device, void *async_arg)
static void mmc_dev_advinfo(union ccb *start_ccb)
static void mmc_announce_periph(struct cam_periph *periph)
static void mmcprobe_cleanup(struct cam_periph *periph)
static struct xpt_xport_ops mmc_xport_ops
#define PROBE_FLAG_ACMD_SENT
FEATURE(mmccam, "CAM-based MMC/SD/SDIO stack")
#define PROBE_SET_ACTION(softc, newaction)
static void mmc_proto_announce(struct cam_ed *device)
static struct xpt_proto mmc_proto
struct mmc_params mmc_ident_data
struct scsi_inquiry_data inq_data
struct cam_periph * periph
void(* cbfcnp)(struct cam_periph *, union ccb *)
u_int32_t base_transfer_speed
struct ccb_trans_settings_mmc mmc
union ccb_trans_settings::@3 proto_specific
struct cam_periph * periph
xpt_proto_announce_func announce
xpt_alloc_device_func alloc_device
struct ccb_trans_settings cts
struct ccb_dev_advinfo cdai