diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -76,6 +76,8 @@ #include #include #include + +#include "mmc_sim_if.h" #endif #include "mmcbr_if.h" @@ -151,14 +153,6 @@ static void pio_read(struct dwmmc_softc *, struct mmc_command *); static void pio_write(struct dwmmc_softc *, struct mmc_command *); static void dwmmc_handle_card_present(struct dwmmc_softc *sc, bool is_present); -#ifdef MMCCAM -static int dwmmc_switch_vccq(device_t, device_t); -static void dwmmc_cam_action(struct cam_sim *, union ccb *); -static void dwmmc_cam_poll(struct cam_sim *); -static int dwmmc_cam_settran_settings(struct dwmmc_softc *, union ccb *); -static int dwmmc_cam_request(struct dwmmc_softc *, union ccb *); -static void dwmmc_cam_handle_mmcio(struct cam_sim *, union ccb *); -#endif static struct resource_spec dwmmc_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, @@ -476,7 +470,7 @@ struct dwmmc_softc *sc = arg; #ifdef MMCCAM - mmccam_start_discovery(sc->sim); + mmc_cam_sim_discover(&sc->mmc_sim); #else DWMMC_LOCK(sc); @@ -771,32 +765,11 @@ #ifdef MMCCAM sc->ccb = NULL; - if ((sc->devq = cam_simq_alloc(1)) == NULL) { - goto fail; + if (mmc_cam_sim_alloc(dev, "dw_mmc", &sc->mmc_sim) != 0) { + device_printf(dev, "cannot alloc cam sim\n"); + dwmmc_detach(dev); + return (ENXIO); } - - mtx_init(&sc->sim_mtx, "dwmmcsim", NULL, MTX_DEF); - sc->sim = cam_sim_alloc_dev(dwmmc_cam_action, dwmmc_cam_poll, - "dw_mmc_sim", sc, dev, - &sc->sim_mtx, 1, 1, sc->devq); - - if (sc->sim == NULL) { - cam_simq_free(sc->devq); - device_printf(dev, "cannot allocate CAM SIM\n"); - goto fail; - } - - mtx_lock(&sc->sim_mtx); - if (xpt_bus_register(sc->sim, sc->dev, 0) != 0) { - device_printf(sc->dev, "cannot register SCSI pass-through bus\n"); - cam_sim_free(sc->sim, FALSE); - cam_simq_free(sc->devq); - mtx_unlock(&sc->sim_mtx); - goto fail; - } - -fail: - mtx_unlock(&sc->sim_mtx); #endif /* * Schedule a card detection as we won't get an interrupt @@ -844,6 +817,10 @@ device_printf(sc->dev, "Cannot disable vqmmc regulator\n"); #endif +#ifdef MMCCAM + mmc_cam_sim_free(&sc->mmc_sim); +#endif + return (0); } @@ -1282,6 +1259,7 @@ return (0); } +#ifndef MMCCAM static int dwmmc_get_ro(device_t brdev, device_t reqdev) { @@ -1319,6 +1297,7 @@ DWMMC_UNLOCK(sc); return (0); } +#endif /* !MMCCAM */ static int dwmmc_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) @@ -1445,133 +1424,34 @@ return EINVAL; } -static void -dwmmc_cam_handle_mmcio(struct cam_sim *sim, union ccb *ccb) -{ - struct dwmmc_softc *sc; - - sc = cam_sim_softc(sim); - - dwmmc_cam_request(sc, ccb); -} - -static void -dwmmc_cam_action(struct cam_sim *sim, union ccb *ccb) +static int +dwmmc_get_tran_settings(device_t dev, struct ccb_trans_settings_mmc *cts) { struct dwmmc_softc *sc; - sc = cam_sim_softc(sim); - if (sc == NULL) { - ccb->ccb_h.status = CAM_SEL_TIMEOUT; - xpt_done(ccb); - return; - } - - mtx_assert(&sc->sim_mtx, MA_OWNED); - - switch (ccb->ccb_h.func_code) { - case XPT_PATH_INQ: - /* XXX: correctly calculate maxio here */ - mmc_path_inq(&ccb->cpi, "Deglitch Networks", sim, MMC_SECTOR_SIZE); - break; - - case XPT_GET_TRAN_SETTINGS: - { - struct ccb_trans_settings *cts = &ccb->cts; - - cts->protocol = PROTO_MMCSD; - cts->protocol_version = 1; - cts->transport = XPORT_MMCSD; - cts->transport_version = 1; - cts->xport_specific.valid = 0; - cts->proto_specific.mmc.host_ocr = sc->host.host_ocr; - cts->proto_specific.mmc.host_f_min = sc->host.f_min; - cts->proto_specific.mmc.host_f_max = sc->host.f_max; - cts->proto_specific.mmc.host_caps = sc->host.caps; - /* XXX: correctly calculate host_max_data */ - cts->proto_specific.mmc.host_max_data = 1; - memcpy(&cts->proto_specific.mmc.ios, &sc->host.ios, sizeof(struct mmc_ios)); - ccb->ccb_h.status = CAM_REQ_CMP; - break; - } - case XPT_SET_TRAN_SETTINGS: - { - dwmmc_cam_settran_settings(sc, ccb); - ccb->ccb_h.status = CAM_REQ_CMP; - break; - } - case XPT_RESET_BUS: { - struct ccb_trans_settings_mmc *cts; - - cts = &ccb->cts.proto_specific.mmc; - cts->ios_valid = MMC_PM; - cts->ios.power_mode = power_off; - /* Power off the MMC bus */ - if (dwmmc_cam_settran_settings(sc, ccb) != 0) { - device_printf(sc->dev,"cannot power down the MMC bus\n"); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - break; - } - - /* Soft Reset controller and run initialization again */ - if (dwmmc_ctrl_reset(sc, (SDMMC_CTRL_RESET | - SDMMC_CTRL_FIFO_RESET | - SDMMC_CTRL_DMA_RESET)) != 0) { - device_printf(sc->dev, "cannot reset the controller\n"); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - break; - } + sc = device_get_softc(dev); - cts->ios_valid = MMC_PM; - cts->ios.power_mode = power_on; - /* Power off the MMC bus */ - if (dwmmc_cam_settran_settings(sc, ccb) != 0) { - device_printf(sc->dev, "cannot power on the MMC bus\n"); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - break; - } + cts->host_ocr = sc->host.host_ocr; + cts->host_f_min = sc->host.f_min; + cts->host_f_max = sc->host.f_max; + cts->host_caps = sc->host.caps; + cts->host_max_data = (IDMAC_MAX_SIZE * IDMAC_DESC_SEGS) / MMC_SECTOR_SIZE; + memcpy(&cts->ios, &sc->host.ios, sizeof(struct mmc_ios)); - ccb->ccb_h.status = CAM_REQ_CMP; - break; - } - case XPT_MMC_IO: - /* - * Here is the HW-dependent part of - * sending the command to the underlying h/w - * At some point in the future an interrupt comes. - * Then the request will be marked as completed. - */ - ccb->ccb_h.status = CAM_REQ_INPROG; - - dwmmc_cam_handle_mmcio(sim, ccb); - return; - /* NOTREACHED */ - break; - default: - ccb->ccb_h.status = CAM_REQ_INVALID; - break; - } - xpt_done(ccb); - return; -} - -static void -dwmmc_cam_poll(struct cam_sim *sim) -{ - return; + return (0); } static int -dwmmc_cam_settran_settings(struct dwmmc_softc *sc, union ccb *ccb) +dwmmc_set_tran_settings(device_t dev, struct ccb_trans_settings_mmc *cts) { + struct dwmmc_softc *sc; struct mmc_ios *ios; struct mmc_ios *new_ios; - struct ccb_trans_settings_mmc *cts; int res; + sc = device_get_softc(dev); ios = &sc->host.ios; - cts = &ccb->cts.proto_specific.mmc; new_ios = &cts->ios; /* Update only requested fields */ @@ -1622,10 +1502,12 @@ } static int -dwmmc_cam_request(struct dwmmc_softc *sc, union ccb *ccb) +dwmmc_cam_request(device_t dev, union ccb *ccb) { + struct dwmmc_softc *sc; struct ccb_mmcio *mmcio; + sc = device_get_softc(dev); mmcio = &ccb->mmcio; DWMMC_LOCK(sc); @@ -1653,19 +1535,28 @@ return (0); } -#endif +#endif /* MMCCAM */ static device_method_t dwmmc_methods[] = { /* Bus interface */ DEVMETHOD(bus_read_ivar, dwmmc_read_ivar), DEVMETHOD(bus_write_ivar, dwmmc_write_ivar), +#ifndef MMCCAM /* mmcbr_if */ DEVMETHOD(mmcbr_update_ios, dwmmc_update_ios), DEVMETHOD(mmcbr_request, dwmmc_request), DEVMETHOD(mmcbr_get_ro, dwmmc_get_ro), DEVMETHOD(mmcbr_acquire_host, dwmmc_acquire_host), DEVMETHOD(mmcbr_release_host, dwmmc_release_host), +#endif + +#ifdef MMCCAM + /* MMCCAM interface */ + DEVMETHOD(mmc_sim_get_tran_settings, dwmmc_get_tran_settings), + DEVMETHOD(mmc_sim_set_tran_settings, dwmmc_set_tran_settings), + DEVMETHOD(mmc_sim_cam_request, dwmmc_cam_request), +#endif DEVMETHOD_END }; diff --git a/sys/dev/mmc/host/dwmmc_var.h b/sys/dev/mmc/host/dwmmc_var.h --- a/sys/dev/mmc/host/dwmmc_var.h +++ b/sys/dev/mmc/host/dwmmc_var.h @@ -41,6 +41,8 @@ #include "opt_mmccam.h" +#include + enum { HWTYPE_NONE, HWTYPE_ALTERA, @@ -58,9 +60,7 @@ struct mtx sc_mtx; #ifdef MMCCAM union ccb * ccb; - struct cam_devq * devq; - struct cam_sim * sim; - struct mtx sim_mtx; + struct mmc_sim mmc_sim; #else struct mmc_request *req; #endif