Index: /trunk/softs/tsar_boot/include/sdcard.h
===================================================================
--- /trunk/softs/tsar_boot/include/sdcard.h	(revision 500)
+++ /trunk/softs/tsar_boot/include/sdcard.h	(revision 501)
@@ -23,9 +23,4 @@
 
     /**
-     * Capacity of the SDCARD in terms of bytes
-     */
-    unsigned int capacity;
-
-    /**
      * Block length of the SDCARD
      */
@@ -46,4 +41,7 @@
      */
     int    slave_id;
+
+    /* is the card high capacity ? */
+    int sdhc;
 };
 
@@ -105,15 +103,4 @@
  */
 void sdcard_dev_lseek(struct sdcard_dev * sdcard, unsigned int pos);
-
-/**
- * \param   sdcard  : Pointer to the initialized block device
- *
- * \return  block device capacity
- *
- * \brief   Get the block device capacity
- * 
- * The block device access pointer is relocated in terms of blocks
- */
-unsigned int sdcard_dev_get_capacity(struct sdcard_dev * sdcard);
 
 /**
Index: /trunk/softs/tsar_boot/src/sdcard.c
===================================================================
--- /trunk/softs/tsar_boot/src/sdcard.c	(revision 500)
+++ /trunk/softs/tsar_boot/src/sdcard.c	(revision 501)
@@ -8,4 +8,5 @@
 
 #include <sdcard.h>
+#include <boot_tty.h>
 
 /**
@@ -157,35 +158,77 @@
 int sdcard_dev_open(struct sdcard_dev * sdcard, struct spi_dev * spi, int ss)
 {
-    unsigned char args[4];
+	unsigned char args[4];
 	unsigned char sdcard_rsp;
-	unsigned int  iter;
+	unsigned int  iter, ersp;
 
 	sdcard->spi      = spi;
-    sdcard->slave_id = ss;
+	sdcard->slave_id = ss;
 
 	/* 
-     * Supply SD card ramp up time (min 74 cycles)
-     */
+	* Supply SD card ramp up time (min 74 cycles)
+	*/
 	_sdcard_gen_tick(sdcard, 10);
 
-    /* 
-     * Assert slave select signal
-     * Send CMD0 (Reset Command)
-     * Deassert slave select signal
-     */
+	/* 
+	* Assert slave select signal
+	* Send CMD0 (Reset Command)
+	* Deassert slave select signal
+	*/
 	_sdcard_enable(sdcard);
 
-    args[0] = 0;
-    args[1] = 0;
-    args[2] = 0;
-    args[3] = 0;
+	args[0] = 0;
+	args[1] = 0;
+	args[2] = 0;
+	args[3] = 0;
 	sdcard_rsp = _sdcard_send_command(sdcard, 0, SDCARD_CMD, args, 0x4A);
 	if ( sdcard_rsp != 0x01 )
 	{
+		boot_puts("card CMD0 failed ");
 		return sdcard_rsp;
 	}
 
 	_sdcard_disable(sdcard);
+	/*
+	 * send CMD8. If card is pre-v2, It will reply with illegal command.
+	 * Otherwise we announce sdhc support.
+	 */
 	_sdcard_enable(sdcard);
+	args[0] = 0;
+	args[1] = 0;
+	args[2] = 0x01;
+	args[3] = 0x01;
+	sdcard_rsp = _sdcard_send_command(sdcard, 8, SDCARD_CMD, args, 0x63);
+	if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) {
+		boot_puts("card CMD8 failed ");
+		return sdcard_rsp;
+	}
+	if (!SDCARD_CHECK_R1_ERROR(sdcard_rsp)) {
+		/* no error, command accepted. get whole reply */
+		ersp = _sdcard_receive_char(sdcard);
+		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
+		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
+		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
+		if ((ersp & 0xffff) != 0x0101) {
+			/* voltage mismatch */
+			boot_puts("card CMD8 mismatch: ");
+			boot_putx(ersp);
+			return sdcard_rsp;
+		}
+		boot_puts("v2 or later ");
+		sdcard->sdhc = 1;
+	} else if ((sdcard_rsp & SDCARD_R1_ILLEGAL_CMD) == 0) {
+		/* other error */
+		boot_puts("card CMD8 error ");
+		return sdcard_rsp;
+	} else {
+		sdcard->sdhc = 0;
+	}
+	_sdcard_disable(sdcard);
+	/* send CMD41, enabling the card */
+	_sdcard_enable(sdcard);
+	args[0] = sdcard->sdhc ? 0x40: 0;
+	args[1] = 0;
+	args[2] = 0;
+	args[3] = 0;
 
 	iter = 0;
@@ -202,6 +245,34 @@
 
 	_sdcard_disable(sdcard);
-
-	return sdcard_rsp;
+	if (sdcard_rsp) {
+		boot_puts("SD ACMD41 failed ");
+		return sdcard_rsp;
+	}
+	if (sdcard->sdhc != 0) {
+		/* get the card capacity to see if it's really HC */
+		_sdcard_enable(sdcard);
+		args[0] = sdcard->sdhc ? 0x40: 0;
+		args[1] = 0;
+		args[2] = 0;
+		args[3] = 0;
+		sdcard_rsp = _sdcard_send_command(sdcard, 58, SDCARD_CMD,
+		    args, 0x00);
+		if (sdcard_rsp) {
+			boot_puts("SD CMD58 failed ");
+			return sdcard_rsp;
+		}
+		ersp = _sdcard_receive_char(sdcard);
+		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
+		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
+		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
+		if (ersp & 0x40000000) {
+			boot_puts("SDHC ");
+		} else {
+			sdcard->sdhc = 0;
+		}
+		_sdcard_disable(sdcard);
+	}
+	boot_puts("card detected ");
+	return 0;
 }
 
@@ -235,5 +306,5 @@
      */
     i = count;
-    while( i++ < (sdcard->block_length + 2) ) _sdcard_receive_char(sdcard);
+    while( i++ < (512 + 2) ) _sdcard_receive_char(sdcard);
 
     _sdcard_disable(sdcard);
@@ -257,9 +328,4 @@
 }
 
-unsigned int sdcard_dev_get_capacity(struct sdcard_dev * sdcard)
-{
-	return sdcard->capacity;
-}
-
 int sdcard_dev_set_blocklen(struct sdcard_dev * sdcard, unsigned int len)
 {
@@ -268,4 +334,12 @@
     register int i;
 
+    if (len != 512)
+	return 1;
+
+    if (sdcard->sdhc) {
+	sdcard->block_length = 1;
+	return 0;
+    }
+
     for (i = 0; i < 4; i++)
         args[i] = (len >> (32 - (i+1)*8)) & 0xFF;
