PERFORCE change 106081 for review

Warner Losh imp at FreeBSD.org
Wed Sep 13 15:24:33 PDT 2006


http://perforce.freebsd.org/chv.cgi?CH=106081

Change 106081 by imp at imp_lighthouse on 2006/09/13 22:24:24

	SD cards now detected
	
	# Had to disable strategy and make it EIO since we have an interrupt
	# problem elsewhere that was keeping bio's in flight which was hanging
	# the boot.

Affected files ...

.. //depot/projects/arm/src/sys/arm/at91/at91_qdmmc.c#9 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/at91/at91_qdmmc.c#9 (text+ko) ====

@@ -131,6 +131,7 @@
 	struct at91_qdmmc_softc *sc = device_get_softc(dev);
 	uint32_t error;
 
+	device_printf(dev, "Sending command %x:%x\n", cmd, arg);
 	WR4(sc, MCI_ARGR, arg);
 	WR4(sc, MCI_CMDR, cmd);
 
@@ -162,6 +163,8 @@
 	WR4(sc, MCI_ARGR, sc->cards[0].rca << 16);
 	WR4(sc, MCI_CMDR, APP_CMD);
 
+	printf("CMD55: %x\n", sc->cards[0].rca << 16);
+
 	// wait for CMDRDY Status flag to read the response
 	do
 	{
@@ -172,10 +175,6 @@
 	if ((status & MCI_SR_ERROR) != 0 )
 		return (status & MCI_SR_ERROR);
 
-	// check if it is a specific command and then send the command
-	if ((cmd & SDCARD_APP_ALL_CMD) == 0)
-		return MCI_SR_ERROR;
-
 	return (at91_qdmmc_SendCommand(dev, cmd, arg));
 }
 
@@ -203,17 +202,18 @@
 		if (response != 0)
 			return (-1);
 		response = RD4(sc, MCI_RSPR);
+		printf("card's OCR is %#x\n", response);
 	}
 	
 	return (response);
 }
 
 static int
-at91_qdmmc_SDCard_GetCID(device_t dev, uint32_t *response)
+at91_qdmmc_GetCID(device_t dev, uint32_t *response)
 {
 	struct at91_qdmmc_softc *sc = device_get_softc(dev);
 
-	if (at91_qdmmc_SendCommand(dev, ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT))
+	if (at91_qdmmc_SendCommand(dev, ALL_SEND_CID_CMD, 0))
 		return EIO;
 	response[0] = RD4(sc, MCI_RSPR + 0 * sizeof(response[0]));
    	response[1] = RD4(sc, MCI_RSPR + 1 * sizeof(response[0]));
@@ -282,43 +282,54 @@
 at91_qdmmc_sdcard_init(device_t dev)
 {
 	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-	uint32_t	*csd;
+	uint32_t	*csd, *cid;
 
-	at91_qdmmc_SendCommand(dev, GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
+	// CMD0
+	at91_qdmmc_SendCommand(dev, GO_IDLE_STATE_CMD, 0);
 
-	if (at91_qdmmc_SDCard_GetOCR(dev) == -1)
+	if (at91_qdmmc_SDCard_GetOCR(dev) == -1) { // ACMD41
+		printf("SD: can't get OCR\n");
 		return ENXIO;
-
-	csd = &sc->cards[0].CSD[0];
-	if (at91_qdmmc_SDCard_GetCID(dev, csd) != 0)
+	}
+	cid = &sc->cards[0].CID[0];
+	if (at91_qdmmc_GetCID(dev, cid) != 0) {	// CMD2
+		printf("SD: cant get cid\n");
 		return ENXIO;
-	if (at91_qdmmc_SendCommand(dev, SET_RELATIVE_ADDR_CMD, 0) != 0)
+	}
+	if (at91_qdmmc_SendCommand(dev, SET_RELATIVE_ADDR_CMD, 0) != 0) {
+		printf("SD: Can't set RCA to 0\n");
 		return ENXIO;
+	}
 	sc->cards[0].rca = RD4(sc, MCI_RSPR) >> 16;
-	if (at91_qdmmc_GetCSD(dev, sc->cards[0].rca, csd) != 0)
+	csd = &sc->cards[0].CSD[0];
+	if (at91_qdmmc_GetCSD(dev, sc->cards[0].rca, csd) != 0) {
+		printf("SD: can't get csd\n");
 		return ENXIO;
-	printf("Found SD Card - CID = 0x%x%x%x%x\n",
-	    sc->cards[0].CID[0],
-	    sc->cards[0].CID[1],
-	    sc->cards[0].CID[2],
-	    sc->cards[0].CID[3]);
-	printf("SD: Vendor-ID = 0x%x\n", sc->cards[0].CID[0] >> 24);
-	printf("SD: OEM-ID = 0x%x\n", (sc->cards[0].CID[0] >> 8) & 0xffff);
-	sc->cards[0].name[0] = (sc->cards[0].CID[0] >> 0) & 0xff;
-	sc->cards[0].name[1] = (sc->cards[0].CID[1] >> 24) & 0xff;
-	sc->cards[0].name[2] = (sc->cards[0].CID[1] >> 16) & 0xff;
-	sc->cards[0].name[3] = (sc->cards[0].CID[1] >> 8) & 0xff;
-	sc->cards[0].name[4] = (sc->cards[0].CID[1] >> 0) & 0xff;
-	sc->cards[0].name[5] = (sc->cards[0].CID[2] >> 24) & 0xff;
+	}
+	printf("Found SD Card - CID = 0x%08x%08x%08x%08x\n",
+	    cid[0],
+	    cid[1],
+	    cid[2],
+	    cid[3]);
+	printf("SD - CSD = 0x%08x%08x%08x%08x\n", csd[0], csd[1], csd[2],
+	    csd[3]);
+	printf("SD: Vendor-ID = 0x%x\n", cid[0] >> 24);
+	printf("SD: OEM-ID = 0x%x\n", (cid[0] >> 8) & 0xffff);
+	sc->cards[0].name[0] = (cid[0] >> 0) & 0xff;
+	sc->cards[0].name[1] = (cid[1] >> 24) & 0xff;
+	sc->cards[0].name[2] = (cid[1] >> 16) & 0xff;
+	sc->cards[0].name[3] = (cid[1] >> 8) & 0xff;
+	sc->cards[0].name[4] = (cid[1] >> 0) & 0xff;
+	sc->cards[0].name[5] = (cid[2] >> 24) & 0xff;
 	sc->cards[0].name[6] = '\0';
 	printf("SD: Productname = %s\n", sc->cards[0].name);
-	printf("SD: Revision = 0x%x\n", (sc->cards[0].CID[2] >> 16) & 0xff);
-	printf("SD: Serial = 0x%x\n", (sc->cards[0].CID[2] << 16) |
-	    (sc->cards[0].CID[3] >> 16));
-	int year = 1997;
-	year += ((sc->cards[0].CID[3] >> 8) & 0xf);
+	printf("SD: Revision = 0x%x\n", (cid[2] >> 16) & 0xff);
+	printf("SD: Serial = 0x%x\n", (cid[2] << 16) |
+	    (cid[3] >> 16));
+	int year = 2001;
+	year += ((cid[3] >> 8) & 0xf);
 	int month = 0;
-	month += ((sc->cards[0].CID[3] >> 12) & 0xf);
+	month += ((cid[3] >> 12) & 0xf);
 	printf("SD: Manufacturing Date = %i/%i\n", year, month);
 	sc->cards[0].mode = 5 * MCI_MR_CLKDIV | MCI_MR_PWSDIV |
 	    (MCI_MR_PWSDIV << 1 | MCI_MR_PDCMODE);
@@ -335,24 +346,29 @@
 	    CSD_3_WBLEN_M;
 	bioq_init(&sc->cards[0].bio_queue);
 
-	sc->cards[0].sector_size = 1 + ((csd[2] >> CSD_2_v21_SECT_SIZE_S) &
-	    CSD_2_v21_SECT_SIZE_M);
+	sc->cards[0].sector_size = 1 << sc->cards[0].read_bl;
 	printf("SD: Blocksize = %i Bytes\n", sc->cards[0].sector_size);
 	uint64_t c_size;
 	uint64_t c_size_mult;
-	c_size = ((sc->cards[0].CSD[1] & 0x3ff) << 2) |
-	    ((sc->cards[0].CSD[2] >> 30) & 0x3);
+	c_size = ((sc->cards[0].CSD[1] & CSD_1_CSIZE_H_M) << 2) |
+	    ((sc->cards[0].CSD[2] >> CSD_2_CSIZE_L_S) & CSD_2_CSIZE_L_M);
 	printf("SD: c_size = %lld\n", c_size);
-	c_size_mult = (sc->cards[0].CSD[2] >> 15) & 0x7;
+	c_size_mult = (sc->cards[0].CSD[2] >> CSD_2_C_SIZE_M_S) & 
+	    CSD_2_C_SIZE_M_M;
 	c_size_mult = 1 << (c_size_mult + 2);
 	printf("SD: c_size_mult = %lld\n", c_size_mult);
 	sc->cards[0].size = sc->cards[0].sector_size *
 	    (c_size + 1) * c_size_mult;
 	printf("SD: Size = %lld Bytes\n", sc->cards[0].size);
-	if (at91_qdmmc_SDCard_SetBusWidth(dev))
+	if (at91_qdmmc_SDCard_SetBusWidth(dev)) {
+		printf("Failed to set bus width");
 		return EIO;
-	if (at91_qdmmc_SetBlocklength(dev, sc->cards[0].sector_size) != 0)
+	}
+	if (at91_qdmmc_SetBlocklength(dev, sc->cards[0].sector_size) != 0) {
+		printf("Failed to set block length!\n");
 		return EIO;
+	}
+	sc->nb_cards++;
 	return 0;
 }
 
@@ -365,7 +381,7 @@
 
 	err = 0;
 	/* get all cards into idle state */
-	at91_qdmmc_SendCommand(dev, MMC_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
+	at91_qdmmc_SendCommand(dev, MMC_GO_IDLE_STATE_CMD, 0);
 
 	/* check operating conditions */
 	do {	/* loop on busy */
@@ -385,15 +401,8 @@
 	for(sc->nb_cards = 0; sc->nb_cards < MMC_MAX; sc->nb_cards++) {
 		int status;
 		int card = sc->nb_cards;
-		status = at91_qdmmc_SendCommand(dev, MMC_ALL_SEND_CID_CMD,
-		    AT91C_NO_ARGUMENT);
-		if (status != 0) {
+		if (at91_qdmmc_GetCID(dev, sc->cards[card].CID))
 			break;
-		}
-		sc->cards[card].CID[0] = RD4(sc, MCI_RSPR + 0);
-		sc->cards[card].CID[1] = RD4(sc, MCI_RSPR + 4);
-		sc->cards[card].CID[2] = RD4(sc, MCI_RSPR + 8);
-		sc->cards[card].CID[3] = RD4(sc, MCI_RSPR + 12);
 		printf("Found MMC %i - CID = 0x%x%x%x%x\n", card,
 		    sc->cards[card].CID[0],
 		    sc->cards[card].CID[1],
@@ -554,7 +563,9 @@
 	}
 
 	if (at91_qdmmc_mmc_init(dev) != 0) {
+		printf("MMC FAILED, LET'S TRY SDCARD\n");
 		if (at91_qdmmc_sdcard_init(dev) != 0) {
+			printf("SD CARD FAILED, YOU LOSE\n");
 			err = 0;
 			goto out;
 		}
@@ -691,10 +702,14 @@
 	//printf("at91_qdmmc_strategy: called\n");
 	sc = (struct at91_qdmmc_softc *)bp->bio_disk->d_drv1;
 
+#if 0
 	AT91_QDMMC_LOCK(sc);
 	bioq_disksort(&sc->cards[0].bio_queue, bp);
 	wakeup(sc);
 	AT91_QDMMC_UNLOCK(sc);
+#else
+	biofinish(bp, NULL, EIO);
+#endif
 }
 
 static void at91_qdmmc_task(void *arg) {
@@ -707,7 +722,7 @@
 
 	tmpbuf = malloc(sc->cards[0].sector_size, M_DEVBUF, M_WAITOK);
 	AT91_QDMMC_LOCK(sc);
-	//printf("at91_qdmmc_task: start\n");
+	printf("at91_qdmmc_task: start\n");
 	for (;;) {
 		do {
 			bp = bioq_first(&sc->cards[0].bio_queue);
@@ -715,19 +730,19 @@
 				msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0);
 		} while (bp == NULL);
 		bioq_remove(&sc->cards[0].bio_queue, bp);
-		//printf("at91_qdmmc_task: request %p\n", bp);
+		printf("at91_qdmmc_task: request %p\n", bp);
 		if (bp->bio_cmd == BIO_READ) {
 			status = at91_qdmmc_SendCommand(sc->dev,
 			    SEL_DESEL_CARD_CMD, (sc->cards[0].addr) << 16);
-			//printf("at91_qdmmc_task: select_card-status = 0x%x\n", status);
+			printf("at91_qdmmc_task: select_card-status = 0x%x\n", status);
 			status = at91_qdmmc_SendCommand(sc->dev,
 			    SET_BLOCKLEN_CMD, sc->cards[0].sector_size);
-			//printf("at91_qdmmc_task: set_blocklen-status = 0x%x\n", status);
-			//printf("at91_qdmmc_task: read block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
+			printf("at91_qdmmc_task: set_blocklen-status = 0x%x\n", status);
+			printf("at91_qdmmc_task: read block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
 			uint32_t block;
 			// Init Mode Register
 			WR4(sc, MCI_MR, sc->cards[0].mode | (sc->cards[0].sector_size << 16));
-			//printf("mode 0x%x\n", RD4(sc, MCI_MR));
+			printf("mode 0x%x\n", RD4(sc, MCI_MR));
 			for (block = bp->bio_pblkno; block < bp->bio_pblkno + (bp->bio_bcount / sc->cards[0].sector_size); block++) {
 
 				WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
@@ -743,20 +758,23 @@
 				WR4(sc, PDC_RPR, addr);
 				WR4(sc, PDC_RCR, sc->cards[0].sector_size / 4);
 				WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
-				WR4(sc, MCI_IER, MCI_SR_RXBUFF);
+				WR4(sc, MCI_IER, MCI_SR_RXBUFF | MCI_SR_ENDRX);
 
-				//printf("status = 0x%x, paddr = %p, RPR = 0x%x, RCR = 0x%x\n", status, paddr,
-				//    RD4(sc, PDC_RPR), RD4(sc, PDC_RCR));
+				printf("status = 0x%x, paddr = %p, RPR = 0x%x, RCR = 0x%x\n", status, paddr,
+				    RD4(sc, PDC_RPR), RD4(sc, PDC_RCR));
 				status = at91_qdmmc_SendCommand(sc->dev, 
 				    READ_SINGLE_BLOCK_CMD, block * sc->cards[0].sector_size);
-				//printf("at91_qdmmc_task: read-status = 0x%x\n", status);
+				printf("at91_qdmmc_task: read-status = 0x%x\n", status);
 
 				// wait for completion
+				printf("TO SLEEP, PURCHANCE TO DREAM\n");
 				msleep(sc, &sc->sc_mtx, PRIBIO, "endrx", 0);
+				printf("DONE SLEEPING\n");
 				// safety check
 				while ((RD4(sc, MCI_SR) & MCI_SR_ENDRX) == 0)
 					DELAY(700);
 
+				printf("DONE WAITING\n");
 				bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD);
 				bus_dmamap_unload(sc->dmatag, sc->map);
 				map = 0;
@@ -771,9 +789,10 @@
 					    ((tmp & 0xff) << 24);
 				}
 			}
+			printf("Delecting card!\n");
 			status = at91_qdmmc_SendCommand(sc->dev,
 			    SEL_DESEL_CARD_CMD, 0);
-			//printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
+			printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
 
 			// Reset Mode Register
 			WR4(sc, MCI_MR, sc->cards[0].mode);
@@ -781,22 +800,22 @@
 			continue;
 		}
 		if (bp->bio_cmd == BIO_WRITE) {
-			//printf("at91_qdmmc_task: write block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
+			printf("at91_qdmmc_task: write block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
 			uint32_t block;
-			//uint32_t *tmpbuf;
+			uint32_t *tmpbuf;
 
 			// Init Mode Register
 			WR4(sc, MCI_MR, sc->cards[0].mode | (sc->cards[0].sector_size << 16));
-			// printf("mode 0x%x\n", RD4(sc, MCI_MR));
+			printf("mode 0x%x\n", RD4(sc, MCI_MR));
 
 			status = at91_qdmmc_SendCommand(sc->dev,
 			    SEL_DESEL_CARD_CMD, (sc->cards[0].addr) << 16);
-			// printf("at91_qdmmc_task: select_card-status = 0x%x\n", status);
+			printf("at91_qdmmc_task: select_card-status = 0x%x\n", status);
 			status = at91_qdmmc_SendCommand(sc->dev, 
 			    SET_BLOCKLEN_CMD, sc->cards[0].sector_size);
-			// printf("at91_qdmmc_task: set_blocklen-status = 0x%x\n", status);
+			printf("at91_qdmmc_task: set_blocklen-status = 0x%x\n", status);
 
-			//tmpbuf = malloc(sc->cards[0].sector_size, M_DEVBUF, M_WAITOK);
+			tmpbuf = malloc(sc->cards[0].sector_size, M_DEVBUF, M_WAITOK);
 			for (block = bp->bio_pblkno; block < bp->bio_pblkno + (bp->bio_bcount / sc->cards[0].sector_size); block++) {
 				char *paddr = bp->bio_data + (block - bp->bio_pblkno) * sc->cards[0].sector_size;
 
@@ -821,8 +840,8 @@
 				WR4(sc, PDC_TPR, addr);
 				WR4(sc, PDC_TCR, sc->cards[0].sector_size / 4);
 
-				// printf("status = 0x%x, tmpbuf = %p, TPR = 0x%x, TCR = 0x%x\n", status, tmpbuf,
-				//     RD4(sc, PDC_TPR), RD4(sc, PDC_TCR));
+				printf("status = 0x%x, tmpbuf = %p, TPR = 0x%x, TCR = 0x%x\n", status, tmpbuf,
+				    RD4(sc, PDC_TPR), RD4(sc, PDC_TCR));
 				status = at91_qdmmc_SendCommand(sc->dev, 
 				    WRITE_BLOCK_CMD, block * sc->cards[0].sector_size);
 				// printf("at91_qdmmc_task: write-status = 0x%x\n", status);
@@ -839,11 +858,11 @@
 				bus_dmamap_unload(sc->dmatag, sc->map);
 				map = 0;
 			}
-			//free(tmpbuf, M_DEVBUF);
+			free(tmpbuf, M_DEVBUF);
 
 			status = at91_qdmmc_SendCommand(sc->dev,
 			    SEL_DESEL_CARD_CMD, 0);
-			//printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
+			printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
 
 			// Reset Mode Register
 			WR4(sc, MCI_MR, sc->cards[0].mode);
@@ -855,7 +874,7 @@
 		if (map)
 			bus_dmamap_unload(sc->dmatag, sc->map);
 		status = at91_qdmmc_SendCommand(sc->dev, SEL_DESEL_CARD_CMD, 0);
-		//printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
+		printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
 		AT91_QDMMC_UNLOCK(sc);
 		biofinish(bp, NULL, ENXIO);
 	}
@@ -884,7 +903,7 @@
 	struct at91_qdmmc_softc *sc = (struct at91_qdmmc_softc*)arg;
 
 	AT91_QDMMC_LOCK(sc);
-	//printf("i 0x%x\n", RD4(sc, MCI_SR));
+	printf("i 0x%x\n", RD4(sc, MCI_SR));
 	wakeup(sc);
 	WR4(sc, MCI_IDR, 0xffffffff);
 	AT91_QDMMC_UNLOCK(sc);


More information about the p4-projects mailing list