mmc: dwmmc: Convert driver to use the mmc_sim interface
A lot more generic cam related things are done in mmc_sim so this simplify the driver a lot. Differential Revision: https://reviews.freebsd.org/D27487 Reviewed by: kibab
This commit is contained in:
parent
2671bdb540
commit
f1cc48e5da
@ -76,6 +76,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <cam/cam_debug.h>
|
#include <cam/cam_debug.h>
|
||||||
#include <cam/cam_sim.h>
|
#include <cam/cam_sim.h>
|
||||||
#include <cam/cam_xpt_sim.h>
|
#include <cam/cam_xpt_sim.h>
|
||||||
|
|
||||||
|
#include "mmc_sim_if.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mmcbr_if.h"
|
#include "mmcbr_if.h"
|
||||||
@ -151,14 +153,6 @@ static int dma_stop(struct dwmmc_softc *);
|
|||||||
static void pio_read(struct dwmmc_softc *, struct mmc_command *);
|
static void pio_read(struct dwmmc_softc *, struct mmc_command *);
|
||||||
static void pio_write(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);
|
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[] = {
|
static struct resource_spec dwmmc_spec[] = {
|
||||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||||
@ -476,7 +470,7 @@ dwmmc_card_task(void *arg, int pending __unused)
|
|||||||
struct dwmmc_softc *sc = arg;
|
struct dwmmc_softc *sc = arg;
|
||||||
|
|
||||||
#ifdef MMCCAM
|
#ifdef MMCCAM
|
||||||
mmccam_start_discovery(sc->sim);
|
mmc_cam_sim_discover(&sc->mmc_sim);
|
||||||
#else
|
#else
|
||||||
DWMMC_LOCK(sc);
|
DWMMC_LOCK(sc);
|
||||||
|
|
||||||
@ -771,32 +765,11 @@ dwmmc_attach(device_t dev)
|
|||||||
|
|
||||||
#ifdef MMCCAM
|
#ifdef MMCCAM
|
||||||
sc->ccb = NULL;
|
sc->ccb = NULL;
|
||||||
if ((sc->devq = cam_simq_alloc(1)) == NULL) {
|
if (mmc_cam_sim_alloc(dev, "dw_mmc", &sc->mmc_sim) != 0) {
|
||||||
goto fail;
|
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
|
#endif
|
||||||
/*
|
/*
|
||||||
* Schedule a card detection as we won't get an interrupt
|
* Schedule a card detection as we won't get an interrupt
|
||||||
@ -844,6 +817,10 @@ dwmmc_detach(device_t dev)
|
|||||||
device_printf(sc->dev, "Cannot disable vqmmc regulator\n");
|
device_printf(sc->dev, "Cannot disable vqmmc regulator\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MMCCAM
|
||||||
|
mmc_cam_sim_free(&sc->mmc_sim);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1282,6 +1259,7 @@ dwmmc_request(device_t brdev, device_t reqdev, struct mmc_request *req)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MMCCAM
|
||||||
static int
|
static int
|
||||||
dwmmc_get_ro(device_t brdev, device_t reqdev)
|
dwmmc_get_ro(device_t brdev, device_t reqdev)
|
||||||
{
|
{
|
||||||
@ -1319,6 +1297,7 @@ dwmmc_release_host(device_t brdev, device_t reqdev)
|
|||||||
DWMMC_UNLOCK(sc);
|
DWMMC_UNLOCK(sc);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#endif /* !MMCCAM */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dwmmc_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
|
dwmmc_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
|
||||||
@ -1445,133 +1424,34 @@ dwmmc_switch_vccq(device_t dev, device_t child)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
dwmmc_cam_handle_mmcio(struct cam_sim *sim, union ccb *ccb)
|
dwmmc_get_tran_settings(device_t dev, struct ccb_trans_settings_mmc *cts)
|
||||||
{
|
{
|
||||||
struct dwmmc_softc *sc;
|
struct dwmmc_softc *sc;
|
||||||
|
|
||||||
sc = cam_sim_softc(sim);
|
sc = device_get_softc(dev);
|
||||||
|
|
||||||
dwmmc_cam_request(sc, ccb);
|
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));
|
||||||
|
|
||||||
static void
|
return (0);
|
||||||
dwmmc_cam_action(struct cam_sim *sim, union ccb *ccb)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 *ios;
|
||||||
struct mmc_ios *new_ios;
|
struct mmc_ios *new_ios;
|
||||||
struct ccb_trans_settings_mmc *cts;
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
ios = &sc->host.ios;
|
ios = &sc->host.ios;
|
||||||
|
|
||||||
cts = &ccb->cts.proto_specific.mmc;
|
|
||||||
new_ios = &cts->ios;
|
new_ios = &cts->ios;
|
||||||
|
|
||||||
/* Update only requested fields */
|
/* Update only requested fields */
|
||||||
@ -1622,10 +1502,12 @@ dwmmc_cam_settran_settings(struct dwmmc_softc *sc, union ccb *ccb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct ccb_mmcio *mmcio;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
mmcio = &ccb->mmcio;
|
mmcio = &ccb->mmcio;
|
||||||
|
|
||||||
DWMMC_LOCK(sc);
|
DWMMC_LOCK(sc);
|
||||||
@ -1653,19 +1535,28 @@ dwmmc_cam_request(struct dwmmc_softc *sc, union ccb *ccb)
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* MMCCAM */
|
||||||
|
|
||||||
static device_method_t dwmmc_methods[] = {
|
static device_method_t dwmmc_methods[] = {
|
||||||
/* Bus interface */
|
/* Bus interface */
|
||||||
DEVMETHOD(bus_read_ivar, dwmmc_read_ivar),
|
DEVMETHOD(bus_read_ivar, dwmmc_read_ivar),
|
||||||
DEVMETHOD(bus_write_ivar, dwmmc_write_ivar),
|
DEVMETHOD(bus_write_ivar, dwmmc_write_ivar),
|
||||||
|
|
||||||
|
#ifndef MMCCAM
|
||||||
/* mmcbr_if */
|
/* mmcbr_if */
|
||||||
DEVMETHOD(mmcbr_update_ios, dwmmc_update_ios),
|
DEVMETHOD(mmcbr_update_ios, dwmmc_update_ios),
|
||||||
DEVMETHOD(mmcbr_request, dwmmc_request),
|
DEVMETHOD(mmcbr_request, dwmmc_request),
|
||||||
DEVMETHOD(mmcbr_get_ro, dwmmc_get_ro),
|
DEVMETHOD(mmcbr_get_ro, dwmmc_get_ro),
|
||||||
DEVMETHOD(mmcbr_acquire_host, dwmmc_acquire_host),
|
DEVMETHOD(mmcbr_acquire_host, dwmmc_acquire_host),
|
||||||
DEVMETHOD(mmcbr_release_host, dwmmc_release_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
|
DEVMETHOD_END
|
||||||
};
|
};
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#include "opt_mmccam.h"
|
#include "opt_mmccam.h"
|
||||||
|
|
||||||
|
#include <cam/mmc/mmc_sim.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HWTYPE_NONE,
|
HWTYPE_NONE,
|
||||||
HWTYPE_ALTERA,
|
HWTYPE_ALTERA,
|
||||||
@ -58,9 +60,7 @@ struct dwmmc_softc {
|
|||||||
struct mtx sc_mtx;
|
struct mtx sc_mtx;
|
||||||
#ifdef MMCCAM
|
#ifdef MMCCAM
|
||||||
union ccb * ccb;
|
union ccb * ccb;
|
||||||
struct cam_devq * devq;
|
struct mmc_sim mmc_sim;
|
||||||
struct cam_sim * sim;
|
|
||||||
struct mtx sim_mtx;
|
|
||||||
#else
|
#else
|
||||||
struct mmc_request *req;
|
struct mmc_request *req;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user