Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Jun 2018 19:16:15 +0200
From:      Emmanuel Vadot <manu@bidouilliste.com>
To:        Ilya Bakulin <kibab@FreeBSD.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r335476 - in head/sys: arm/allwinner conf
Message-ID:  <20180621191615.a407caac02bd671c267f40aa@bidouilliste.com>
In-Reply-To: <201806211149.w5LBnLl9061185@repo.freebsd.org>
References:  <201806211149.w5LBnLl9061185@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 21 Jun 2018 11:49:21 +0000 (UTC)
Ilya Bakulin <kibab@FreeBSD.org> wrote:

> Author: kibab
> Date: Thu Jun 21 11:49:21 2018
> New Revision: 335476
> URL: https://svnweb.freebsd.org/changeset/base/335476
> 
> Log:
>   Add MMCCAM support to AllWinner MMC driver
>   
>   Using MMCCAM on AllWinner boards is now possible, reaching highest
>   possible data transfer speed.
>   
>   For now, MMCCAM doesn't scan cards on boot. This means that scanning
>   has to be done manually and that it's not possible to mount root FS
>   from MMC/SD card since there is no block device at the boot time.
>   
>   For manually scanning the cards, run:
>   # camcontrol rescan X:0:0
>   Where X is the bus number (look at camcontrol devlist to determine
>   bus number assigned to the MMC controller).
>   
>   Reviewed by:	manu

 No, as I said in the review I haven't reviewed it since I know nothing
about CAM.

>   Approved by:	imp (mentor)
>   Differential Revision:	https://reviews.freebsd.org/D15891
> 
> Modified:
>   head/sys/arm/allwinner/aw_mmc.c
>   head/sys/arm/allwinner/files.allwinner
>   head/sys/conf/files.arm64
> 
> Modified: head/sys/arm/allwinner/aw_mmc.c
> ==============================================================================
> --- head/sys/arm/allwinner/aw_mmc.c	Thu Jun 21 11:43:54 2018	(r335475)
> +++ head/sys/arm/allwinner/aw_mmc.c	Thu Jun 21 11:49:21 2018	(r335476)
> @@ -55,6 +55,16 @@ __FBSDID("$FreeBSD$");
>  #include <dev/extres/hwreset/hwreset.h>
>  #include <dev/extres/regulator/regulator.h>
>  
> +#include "opt_mmccam.h"
> +
> +#ifdef MMCCAM
> +#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>
> +#endif
> +
>  #define	AW_MMC_MEMRES		0
>  #define	AW_MMC_IRQRES		1
>  #define	AW_MMC_RESSZ		2
> @@ -112,7 +122,14 @@ struct aw_mmc_softc {
>  	int			aw_timeout;
>  	struct callout		aw_timeoutc;
>  	struct mmc_host		aw_host;
> +#ifdef MMCCAM
> +	union ccb *		ccb;
> +	struct cam_devq *	devq;
> +	struct cam_sim * 	sim;
> +	struct mtx		sim_mtx;
> +#else
>  	struct mmc_request *	aw_req;
> +#endif
>  	struct mtx		aw_mtx;
>  	struct resource *	aw_res[AW_MMC_RESSZ];
>  	struct aw_mmc_conf *	aw_mmc_conf;
> @@ -148,11 +165,19 @@ static int aw_mmc_init(struct aw_mmc_softc *);
>  static void aw_mmc_intr(void *);
>  static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t);
>  
> +static void aw_mmc_print_error(uint32_t);
>  static int aw_mmc_update_ios(device_t, device_t);
>  static int aw_mmc_request(device_t, device_t, struct mmc_request *);
>  static int aw_mmc_get_ro(device_t, device_t);
>  static int aw_mmc_acquire_host(device_t, device_t);
>  static int aw_mmc_release_host(device_t, device_t);
> +#ifdef MMCCAM
> +static void aw_mmc_cam_action(struct cam_sim *, union ccb *);
> +static void aw_mmc_cam_poll(struct cam_sim *);
> +static int aw_mmc_cam_settran_settings(struct aw_mmc_softc *, union ccb *);
> +static int aw_mmc_cam_request(struct aw_mmc_softc *, union ccb *);
> +static void aw_mmc_cam_handle_mmcio(struct cam_sim *, union ccb *);
> +#endif
>  
>  #define	AW_MMC_LOCK(_sc)	mtx_lock(&(_sc)->aw_mtx)
>  #define	AW_MMC_UNLOCK(_sc)	mtx_unlock(&(_sc)->aw_mtx)
> @@ -161,7 +186,201 @@ static int aw_mmc_release_host(device_t, device_t);
>  #define	AW_MMC_WRITE_4(_sc, _reg, _value)				\
>  	bus_write_4((_sc)->aw_res[AW_MMC_MEMRES], _reg, _value)
>  
> +#ifdef MMCCAM
> +static void
> +aw_mmc_cam_handle_mmcio(struct cam_sim *sim, union ccb *ccb)
> +{
> +	struct aw_mmc_softc *sc;
> +
> +	sc = cam_sim_softc(sim);
> +
> +	aw_mmc_cam_request(sc, ccb);
> +}
> +
> +static void
> +aw_mmc_cam_action(struct cam_sim *sim, union ccb *ccb)
> +{
> +	struct aw_mmc_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:
> +	{
> +		struct ccb_pathinq *cpi;
> +
> +		cpi = &ccb->cpi;
> +		cpi->version_num = 1;
> +		cpi->hba_inquiry = 0;
> +		cpi->target_sprt = 0;
> +		cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
> +		cpi->hba_eng_cnt = 0;
> +		cpi->max_target = 0;
> +		cpi->max_lun = 0;
> +		cpi->initiator_id = 1;
> +		cpi->maxio = (sc->aw_mmc_conf->dma_xferlen *
> +			      AW_MMC_DMA_SEGS) / MMC_SECTOR_SIZE;
> +		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
> +		strncpy(cpi->hba_vid, "Deglitch Networks", HBA_IDLEN);
> +		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
> +		cpi->unit_number = cam_sim_unit(sim);
> +		cpi->bus_id = cam_sim_bus(sim);
> +		cpi->protocol = PROTO_MMCSD;
> +		cpi->protocol_version = SCSI_REV_0;
> +		cpi->transport = XPORT_MMCSD;
> +		cpi->transport_version = 1;
> +
> +		cpi->ccb_h.status = CAM_REQ_CMP;
> +		break;
> +	}
> +	case XPT_GET_TRAN_SETTINGS:
> +	{
> +		struct ccb_trans_settings *cts = &ccb->cts;
> +
> +		if (bootverbose)
> +			device_printf(sc->aw_dev, "Got XPT_GET_TRAN_SETTINGS\n");
> +
> +		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->aw_host.host_ocr;
> +		cts->proto_specific.mmc.host_f_min = sc->aw_host.f_min;
> +		cts->proto_specific.mmc.host_f_max = sc->aw_host.f_max;
> +		cts->proto_specific.mmc.host_caps = sc->aw_host.caps;
> +		memcpy(&cts->proto_specific.mmc.ios, &sc->aw_host.ios, sizeof(struct mmc_ios));
> +		ccb->ccb_h.status = CAM_REQ_CMP;
> +		break;
> +	}
> +	case XPT_SET_TRAN_SETTINGS:
> +	{
> +		if (bootverbose)
> +			device_printf(sc->aw_dev, "Got XPT_SET_TRAN_SETTINGS\n");
> +		aw_mmc_cam_settran_settings(sc, ccb);
> +		ccb->ccb_h.status = CAM_REQ_CMP;
> +		break;
> +	}
> +	case XPT_RESET_BUS:
> +		if (bootverbose)
> +			device_printf(sc->aw_dev, "Got XPT_RESET_BUS, ACK it...\n");
> +		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;
> +
> +		aw_mmc_cam_handle_mmcio(sim, ccb);
> +		return;
> +		/* NOTREACHED */
> +		break;
> +	default:
> +		ccb->ccb_h.status = CAM_REQ_INVALID;
> +		break;
> +	}
> +	xpt_done(ccb);
> +	return;
> +}
> +
> +static void
> +aw_mmc_cam_poll(struct cam_sim *sim)
> +{
> +	return;
> +}
> +
>  static int
> +aw_mmc_cam_settran_settings(struct aw_mmc_softc *sc, union ccb *ccb)
> +{
> +	struct mmc_ios *ios;
> +	struct mmc_ios *new_ios;
> +	struct ccb_trans_settings_mmc *cts;
> +
> +	ios = &sc->aw_host.ios;
> +
> +	cts = &ccb->cts.proto_specific.mmc;
> +	new_ios = &cts->ios;
> +
> +	/* Update only requested fields */
> +	if (cts->ios_valid & MMC_CLK) {
> +		ios->clock = new_ios->clock;
> +		device_printf(sc->aw_dev, "Clock => %d\n", ios->clock);
> +	}
> +	if (cts->ios_valid & MMC_VDD) {
> +		ios->vdd = new_ios->vdd;
> +		device_printf(sc->aw_dev, "VDD => %d\n", ios->vdd);
> +	}
> +	if (cts->ios_valid & MMC_CS) {
> +		ios->chip_select = new_ios->chip_select;
> +		device_printf(sc->aw_dev, "CS => %d\n", ios->chip_select);
> +	}
> +	if (cts->ios_valid & MMC_BW) {
> +		ios->bus_width = new_ios->bus_width;
> +		device_printf(sc->aw_dev, "Bus width => %d\n", ios->bus_width);
> +	}
> +	if (cts->ios_valid & MMC_PM) {
> +		ios->power_mode = new_ios->power_mode;
> +		device_printf(sc->aw_dev, "Power mode => %d\n", ios->power_mode);
> +	}
> +	if (cts->ios_valid & MMC_BT) {
> +		ios->timing = new_ios->timing;
> +		device_printf(sc->aw_dev, "Timing => %d\n", ios->timing);
> +	}
> +	if (cts->ios_valid & MMC_BM) {
> +		ios->bus_mode = new_ios->bus_mode;
> +		device_printf(sc->aw_dev, "Bus mode => %d\n", ios->bus_mode);
> +	}
> +
> +	return (aw_mmc_update_ios(sc->aw_dev, NULL));
> +}
> +
> +static int
> +aw_mmc_cam_request(struct aw_mmc_softc *sc, union ccb *ccb)
> +{
> +	struct ccb_mmcio *mmcio;
> +
> +	mmcio = &ccb->mmcio;
> +
> +	AW_MMC_LOCK(sc);
> +
> +#ifdef DEBUG
> +	if (__predict_false(bootverbose)) {
> +		device_printf(sc->aw_dev, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n",
> +			    mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags,
> +			    mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0,
> +			    mmcio->cmd.data != NULL ? mmcio->cmd.data->flags: 0);
> +	}
> +#endif
> +	if (mmcio->cmd.data != NULL) {
> +		if (mmcio->cmd.data->len == 0 || mmcio->cmd.data->flags == 0)
> +			panic("data->len = %d, data->flags = %d -- something is b0rked",
> +			      (int)mmcio->cmd.data->len, mmcio->cmd.data->flags);
> +	}
> +	if (sc->ccb != NULL) {
> +		device_printf(sc->aw_dev, "Controller still has an active command\n");

 Should be under a ifdef DEBUG

> +		return (EBUSY);
> +	}
> +	sc->ccb = ccb;
> +	/* aw_mmc_request locks again */
> +	AW_MMC_UNLOCK(sc);
> +	aw_mmc_request(sc->aw_dev, NULL, NULL);
> +
> +	return (0);
> +}
> +#endif /* MMCCAM */
> +
> +static int
>  aw_mmc_probe(device_t dev)
>  {
>  
> @@ -192,7 +411,9 @@ aw_mmc_attach(device_t dev)
>  
>  	sc->aw_mmc_conf = (struct aw_mmc_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
>  
> +#ifndef MMCCAM
>  	sc->aw_req = NULL;
> +#endif
>  	if (bus_alloc_resources(dev, aw_mmc_res_spec, sc->aw_res) != 0) {
>  		device_printf(dev, "cannot allocate device resources\n");
>  		return (ENXIO);
> @@ -295,6 +516,35 @@ aw_mmc_attach(device_t dev)
>  	if (bus_width >= 8)
>  		sc->aw_host.caps |= MMC_CAP_8_BIT_DATA;
>  
> +#ifdef MMCCAM
> +	child = NULL; /* Not used by MMCCAM, need to silence compiler warnings */
> +	sc->ccb = NULL;
> +	if ((sc->devq = cam_simq_alloc(1)) == NULL) {
> +		goto fail;
> +	}
> +
> +	mtx_init(&sc->sim_mtx, "awmmcsim", NULL, MTX_DEF);
> +	sc->sim = cam_sim_alloc(aw_mmc_cam_action, aw_mmc_cam_poll,
> +	    "aw_mmc_sim", sc, device_get_unit(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->aw_dev, 0) != 0) {
> +                device_printf(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;
> +        }
> +
> +        mtx_unlock(&sc->sim_mtx);
> +#else /* !MMCCAM */
>  	child = device_add_child(dev, "mmc", -1);
>  	if (child == NULL) {
>  		device_printf(dev, "attaching MMC bus failed!\n");
> @@ -305,7 +555,7 @@ aw_mmc_attach(device_t dev)
>  		device_delete_child(dev, child);
>  		goto fail;
>  	}
> -
> +#endif /* MMCCAM */
>  	return (0);
>  
>  fail:
> @@ -314,6 +564,17 @@ fail:
>  	bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES], sc->aw_intrhand);
>  	bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res);
>  
> +#ifdef MMCCAM
> +	if (sc->sim != NULL) {
> +                mtx_lock(&sc->sim_mtx);
> +                xpt_bus_deregister(cam_sim_path(sc->sim));
> +                cam_sim_free(sc->sim, FALSE);
> +                mtx_unlock(&sc->sim_mtx);
> +        }
> +
> +        if (sc->devq != NULL)
> +                cam_simq_free(sc->devq);
> +#endif
>  	return (ENXIO);
>  }
>  
> @@ -437,7 +698,11 @@ aw_mmc_prepare_dma(struct aw_mmc_softc *sc)
>  	struct mmc_command *cmd;
>  	uint32_t val;
>  
> +#ifdef MMCCAM
> +	cmd = &sc->ccb->mmcio.cmd;
> +#else
>  	cmd = sc->aw_req->cmd;
> +#endif
>  	if (cmd->data->len > (sc->aw_mmc_conf->dma_xferlen * AW_MMC_DMA_SEGS))
>  		return (EFBIG);
>  	error = bus_dmamap_load(sc->aw_dma_buf_tag, sc->aw_dma_buf_map,
> @@ -549,11 +814,25 @@ static void
>  aw_mmc_req_done(struct aw_mmc_softc *sc)
>  {
>  	struct mmc_command *cmd;
> +#ifdef MMCCAM
> +	union ccb *ccb;
> +#else
>  	struct mmc_request *req;
> +#endif
>  	uint32_t val, mask;
>  	int retry;
>  
> +#ifdef MMCCAM
> +	ccb = sc->ccb;
> +	cmd = &ccb->mmcio.cmd;
> +#else
>  	cmd = sc->aw_req->cmd;
> +#endif
> +#ifdef DEBUG
> +	if (bootverbose) {
> +		device_printf(sc->aw_dev, "%s: cmd %d err %d\n", __func__, cmd->opcode, cmd->error);
> +	}
> +#endif
>  	if (cmd->error != MMC_ERR_NONE) {
>  		/* Reset the FIFO and DMA engines. */
>  		mask = AW_MMC_GCTL_FIFO_RST | AW_MMC_GCTL_DMA_RST;
> @@ -573,14 +852,21 @@ aw_mmc_req_done(struct aw_mmc_softc *sc)
>  		aw_mmc_update_clock(sc, 1);
>  	}
>  
> -	req = sc->aw_req;
>  	callout_stop(&sc->aw_timeoutc);
> -	sc->aw_req = NULL;
>  	sc->aw_intr = 0;
>  	sc->aw_resid = 0;
>  	sc->aw_dma_map_err = 0;
>  	sc->aw_intr_wait = 0;
> +#ifdef MMCCAM
> +	sc->ccb = NULL;
> +	ccb->ccb_h.status =
> +		(ccb->mmcio.cmd.error == 0 ? CAM_REQ_CMP : CAM_REQ_CMP_ERR);
> +	xpt_done(ccb);
> +#else
> +	req = sc->aw_req;
> +	sc->aw_req = NULL;
>  	req->done(req);
> +#endif
>  }
>  
>  static void
> @@ -597,7 +883,11 @@ aw_mmc_req_ok(struct aw_mmc_softc *sc)
>  			break;
>  		DELAY(1000);
>  	}
> +#ifdef MMCCAM
> +	cmd = &sc->ccb->mmcio.cmd;
> +#else
>  	cmd = sc->aw_req->cmd;
> +#endif
>  	if (timeout == 0) {
>  		cmd->error = MMC_ERR_FAILED;
>  		aw_mmc_req_done(sc);
> @@ -618,15 +908,30 @@ aw_mmc_req_ok(struct aw_mmc_softc *sc)
>  	aw_mmc_req_done(sc);
>  }
>  
> +
> +static inline void
> +set_mmc_error(struct aw_mmc_softc *sc, int error_code)
> +{
> +#ifdef MMCCAM
> +	sc->ccb->mmcio.cmd.error = error_code;
> +#else
> +	sc->aw_req->cmd->error = error_code;
> +#endif
> +}
> +
>  static void
>  aw_mmc_timeout(void *arg)
>  {
>  	struct aw_mmc_softc *sc;
>  
>  	sc = (struct aw_mmc_softc *)arg;
> +#ifdef MMCCAM
> +	if (sc->ccb != NULL) {
> +#else
>  	if (sc->aw_req != NULL) {
> +#endif
>  		device_printf(sc->aw_dev, "controller timeout\n");
> -		sc->aw_req->cmd->error = MMC_ERR_TIMEOUT;
> +		set_mmc_error(sc, MMC_ERR_TIMEOUT);
>  		aw_mmc_req_done(sc);
>  	} else
>  		device_printf(sc->aw_dev,
> @@ -634,6 +939,28 @@ aw_mmc_timeout(void *arg)
>  }
>  
>  static void
> +aw_mmc_print_error(uint32_t err)
> +{
> +	if(err & AW_MMC_INT_RESP_ERR)
> +		printf("AW_MMC_INT_RESP_ERR ");
> +	if (err & AW_MMC_INT_RESP_CRC_ERR)
> +		printf("AW_MMC_INT_RESP_CRC_ERR ");
> +	if (err & AW_MMC_INT_DATA_CRC_ERR)
> +		printf("AW_MMC_INT_DATA_CRC_ERR ");
> +	if (err & AW_MMC_INT_RESP_TIMEOUT)
> +		printf("AW_MMC_INT_RESP_TIMEOUT ");
> +	if (err & AW_MMC_INT_FIFO_RUN_ERR)
> +		printf("AW_MMC_INT_FIFO_RUN_ERR ");
> +	if (err & AW_MMC_INT_CMD_BUSY)
> +		printf("AW_MMC_INT_CMD_BUSY ");
> +	if (err & AW_MMC_INT_DATA_START_ERR)
> +		printf("AW_MMC_INT_DATA_START_ERR ");
> +	if (err & AW_MMC_INT_DATA_END_BIT_ERR)
> +		printf("AW_MMC_INT_DATA_END_BIT_ERR");
> +	printf("\n");
> +}
> +
> +static void
>  aw_mmc_intr(void *arg)
>  {
>  	bus_dmasync_op_t sync_op;
> @@ -654,31 +981,41 @@ aw_mmc_intr(void *arg)
>  	device_printf(sc->aw_dev, "idst: %#x, imask: %#x, rint: %#x\n",
>  	    idst, imask, rint);
>  #endif
> +#ifdef MMCCAM
> +	if (sc->ccb == NULL) {
> +#else
>  	if (sc->aw_req == NULL) {
> +#endif
>  		device_printf(sc->aw_dev,
>  		    "Spurious interrupt - no active request, rint: 0x%08X\n",
>  		    rint);
> +		aw_mmc_print_error(rint);
>  		goto end;
>  	}
>  	if (rint & AW_MMC_INT_ERR_BIT) {
>  		if (bootverbose)
>  			device_printf(sc->aw_dev, "error rint: 0x%08X\n", rint);
> +		aw_mmc_print_error(rint);
>  		if (rint & AW_MMC_INT_RESP_TIMEOUT)
> -			sc->aw_req->cmd->error = MMC_ERR_TIMEOUT;
> +			set_mmc_error(sc, MMC_ERR_TIMEOUT);
>  		else
> -			sc->aw_req->cmd->error = MMC_ERR_FAILED;
> +			set_mmc_error(sc, MMC_ERR_FAILED);
>  		aw_mmc_req_done(sc);
>  		goto end;
>  	}
>  	if (idst & AW_MMC_IDST_ERROR) {
>  		device_printf(sc->aw_dev, "error idst: 0x%08x\n", idst);
> -		sc->aw_req->cmd->error = MMC_ERR_FAILED;
> +		set_mmc_error(sc, MMC_ERR_FAILED);
>  		aw_mmc_req_done(sc);
>  		goto end;
>  	}
>  
>  	sc->aw_intr |= rint;
> +#ifdef MMCCAM
> +	data = sc->ccb->mmcio.cmd.data;
> +#else
>  	data = sc->aw_req->cmd->data;
> +#endif
>  	if (data != NULL && (idst & AW_MMC_IDST_COMPLETE) != 0) {
>  		if (data->flags & MMC_DATA_WRITE)
>  			sync_op = BUS_DMASYNC_POSTWRITE;
> @@ -712,13 +1049,29 @@ aw_mmc_request(device_t bus, device_t child, struct mm
>  	sc = device_get_softc(bus);
>  
>  	AW_MMC_LOCK(sc);
> +#ifdef MMCCAM
> +	KASSERT(req == NULL, ("req should be NULL in MMCCAM case!"));
> +	/*
> +	 * For MMCCAM, sc->ccb has been NULL-checked and populated
> +	 * by aw_mmc_cam_request() already.
> +	 */
> +	cmd = &sc->ccb->mmcio.cmd;
> +#else
>  	if (sc->aw_req) {
>  		AW_MMC_UNLOCK(sc);
>  		return (EBUSY);
>  	}
> -
>  	sc->aw_req = req;
>  	cmd = req->cmd;
> +
> +#ifdef DEBUG
> +	if (bootverbose)
> +		device_printf(sc->aw_dev, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n",
> +			      cmd->opcode, cmd->arg, cmd->flags,
> +			      cmd->data != NULL ? (unsigned int)cmd->data->len : 0,
> +			      cmd->data != NULL ? cmd->data->flags: 0);
> +#endif
> +#endif
>  	cmdreg = AW_MMC_CMDR_LOAD;
>  	imask = AW_MMC_INT_ERR_BIT;
>  	sc->aw_intr_wait = 0;
> @@ -1163,4 +1516,6 @@ static driver_t aw_mmc_driver = {
>  
>  DRIVER_MODULE(aw_mmc, simplebus, aw_mmc_driver, aw_mmc_devclass, NULL,
>      NULL);
> +#ifndef MMCCAM
>  MMC_DECLARE_BRIDGE(aw_mmc);
> +#endif
> 
> Modified: head/sys/arm/allwinner/files.allwinner
> ==============================================================================
> --- head/sys/arm/allwinner/files.allwinner	Thu Jun 21 11:43:54 2018	(r335475)
> +++ head/sys/arm/allwinner/files.allwinner	Thu Jun 21 11:49:21 2018	(r335476)
> @@ -10,7 +10,7 @@ arm/allwinner/a10_sramc.c		standard
>  arm/allwinner/aw_gpio.c			optional	gpio
>  arm/allwinner/aw_if_dwc.c		optional	dwc
>  arm/allwinner/aw_machdep.c		standard
> -arm/allwinner/aw_mmc.c			optional	mmc
> +arm/allwinner/aw_mmc.c			optional	mmc | mmccam
>  arm/allwinner/aw_mp.c			optional	smp
>  arm/allwinner/aw_nmi.c			optional	intrng
>  arm/allwinner/aw_rsb.c			optional	rsb | p2wi
> 
> Modified: head/sys/conf/files.arm64
> ==============================================================================
> --- head/sys/conf/files.arm64	Thu Jun 21 11:43:54 2018	(r335475)
> +++ head/sys/conf/files.arm64	Thu Jun 21 11:49:21 2018	(r335476)
> @@ -27,7 +27,7 @@ cloudabi64_vdso_blob.o		optional	compat_cloudabi64	\
>  # Allwinner common files
>  arm/allwinner/a10_ehci.c	optional	ehci aw_ehci fdt
>  arm/allwinner/aw_gpio.c		optional	gpio aw_gpio fdt
> -arm/allwinner/aw_mmc.c		optional	mmc aw_mmc fdt
> +arm/allwinner/aw_mmc.c		optional	mmc aw_mmc fdt | mmccam aw_mmc fdt
>  arm/allwinner/aw_nmi.c		optional	aw_nmi fdt \
>  	compile-with "${NORMAL_C} -I$S/gnu/dts/include"
>  arm/allwinner/aw_rsb.c		optional	aw_rsb fdt


-- 
Emmanuel Vadot <manu@bidouilliste.com> <manu@freebsd.org>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180621191615.a407caac02bd671c267f40aa>