Index: asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.c	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.c	(revision 359)
@@ -53,5 +53,65 @@
 #include "util/ntstdio.h"
 
-//extern ntstdio_t ntstdio;
+extern ntstdio_t ntstdio;
+
+enum ffarch_state_t {
+	FFS_IDLE,
+	FFS_RETRY_WAIT,
+};
+
+enum ffarch_state_t ffarch_state;
+volatile int ffarch_timer;
+int ffarch_retry_count;
+uint8_t sdfs_new_status, sdfs_prev_status;
+
+static void ffarch_initialize();
+
+/*
+ * FatFSタスク
+ */
+void ffarch_task(intptr_t exinf)
+{
+	ER ret, ret2;
+	SYSTIM prev, now;
+	int timer;
+
+	ffarch_initialize();
+
+	ret2 = get_tim(&now);
+	if (ret2 != E_OK){
+		ntstdio_printf(&ntstdio, "[ffarch] get_tim error: %s",
+			itron_strerror(ret2));
+		return;
+	}
+
+	for(;;){
+		prev = now;
+
+		/* タイマー取得 */
+		timer = ffarch_get_timer();
+
+		/* 待ち */
+		ret = tslp_tsk(timer);
+		if ((ret != E_OK) && (ret != E_TMOUT)) {
+			ntstdio_printf(&ntstdio, "[ffarch] tslp_tsk error: %s %d",
+				itron_strerror(ret), timer);
+			break;
+		}
+
+		ret2 = get_tim(&now);
+		if (ret2 != E_OK) {
+			ntstdio_printf(&ntstdio, "[ffarch] get_tim error: %s",
+				itron_strerror(ret2));
+			break;
+		}
+
+		/* 時間経過 */
+		int elapse = now - prev;
+		ffarch_progress(elapse);
+
+		/* タイムアウト処理 */
+		ffarch_timeout();
+	}
+}
 
 FATFS RomDisk;
@@ -71,8 +131,6 @@
 bool_t SD_begin();
 
-int ffarch_init()
-{
-	int result = -1;
-
+void ffarch_init()
+{
 	/* SD_CD */
 	gpio_init_in(&ins, P7_8);
@@ -81,29 +139,27 @@
 	sdfs_init(&sdfs, P8_5, P8_6, P8_3, P8_4, "sd");
 
-	result = SD_begin() ? 0 : -1;
-	if (result == 0) {
-		printf("SD card (1:) OK!\n");
+	ffarch_state = FFS_IDLE;
+	ffarch_timer = 0;
+	ffarch_retry_count = 3;
+	sdfs_new_status = 0;
+	sdfs_prev_status = STA_NODISK;
+
+	ffarch_timeout();
+
+	act_tsk(FFARCH_TASK);
+
+	if (romdisk_init()) {
+		ntstdio_printf(&ntstdio, "ROM disk (0:) OK!\n");
 	}
 	else {
-		printf("SD card (1:) NG!\n");
-	}
+		ntstdio_printf(&ntstdio, "ROM disk (0:) NG!\n");
+	}
+
+	serial_ctl_por(SIO_PORTID, IOCTL_FCSND | IOCTL_FCRCV);
+}
+
+void ffarch_initialize()
+{
 	sta_cyc(SDFS_CYC);
-
-	if (romdisk_init())
-		result = 0;
-
-	if (result == 0) {
-		printf("ROM disk (0:) OK!\n");
-	}
-	else {
-		printf("ROM disk (0:) NG!\n");
-	}
-
-	/* uploadディレクトリを作成しておく */
-	f_mkdir("1:/upload");
-
-	serial_ctl_por(SIO_PORTID, IOCTL_FCSND | IOCTL_FCRCV);
-
-	return result;
 }
 
@@ -173,5 +229,5 @@
 		return ramdisk_get_status();
 	case 1:
-		return sdfs_status(&sdfs);
+		return sdfs._is_initialized;
 	}
 	return STA_NOINIT;
@@ -200,4 +256,6 @@
 }
 
+DRESULT sdfs_ioctl(BYTE ctrl, void *buff);
+
 DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
 {
@@ -206,31 +264,166 @@
 		return RES_PARERR; /* ramdisk_ioctl(cmd, buff); */
 	case 1:
-		switch(cmd) {
-		case CTRL_SYNC:
-			return sdfs_sync(&sdfs);
-		case GET_SECTOR_COUNT:
-			return sdfs_sectors(&sdfs);
-		case GET_BLOCK_SIZE:
-			*((DWORD*)buff) = 1; // default when not known
-			return RES_OK;
-		}
+		return sdfs_ioctl(cmd, buff);
 	}
 	return RES_PARERR;
 }
 
+DRESULT sdfs_ioctl(BYTE ctrl, void *buff)
+{
+	DRESULT res;
+	uint32_t *dp = (uint32_t *)buff, st, ed;
+	uint8_t *ptr = (uint8_t *)buff;
+
+	if (sdfs._is_initialized & STA_NOINIT)
+		return RES_NOTRDY;
+
+	res = RES_ERROR;
+
+	switch (ctrl) {
+	case CTRL_SYNC:
+		if (sdfs_sync(&sdfs) == 0) {
+			res = RES_OK;
+		}
+		break;
+	case GET_SECTOR_SIZE:
+		*(WORD*)buff = 512;
+		res = RES_OK;
+		break;
+	case GET_SECTOR_COUNT:
+		*(DWORD*)buff = sdfs._capacity / 512;
+		res = RES_OK;
+		break;
+	case GET_BLOCK_SIZE:
+		*(DWORD*)buff = sdfs._block_len;
+		res = RES_OK;
+		break;
+	case CTRL_TRIM:
+		res = sdfs_trim(&sdfs, dp[0], dp[1]);
+		break;
+	case MMC_GET_TYPE:
+		*ptr = sdfs._card_type;
+		res = RES_OK;
+		break;
+	case MMC_GET_CSD:
+		memcpy(ptr, sdfs._csd, sizeof(sdfs._csd));
+		res = RES_OK;
+		break;
+	case MMC_GET_CID:
+		memcpy(ptr, sdfs._cid, sizeof(sdfs._cid));
+		res = RES_OK;
+		break;
+	case MMC_GET_OCR:
+		if (sdfs_get_ocr(&sdfs, buff) == 0) {
+			res = RES_OK;
+		}
+		break;
+	case MMC_GET_SDSTAT:
+		if (sdfs_get_sdstat(&sdfs, buff) == 0) {
+			res = RES_OK;
+		}
+		break;
+	default:
+		res = RES_PARERR;
+	}
+
+	return res;
+}
+
 void sdfs_cychdr(intptr_t exinf)
 {
-	BYTE s;
-
-	s = sdfs._is_initialized;
-	if (WP())		/* Write protected */
+	BYTE s = 0;
+             
+	/* Write protected */
+	if (WP())
 		s |= STA_PROTECT;
-	else		/* Write enabled */
+	else
 		s &= ~STA_PROTECT;
-	if (gpio_read(&ins))	/* Card is in socket */
+
+	/* Card is in socket */
+	if (gpio_read(&ins))
+		s |= (STA_NODISK | STA_NOINIT);
+	else
 		s &= ~STA_NODISK;
-	else		/* Socket empty */
-		s |= (STA_NODISK | STA_NOINIT);
-	sdfs._is_initialized = s;
+
+	sdfs_new_status = s;
+
+	if ((sdfs_prev_status != sdfs_new_status) && (ffarch_state == FFS_IDLE)) {
+		ffarch_timer = 0;
+		wup_tsk(FFARCH_TASK);
+	}
+}
+
+int ffarch_get_timer()
+{
+	return ffarch_timer;
+}
+
+void ffarch_progress(int elapse)
+{
+	if (ffarch_timer != TMO_FEVR) {
+		ffarch_timer -= elapse;
+		if (ffarch_timer < 0) {
+			ffarch_timer = 0;
+		}
+	}
+}
+
+void ffarch_timeout()
+{
+	if (ffarch_timer != 0)
+		return;
+
+	switch (ffarch_state) {
+	case FFS_RETRY_WAIT:
+		if (ffarch_retry_count == 0) {
+			ntstdio_printf(&ntstdio, "SD card (1:) initialize tired...\n");
+
+			ffarch_state = FFS_IDLE;
+			ffarch_timer = TMO_FEVR;
+			ffarch_retry_count = 3;
+			break;
+		}
+		ffarch_retry_count--;
+		//goto case FFS_IDLE;
+	case FFS_IDLE:
+ 		/* SDカードが入れられた場合 */
+ 		if ((sdfs._is_initialized & STA_NOINIT)
+ 			|| (((sdfs_prev_status & STA_NODISK) != 0) && ((sdfs_new_status & STA_NODISK) == 0))) {
+			ntstdio_printf(&ntstdio, "SD card initializing ...\n");
+
+			if (SD_begin()) {
+				ntstdio_printf(&ntstdio, "SD card (1:) OK!\n");
+
+				/* uploadディレクトリを作成しておく */
+				f_mkdir("1:/upload");
+
+				ffarch_state = FFS_IDLE;
+				ffarch_timer = TMO_FEVR;
+				ffarch_retry_count = 3;
+			}
+			else {
+				ntstdio_printf(&ntstdio, "SD card (1:) NG!\n");
+				ffarch_state = FFS_RETRY_WAIT;
+				ffarch_timer = 1000 * 1000;
+			}
+		}
+		/* SDカードが抜かれた場合 */
+		else if (((sdfs_prev_status & STA_NODISK) == 0) && ((sdfs_new_status & STA_NODISK) != 0)) {
+			ntstdio_printf(&ntstdio, "SD card unmount\n");
+
+			f_mount(&Sd.FatFs, "1:", 0);
+			ffarch_state = FFS_IDLE;
+			ffarch_timer = TMO_FEVR;
+			ffarch_retry_count = 3;
+		}
+		if (((sdfs_prev_status ^ sdfs_new_status) & STA_PROTECT) != 0) {
+			if ((sdfs_new_status & STA_PROTECT) != 0)
+				sdfs._is_initialized |= STA_PROTECT;
+			else
+				sdfs._is_initialized &= ~STA_PROTECT;
+		}
+		sdfs_prev_status = sdfs_new_status;
+		break;
+	}
 }
 
Index: asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.cfg
===================================================================
--- asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.cfg	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.cfg	(revision 359)
@@ -38,4 +38,5 @@
 #include "ffarch.h"
 
+CRE_TSK(FFARCH_TASK, { TA_NULL, 0, ffarch_task, FFARCH_PRIORITY, FFARCH_STACK_SIZE, NULL });
 CRE_CYC(SDFS_CYC, { TA_NULL, { TNFY_HANDLER, 0, sdfs_cychdr }, 1000000, 0 });
 
Index: asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.h	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/ffarch.h	(revision 359)
@@ -38,5 +38,13 @@
 #define _FFARCH_H_
 
-int ffarch_init();
+#define FFARCH_PRIORITY			5
+#define FFARCH_STACK_SIZE		512
+
+void ffarch_init();
+void ffarch_task(intptr_t exinf);
+int ffarch_get_timer();
+void ffarch_progress(int elapse);
+void ffarch_timeout();
+
 void sdfs_cychdr(intptr_t exinf);
 
Index: asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/sdfs.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/sdfs.c	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/sdfs.c	(revision 359)
@@ -115,9 +115,12 @@
 	*/
 #include "sdfs.h"
+#include "diskio.h"
 //#include "mbed_debug.h"
 #include "mbed_wait_api.h"
-
-#define debug(str, ...)
-#define debug_if(cond, strt, ...) if(cond){ debug(str, __ARGS__); }
+#include "util/ntstdio.h"
+
+extern ntstdio_t ntstdio;
+#define debug(...) ntstdio_printf(&ntstdio, __VA_ARGS__)
+#define debug_if(cond, ...) if(cond){ ntstdio_printf(&ntstdio, __VA_ARGS__); }
 
 static int sdfs_initialise_card_v1(sdfs_t *obj);
@@ -144,4 +147,5 @@
     obj->_init_sck = 100000;
     obj->_transfer_sck = 1000000;
+	obj->_is_initialized = STA_NOINIT;
 }
 
@@ -154,10 +158,4 @@
 #define R1_PARAMETER_ERROR      (1 << 6)
 
-// Types
-#define SDCARD_FAIL 0 //!< v1.x Standard Capacity
-#define SDCARD_V1   1 //!< v2.x Standard Capacity
-#define SDCARD_V2   2 //!< v2.x High Capacity
-#define SDCARD_V2HC 3 //!< Not recognised as an SD Card
-
 int sdfs_initialise_card(sdfs_t *obj)
 {
@@ -173,5 +171,5 @@
 	if (sdfs__cmd(obj, 0, 0) != R1_IDLE_STATE) {
 		debug("No disk, or could not put SD card in to SPI idle state\n");
-		return SDCARD_FAIL;
+		return CT_FAIL;
 	}
 
@@ -186,5 +184,5 @@
 	else {
 		debug("Not in idle state after sending CMD8 (not an SD card?)\n");
-		return SDCARD_FAIL;
+		return CT_FAIL;
 	}
 }
@@ -192,50 +190,82 @@
 static int sdfs_initialise_card_v1(sdfs_t *obj)
 {
+	sdfs__cmd(obj, 55, 0);
+	if (sdfs__cmd(obj, 41, 0) <= 1) {
+		obj->cdv = 512;
+		debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r");
+		for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+			sdfs__cmd(obj, 55, 0);
+			if (sdfs__cmd(obj, 41, 0) == 0) {
+				break;
+			}
+		}
+		return CT_SD1;
+	}
+	else {
+		for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+			if (sdfs__cmd(obj, 1, 0) == 0)
+				break;
+		}
+		return CT_MMC;
+	}
+	//if (!Timer1 || sdfs__cmd(obj, 16, 512) != 0)	/* Set block length: 512 */
+	//	ty = 0;
+
+	debug("Timeout waiting for v1.x card\n");
+	return CT_FAIL;
+}
+
+static int sdfs_initialise_card_v2(sdfs_t *obj)
+{
+	int n;
+	uint8_t ocr[4];
+
+	/* Get 32 bit return value of R7 resp */
+	for (n = 0; n < 4; n++) ocr[n] = spi_master_write(&obj->_spi, 0xFF);
 	for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
 		sdfs__cmd(obj, 55, 0);
-		if (sdfs__cmd(obj, 41, 0) == 0) {
-			obj->cdv = 512;
-			debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r");
-			return SDCARD_V1;
-		}
-	}
-
-	debug("Timeout waiting for v1.x card\n");
-	return SDCARD_FAIL;
-}
-
-static int sdfs_initialise_card_v2(sdfs_t *obj)
-{
-	for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+		if (sdfs__cmd(obj, 41, 0x40000000) == 0) {
+			if (sdfs__cmd58(obj) == 0) {
+				for (n = 0; n < 4; n++) ocr[n] = spi_master_write(&obj->_spi, 0xFF);
+				debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r");
+				obj->cdv = 1;
+				return (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
+			}
+		}
 		wait_ms(50);
-		sdfs__cmd58(obj);
-		sdfs__cmd(obj, 55, 0);
-		if (sdfs__cmd(obj, 41, 0x40000000) == 0) {
-			sdfs__cmd58(obj);
-			debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r");
-			obj->cdv = 1;
-			return SDCARD_V2;
-		}
 	}
 
 	debug("Timeout waiting for v2.x card\n");
-	return SDCARD_FAIL;
+	return CT_FAIL;
 }
 
 int sdfs_initialize(sdfs_t *obj)
 {
-	obj->_is_initialized = sdfs_initialise_card(obj);
-	if (obj->_is_initialized == 0) {
+	obj->_is_initialized |= STA_NOINIT;
+
+	obj->_card_type = sdfs_initialise_card(obj);
+	if (obj->_card_type == 0) {
 		debug("Fail to initialize card\n");
 		return 1;
 	}
-	debug_if(SD_DBG, "init card = %d\n", obj->_is_initialized);
+	debug_if(SD_DBG, "init card = %x\n", obj->_is_initialized);
+
 	obj->_sectors = sdfs__sd_sectors(obj);
+
+	if (sdfs__cmdx(obj, 10, 0) != 0		/* READ_CID */
+		|| sdfs__read(obj, obj->_cid, 16) != 0) {
+		obj->_card_type = CT_FAIL;
+		debug("Fail to read cid\n");
+		return 1;
+	}
 
 	// Set block length to 512 (CMD16)
 	if (sdfs__cmd(obj, 16, 512) != 0) {
+		obj->_card_type = CT_FAIL;
 		debug("Set 512-byte block timed out\n");
 		return 1;
 	}
+
+	obj->_is_initialized &= ~STA_NOINIT;
 
 	// Set SCK for data transfer
@@ -246,5 +276,5 @@
 int sdfs_write(sdfs_t *obj, const uint8_t *buffer, uint32_t block_number, uint32_t count)
 {
-	if (!obj->_is_initialized) {
+	if (obj->_is_initialized & (STA_NOINIT | STA_PROTECT)) {
 		return -1;
 	}
@@ -266,5 +296,5 @@
 int sdfs_read(sdfs_t *obj, uint8_t *buffer, uint32_t block_number, uint32_t count)
 {
-	if (!obj->_is_initialized) {
+	if (obj->_is_initialized & STA_NOINIT) {
 		return -1;
 	}
@@ -287,5 +317,5 @@
 {
 	// FATFileSystem::disk_status() returns 0 when initialized
-	if (obj->_is_initialized) {
+	if ((obj->_is_initialized & STA_NOINIT) == 0) {
 		return 0;
 	}
@@ -294,5 +324,5 @@
 	}
 }
-int sdfs_sync(sdfs_t *obj) { return 0; }
+
 uint64_t sdfs_sectors(sdfs_t *obj) { return obj->_sectors; }
 
@@ -477,5 +507,5 @@
 {
 	uint32_t c_size, c_size_mult, read_bl_len;
-	uint32_t block_len, mult, blocknr, capacity;
+	uint32_t mult, blocknr;
 	uint32_t hc_c_size;
 	uint64_t blocks;
@@ -487,6 +517,5 @@
 	}
 
-	uint8_t csd[16];
-	if (sdfs__read(obj, csd, 16) != 0) {
+	if (sdfs__read(obj, obj->_csd, 16) != 0) {
 		debug("Couldn't read csd response from disk\n");
 		return 0;
@@ -498,24 +527,24 @@
 	// read_bl_len   : csd[83:80] - the *maximum* read block length
 
-	int csd_structure = sdfs_ext_bits(obj, csd, 127, 126);
+	int csd_structure = sdfs_ext_bits(obj, obj->_csd, 127, 126);
 
 	switch (csd_structure) {
 	case 0:
 		obj->cdv = 512;
-		c_size = sdfs_ext_bits(obj, csd, 73, 62);
-		c_size_mult = sdfs_ext_bits(obj, csd, 49, 47);
-		read_bl_len = sdfs_ext_bits(obj, csd, 83, 80);
-
-		block_len = 1 << read_bl_len;
+		c_size = sdfs_ext_bits(obj, obj->_csd, 73, 62);
+		c_size_mult = sdfs_ext_bits(obj, obj->_csd, 49, 47);
+		read_bl_len = sdfs_ext_bits(obj, obj->_csd, 83, 80);
+
+		obj->_block_len = 1 << read_bl_len;
 		mult = 1 << (c_size_mult + 2);
 		blocknr = (c_size + 1) * mult;
-		capacity = blocknr * block_len;
-		blocks = capacity / 512;
-		debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks);
+		obj->_capacity = blocknr * obj->_block_len;
+		blocks = obj->_capacity / 512;
+		debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, obj->_capacity, blocks);
 		break;
 
 	case 1:
 		obj->cdv = 1;
-		hc_c_size = sdfs_ext_bits(obj, csd, 63, 48);
+		hc_c_size = sdfs_ext_bits(obj, obj->_csd, 63, 48);
 		blocks = (hc_c_size + 1) * 1024;
 		debug_if(SD_DBG, "\n\rSDHC Card \n\rhc_c_size: %d\n\rcapacity: %lld \n\rsectors: %lld\n\r", hc_c_size, blocks * 512, blocks);
@@ -528,2 +557,113 @@
 	return blocks;
 }
+
+static
+int wait_ready(sdfs_t *obj, uint32_t wt)
+{
+	/* Wait until card goes ready or timeout */
+	for (int i = 0; i < wt; i++) {
+		if (spi_master_write(&obj->_spi, 0xFF) == 0xFF)
+			/* Card goes ready */
+			return 1;
+	}
+
+	/* Timeout occured */
+	return 0;
+}
+
+static
+void deselect(sdfs_t *obj)
+{
+	/* Set CS# high */
+	gpio_write(&obj->_cs, 0);
+
+	/* Dummy clock (force DO hi-z for multiple slave SPI) */
+	spi_master_write(&obj->_spi, 0xFF);
+}
+
+static
+int select(sdfs_t *obj)
+{
+	/* Set CS# low */
+	gpio_write(&obj->_cs, 1);
+
+	/* Dummy clock (force DO enabled) */
+	spi_master_write(&obj->_spi, 0xFF);
+
+	/* Wait for card ready */
+	if (wait_ready(obj, 500))
+		return 0;
+
+	deselect(obj);
+
+	/* Failed to select the card due to timeout */
+	return -1;
+}
+
+int sdfs_sync(sdfs_t *obj)
+{
+	int ret = select(obj);
+	deselect(obj);
+	return ret;
+}
+
+int sdfs_trim(sdfs_t *obj, uint32_t st, uint32_t ed)
+{
+	int res = -1;
+
+	for(;;) {
+		/* Check if the card is SDC */
+		if (!(obj->_card_type & CT_SDC))
+			break;
+		/* Check if sector erase can be applied to the card */
+		if (!(obj->_csd[0] >> 6) && !(obj->_csd[10] & 0x40))
+			break;
+		/* Load sector block */
+		if (!(obj->_card_type & CT_BLOCK)) {
+			st *= 512; ed *= 512;
+		}
+		/* Erase sector block */
+		if ((sdfs__cmd(obj, 32, st) == 0)
+			&& (sdfs__cmd(obj, 33, ed) == 0)
+			&& (sdfs__cmd(obj, 38, 0) == 0)
+			&& wait_ready(obj, 30000))
+			res = 0;
+	}
+
+	return res;
+}
+
+int sdfs_get_ocr(sdfs_t *obj, uint8_t buff[4])
+{
+	int res = -1, n;
+
+	/* READ_OCR */
+	if (sdfs__cmd58(obj) == 0) {
+		for (n = 4; n; n--) {
+			*buff++ = spi_master_write(&obj->_spi, 0xFF);
+		}
+		res = 0;
+	}
+
+	deselect(obj);
+
+	return res;
+}
+
+int sdfs_get_sdstat(sdfs_t *obj, uint8_t buff[64])
+{
+	int res = -1;
+
+	sdfs__cmd(obj, 55, 0);
+
+	/* SD_STATUS */
+	if (sdfs__cmd(obj, 13, 0) == 0) {
+		spi_master_write(&obj->_spi, 0xFF);
+		if (sdfs__read(obj, buff, 64) == 0)
+			return 0;
+	}
+
+	deselect(obj);
+
+	return res;
+}
Index: asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/sdfs.h
===================================================================
--- asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/sdfs.h	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/ntshell/fatfs/sdfs.h	(revision 359)
@@ -34,4 +34,12 @@
 #endif
 
+/* MMC card type flags (MMC_GET_TYPE) */
+#define CT_FAIL		0x00
+#define CT_MMC		0x01		/* MMC ver 3 */
+#define CT_SD1		0x02		/* SD ver 1 */
+#define CT_SD2		0x04		/* SD ver 2 */
+#define CT_SDC		(CT_SD1|CT_SD2)	/* SD */
+#define CT_BLOCK	0x08		/* Block addressing */
+
 /** Access the filesystem on an SD Card using SPI
 	*
@@ -51,4 +59,9 @@
 typedef struct sdfs_s{
 	const char* name;
+	volatile uint8_t _is_initialized;
+	uint8_t _card_type;
+	uint8_t _csd[16], _cid[16];
+	uint64_t _capacity;
+	uint64_t _block_len;
 	uint64_t _sectors;
 	spi_t _spi;
@@ -57,5 +70,4 @@
     uint32_t _init_sck;
     uint32_t _transfer_sck;
-	int _is_initialized;
 } sdfs_t;
 
@@ -76,4 +88,7 @@
 int sdfs_sync(sdfs_t *obj);
 uint64_t sdfs_sectors(sdfs_t *obj);
+int sdfs_trim(sdfs_t *obj, uint32_t st, uint32_t ed);
+int sdfs_get_ocr(sdfs_t *obj, uint8_t buff[4]);
+int sdfs_get_sdstat(sdfs_t *obj, uint8_t buff[64]);
 
 #ifdef __cplusplus
