Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Jun 2015 07:48:01 GMT
From:      pratiksinghal@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r287418 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner
Message-ID:  <201506210748.t5L7m1VS047282@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pratiksinghal
Date: Sun Jun 21 07:48:00 2015
New Revision: 287418
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287418

Log:
  Cleaned up code

Replaced:
  soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c   (contents, props changed)
     - copied, changed from r287417, mirror/FreeBSD/head/sys/arm/allwinner/a10_mmc.c

Copied and modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c (from r287417, mirror/FreeBSD/head/sys/arm/allwinner/a10_mmc.c)
==============================================================================
--- mirror/FreeBSD/head/sys/arm/allwinner/a10_mmc.c	Sun Jun 21 06:57:40 2015	(r287417, copy source)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c	Sun Jun 21 07:48:00 2015	(r287418)
@@ -38,6 +38,7 @@
 #include <sys/resource.h>
 #include <sys/rman.h>
 #include <sys/sysctl.h>
+#include <sys/endian.h>
 
 #include <machine/bus.h>
 
@@ -48,12 +49,21 @@
 #include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
+
 #include <arm/allwinner/a10_clk.h>
 #include <arm/allwinner/a10_mmc.h>
 
 #define	A10_MMC_MEMRES		0
 #define	A10_MMC_IRQRES		1
 #define	A10_MMC_RESSZ		2
+#define A10_MMC_NDESC		16
+#define A10_DMA_NSEGS		16
+#define A10_DMA_BUFF_SIZE	0x2000
+#define A10_DMA_MAX_SIZE	0x20000
+#define A10_MMC_DMA_FTRGLEVEL_A20	0x20070008
+#define A10_MMC_DMA_FTRGLEVEL_A10 	0x00070208
+#define A10_MMC_DMA_MAXLEN  	(A10_DMA_MAX_SIZE)
+#define A10_MMC_DMA_MINLEN	512
 
 struct a10_mmc_softc {
 	bus_space_handle_t	a10_bsh;
@@ -69,8 +79,22 @@
 	struct mtx		a10_mtx;
 	struct resource *	a10_res[A10_MMC_RESSZ];
 	uint32_t		a10_intr;
+	uint32_t		a10_idst ;
 	uint32_t		a10_intr_wait;
 	void *			a10_intrhand;
+	int 			a10_use_dma ;
+
+	/* Fields required for DMA access */
+	bus_addr_t	  	a10_dma_cb_arg ;
+	bus_dmamap_t		a10_dma_map ;
+	bus_dma_tag_t 		a10_dma_tag ;
+	void* 			a10_dma_desc ;
+	bus_dma_tag_t		a10_dma_buff_tag ;
+	bus_dmamap_t		a10_dma_buff_map ;
+	bus_addr_t		a10_dma_buff_addrs[A10_DMA_NSEGS] ;
+	bus_size_t		a10_dma_buff_sizes[A10_DMA_NSEGS] ;  
+	uint32_t 		a10_dma_nsegs ; 
+
 };
 
 static struct resource_spec a10_mmc_res_spec[] = {
@@ -81,11 +105,16 @@
 
 static int a10_mmc_probe(device_t);
 static int a10_mmc_attach(device_t);
+static int a10_mmc_setup_dma(struct a10_mmc_softc*, device_t) ;
+static int a10_mmc_prepare_dma(struct a10_mmc_softc*) ;
+static int a10_mmc_can_do_dma(struct mmc_request*) ;
+static void a10_dma_buff_cb(void*, bus_dma_segment_t*, int, int) ;
 static int a10_mmc_detach(device_t);
 static int a10_mmc_reset(struct a10_mmc_softc *);
 static void a10_mmc_intr(void *);
 static int a10_mmc_update_clock(struct a10_mmc_softc *);
 
+static void a10_dma_cb(void*, bus_dma_segment_t*, int, int) ;
 static int a10_mmc_update_ios(device_t, device_t);
 static int a10_mmc_request(device_t, device_t, struct mmc_request *);
 static int a10_mmc_get_ro(device_t, device_t);
@@ -98,6 +127,12 @@
 	bus_space_read_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg)
 #define	A10_MMC_WRITE_4(_sc, _reg, _value)				\
 	bus_space_write_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg, _value)
+#define	A10_MMC_READ_2(_sc, _reg)					\
+	bus_space_read_2((_sc)->a10_bst, (_sc)->a10_bsh, _reg)
+#define	A10_MMC_WRITE_2(_sc, _reg, _value)				\
+	bus_space_write_2((_sc)->a10_bst, (_sc)->a10_bsh, _reg, _value)
+
+
 
 static int
 a10_mmc_probe(device_t dev)
@@ -121,6 +156,7 @@
 	struct sysctl_oid_list *tree;
 
 	sc = device_get_softc(dev);
+	sc->a10_use_dma = 1 ;
 	sc->a10_dev = dev;
 	sc->a10_req = NULL;
 	sc->a10_id = device_get_unit(dev);
@@ -183,6 +219,17 @@
 		goto fail;
 	}
 
+	if (sc->a10_use_dma == 1) {
+		if (a10_mmc_setup_dma(sc,dev) != 0) {
+			device_printf(sc->a10_dev, "Couldn't setup DMA!\n") ;
+			sc->a10_use_dma = 0 ;
+		}
+	}
+	//device_printf(sc->a10_dev, "The address of desc is %p\n",sc->a10_dma_desc) ; 
+	sc->a10_dma_nsegs = 0 ; 
+#ifdef DEBUG
+	device_printf(sc->a10_dev, "DMA status %d\n", sc->a10_use_dma) ;
+#endif
 	return (0);
 
 fail:
@@ -195,6 +242,154 @@
 }
 
 static int
+a10_mmc_setup_dma(struct a10_mmc_softc* sc, device_t dev)
+{
+	uint32_t a10_dma_size = sizeof(struct a10_mmc_dma_desc)*(A10_MMC_NDESC);
+
+	uint32_t error ;
+	error = bus_dma_tag_create(bus_get_dma_tag(dev),1,
+				a10_dma_size,BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
+				NULL,NULL,a10_dma_size,
+				1,a10_dma_size,0,
+				NULL,NULL,&sc->a10_dma_tag) ;
+	if (error)
+		return (error) ;
+	error = bus_dmamem_alloc(sc->a10_dma_tag,&sc->a10_dma_desc,BUS_DMA_WAITOK|BUS_DMA_ZERO,&sc->a10_dma_map) ;
+		if (error)
+			return (error) ;
+
+	error = bus_dmamap_load(sc->a10_dma_tag, sc->a10_dma_map,sc->a10_dma_desc,a10_dma_size,a10_dma_cb, &sc->a10_dma_cb_arg,0) ;
+
+	if ((error != 0)&&(error != EINPROGRESS))
+		return (error) ;
+	error = bus_dma_tag_create(bus_get_dma_tag(dev),1,
+				0,BUS_SPACE_MAXADDR_32BIT,BUS_SPACE_MAXADDR,
+				NULL,NULL,A10_DMA_MAX_SIZE,
+				A10_DMA_NSEGS,A10_DMA_BUFF_SIZE,0,
+				NULL,NULL,&sc->a10_dma_buff_tag) ;
+	if (error)
+		return (error) ;
+
+	error = bus_dmamap_create(sc->a10_dma_buff_tag,0,&sc->a10_dma_buff_map) ;
+	if (error)
+		return (error) ;
+
+	return(0) ;
+
+}
+
+static int
+a10_mmc_prepare_dma(struct a10_mmc_softc* sc)
+{
+
+	struct a10_mmc_dma_desc* dma = sc->a10_dma_desc ;
+	struct mmc_command* cmd = sc->a10_req->cmd ;
+	bus_addr_t desc_paddr = sc->a10_dma_cb_arg ;
+	int desc, rem ;
+	uint32_t val;
+	desc = 0 ;
+	rem = min(A10_MMC_DMA_MAXLEN,cmd->data->len) ;
+	uint32_t error = bus_dmamap_load(sc->a10_dma_buff_tag, sc->a10_dma_buff_map,
+					cmd->data->data,rem,a10_dma_buff_cb,
+					sc,0) ;
+	if (error == EINPROGRESS) {
+		for( ; sc->a10_dma_nsegs == 0 ; )  { }
+	}
+	else if (error != 0)  {
+		device_printf(sc->a10_dev, "DMA transaction failed due to insufficient resources! error = %u\n",error) ;
+		return EIO  ;
+	}
+
+	dma[0].config |= htole32(A10_MMC_DMA_CONFIG_FD) ; 
+	while (desc < A10_MMC_NDESC) { 
+		dma[desc].buff_size = htole32(sc->a10_dma_buff_sizes[desc]) ;
+		dma[desc].buff_addr = htole32(sc->a10_dma_buff_addrs[desc]) ;
+		dma[desc].config = htole32(A10_MMC_DMA_CONFIG_CH|A10_MMC_DMA_CONFIG_OWN) ;
+		rem -= sc->a10_dma_buff_sizes[desc] ; 
+		cmd->data->len -= sc->a10_dma_buff_sizes[desc] ; 
+		if (rem > 0) {
+			dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_DIC) ;
+			dma[desc].next = htole32(desc_paddr + ((desc+1)*sizeof(struct a10_mmc_dma_desc))) ;
+		}
+		else {
+			dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_LD | A10_MMC_DMA_CONFIG_ER) ; 
+			dma[desc].next = 0  ; 
+			break ; 
+		}
+		desc++ ;
+	}
+	if (rem > 0) {
+		device_printf(sc->a10_dev, "Couldn't find enough descriptors for DMA transfer!, rem = %d\n", rem);
+		return EIO ;
+	}
+
+	if (sc->a10_req->cmd->data->flags & MMC_DATA_WRITE)
+		bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_PREWRITE) ;
+	else
+		bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_PREREAD) ;
+
+	bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE) ;
+
+	val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) ;
+	val |= A10_MMC_DMA_ENABLE ;
+	val |= A10_MMC_INT_ENABLE ;
+	A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,val) ;
+	val |= A10_MMC_DMA_RESET ;
+	A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,val) ;
+	A10_MMC_WRITE_4(sc, A10_MMC_DMAC,A10_MMC_IDMAC_SOFT_RST) ;
+	A10_MMC_WRITE_4(sc, A10_MMC_DMAC,A10_MMC_IDMAC_IDMA_ON | A10_MMC_IDMAC_FIX_BURST) ;
+	val = A10_MMC_READ_4(sc,A10_MMC_IDIE) ;
+	val &= ~(A10_MMC_IDMAC_RECEIVE_INT | A10_MMC_IDMAC_TRANSMIT_INT) ;
+	A10_MMC_WRITE_4(sc,A10_MMC_IDIE, val) ;
+	if (sc->a10_req->cmd->data->flags & MMC_DATA_WRITE)
+		val |= A10_MMC_IDMAC_TRANSMIT_INT ;
+	else
+		val |= A10_MMC_IDMAC_RECEIVE_INT ;
+	A10_MMC_WRITE_4(sc, A10_MMC_IDIE,val) ;
+	A10_MMC_WRITE_4(sc, A10_MMC_DLBA,desc_paddr) ;
+	A10_MMC_WRITE_4(sc, A10_MMC_FTRGL,A10_MMC_DMA_FTRGLEVEL_A10) ;
+
+	return (0) ;
+}
+
+
+static int
+a10_mmc_can_do_dma(struct mmc_request* req)
+{
+	if (req->cmd->data->len >= A10_MMC_DMA_MAXLEN) 
+	//if ((req->cmd->data->len > A10_MMC_DMA_MAXLEN) || (req->cmd->data->len <= A10_MMC_DMA_MINLEN))
+		return (0) ;
+	else
+		return (1) ;
+}
+static void
+a10_dma_cb(void* arg, bus_dma_segment_t* segs, int nsegs, int error)
+{
+	if (error) {
+		printf("a10_mmc: Error in a10_dma_callback function, code = %d\n",error) ;
+		return ;
+	}
+
+	*(bus_addr_t*)arg = segs[0].ds_addr ;
+}
+
+static void
+a10_dma_buff_cb(void* arg, bus_dma_segment_t* segs, int nsegs, int error)
+{
+	if (error) {
+		printf("a10_mmc: Error in a10_dma_buff_callback function, code = %d\n", error) ;
+		return  ;
+	}
+	int i ; 
+	struct a10_mmc_softc* sc = (struct a10_mmc_softc*) arg ; 
+	sc->a10_dma_nsegs = nsegs ; 
+	for(i=0; i<nsegs; i++) { 
+		sc->a10_dma_buff_addrs[i] = segs[i].ds_addr ; 
+		sc->a10_dma_buff_sizes[i] = segs[i].ds_len ; 
+	}
+}
+
+static int
 a10_mmc_detach(device_t dev)
 {
 
@@ -217,21 +412,18 @@
 	if (timeout == 0)
 		return (ETIMEDOUT);
 
-	/* Set the timeout. */
 	A10_MMC_WRITE_4(sc, A10_MMC_TIMEOUT, 0xffffffff);
-
-	/* Clear pending interrupts. */
 	A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+	A10_MMC_WRITE_4(sc, A10_MMC_IDST, 0xffffffff) ;
 	/* Unmask interrupts. */
 	A10_MMC_WRITE_4(sc, A10_MMC_IMASK,
 	    A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT |
 	    A10_MMC_DATA_OVER | A10_MMC_AUTOCMD_DONE |
 	    A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ);
+	uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
+	temp_val  = temp_val & (~A10_MMC_DMA_ENABLE) ;
 	/* Enable interrupts and AHB access. */
-	A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
-	    A10_MMC_READ_4(sc, A10_MMC_GCTRL) |
-	    A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB);
-
+	A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,temp_val) ;
 	return (0);
 }
 
@@ -256,7 +448,9 @@
 	sc->a10_req = NULL;
 	sc->a10_intr = 0;
 	sc->a10_resid = 0;
+	sc->a10_idst = 0 ;
 	sc->a10_intr_wait = 0;
+	sc->a10_dma_nsegs = 0 ;
 	req->done(req);
 }
 
@@ -295,7 +489,7 @@
 	a10_mmc_req_done(sc);
 }
 
-static void 
+static void
 a10_mmc_timeout(void *arg)
 {
 	struct a10_mmc_softc *sc;
@@ -337,48 +531,80 @@
 {
 	struct a10_mmc_softc *sc;
 	struct mmc_data *data;
-	uint32_t imask, rint;
+	uint32_t imask, rint,idst;
 
 	sc = (struct a10_mmc_softc *)arg;
 	A10_MMC_LOCK(sc);
 	rint = A10_MMC_READ_4(sc, A10_MMC_RINTR);
 	imask = A10_MMC_READ_4(sc, A10_MMC_IMASK);
-	if (imask == 0 && rint == 0) {
+	idst = A10_MMC_READ_4(sc, A10_MMC_IDST) ;
+
+	if (imask == 0 && rint == 0 && idst == 0 ) {
 		A10_MMC_UNLOCK(sc);
 		return;
 	}
-#ifdef DEBUG
-	device_printf(sc->a10_dev, "imask: %#x, rint: %#x\n", imask, rint);
-#endif
+
+	A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint) ;
+	A10_MMC_WRITE_4(sc, A10_MMC_IDST, idst) ;
+	A10_MMC_WRITE_4(sc, A10_MMC_IMASK, imask) ;
+	//device_printf(sc->a10_dev, "imask: %#x, rint: %#x, idst: %#x, gctrl: %#x\n", imask, rint,idst, A10_MMC_READ_4(sc, A10_MMC_GCTRL));
 	if (sc->a10_req == NULL) {
 		device_printf(sc->a10_dev,
 		    "Spurious interrupt - no active request, rint: 0x%08X\n",
 		    rint);
-		A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint);
 		A10_MMC_UNLOCK(sc);
 		return;
 	}
+
+	sc->a10_intr |= rint;
 	if (rint & A10_MMC_INT_ERR_BIT) {
 		device_printf(sc->a10_dev, "error rint: 0x%08X\n", rint);
-		if (rint & A10_MMC_RESP_TIMEOUT)
+		if (rint & A10_MMC_RESP_TIMEOUT) {
 			sc->a10_req->cmd->error = MMC_ERR_TIMEOUT;
+		}
 		else
 			sc->a10_req->cmd->error = MMC_ERR_FAILED;
-		A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint);
 		a10_mmc_req_done(sc);
 		A10_MMC_UNLOCK(sc);
 		return;
 	}
 
-	sc->a10_intr |= rint;
+	if (idst & A10_MMC_IDMAC_ERROR) {
+		device_printf(sc->a10_dev, "error idst: 0x%08x\n", idst) ;
+		sc->a10_req->cmd->error = MMC_ERR_FAILED ;
+		a10_mmc_req_done(sc) ;
+		A10_MMC_UNLOCK(sc) ;
+		return ;
+	}
+
+	if ((idst & A10_MMC_IDMAC_COMPLETE) && ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)) {
+		if (sc->a10_req->cmd->data->flags & MMC_DATA_WRITE)
+			bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_POSTWRITE) ;
+		else 
+			bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_POSTREAD) ;
+		bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_POSTWRITE) ; 
+		bus_dmamap_unload(sc->a10_dma_buff_tag, sc->a10_dma_buff_map) ;
+		a10_mmc_req_ok(sc) ;
+		A10_MMC_UNLOCK(sc) ;
+		return ;
+	}
+
+	if ((idst)&&(!(idst & A10_MMC_IDMAC_COMPLETE))) {
+		device_printf(sc->a10_dev, "DMA timeout error!\n") ;
+		sc->a10_req->cmd->error = MMC_ERR_TIMEOUT ;
+		a10_mmc_req_done(sc) ;
+		A10_MMC_UNLOCK(sc) ;
+		return  ;
+	}
+
 	data = sc->a10_req->cmd->data;
+
 	if (data != NULL && (rint & (A10_MMC_DATA_OVER |
 	    A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ)) != 0)
-		a10_mmc_pio_transfer(sc, data);
+			a10_mmc_pio_transfer(sc, data);
 	if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)
 		a10_mmc_req_ok(sc);
 
-	A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint);
 	A10_MMC_UNLOCK(sc);
 }
 
@@ -388,7 +614,7 @@
 	int blksz;
 	struct a10_mmc_softc *sc;
 	struct mmc_command *cmd;
-	uint32_t cmdreg;
+	uint32_t cmdreg ;
 
 	sc = device_get_softc(bus);
 	A10_MMC_LOCK(sc);
@@ -396,6 +622,7 @@
 		A10_MMC_UNLOCK(sc);
 		return (EBUSY);
 	}
+
 	sc->a10_req = req;
 	cmd = req->cmd;
 	cmdreg = A10_MMC_START;
@@ -410,8 +637,10 @@
 
 	sc->a10_intr = 0;
 	sc->a10_resid = 0;
+	sc->a10_idst = 0 ;
 	sc->a10_intr_wait = A10_MMC_CMD_DONE;
 	cmd->error = MMC_ERR_NONE;
+
 	if (cmd->data != NULL) {
 		sc->a10_intr_wait |= A10_MMC_DATA_OVER;
 		cmdreg |= A10_MMC_DATA_EXP | A10_MMC_WAIT_PREOVER;
@@ -419,11 +648,38 @@
 			cmdreg |= A10_MMC_SEND_AUTOSTOP;
 			sc->a10_intr_wait |= A10_MMC_AUTOCMD_DONE;
 		}
-		if (cmd->data->flags & MMC_DATA_WRITE)
+		if (cmd->data->flags & MMC_DATA_WRITE) {
 			cmdreg |= A10_MMC_WRITE;
+		}
+
 		blksz = min(cmd->data->len, MMC_SECTOR_SIZE);
 		A10_MMC_WRITE_4(sc, A10_MMC_BLKSZ, blksz);
 		A10_MMC_WRITE_4(sc, A10_MMC_BCNTR, cmd->data->len);
+
+		if ((sc->a10_use_dma == 1)&&(a10_mmc_can_do_dma(req))) {
+			uint32_t error = a10_mmc_prepare_dma(sc) ;
+			if (error == 0) {
+				A10_MMC_WRITE_4(sc, A10_MMC_IMASK, A10_MMC_READ_4(sc, A10_MMC_IMASK) | (A10_MMC_TX_DATA_REQ | A10_MMC_RX_DATA_REQ)) ;
+			}
+			else {
+				uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
+				temp_val  = temp_val & (~A10_MMC_DMA_ENABLE) ;
+				A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ;
+			}
+		}
+		else
+		{
+			uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
+			temp_val  = temp_val & (~A10_MMC_DMA_ENABLE) ;
+			A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ;
+		}
+
+	}
+	else
+	{
+		uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
+		temp_val = temp_val & (~A10_MMC_DMA_ENABLE) ;
+		A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ;
 	}
 
 	A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg);
@@ -436,7 +692,7 @@
 }
 
 static int
-a10_mmc_read_ivar(device_t bus, device_t child, int which, 
+a10_mmc_read_ivar(device_t bus, device_t child, int which,
     uintptr_t *result)
 {
 	struct a10_mmc_softc *sc;



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