diff --git a/apps/debug_menu.c b/apps/debug_menu.c index ab2f2821b2..0e4eab1a44 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -1889,8 +1889,11 @@ static int disk_callback(int btn, struct gui_synclist *lists) static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 }; static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" }; static const unsigned char *nsec_units[] = { "ns", "µs", "ms" }; - static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2", +#if (CONFIG_STORAGE & STORAGE_MMC) + static const char *mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2", "3.1-3.31", "4.0" }; +#endif + if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW)) { #ifdef HAVE_HOTSWAP @@ -1914,19 +1917,43 @@ static int disk_callback(int btn, struct gui_synclist *lists) (int) card_extract_bits(card->cid, 51, 4)); simplelist_addline(SIMPLELIST_ADD_LINE, "Prod: %d/%d", +#if (CONFIG_STORAGE & STORAGE_SD) + (int) card_extract_bits(card->cid, 11, 3), + (int) card_extract_bits(card->cid, 19, 8) + 2000 +#elif (CONFIG_STORAGE & STORAGE_MMC) (int) card_extract_bits(card->cid, 15, 4), - (int) card_extract_bits(card->cid, 11, 4) + 1997); + (int) card_extract_bits(card->cid, 11, 4) + 1997 +#endif + ); simplelist_addline(SIMPLELIST_ADD_LINE, +#if (CONFIG_STORAGE & STORAGE_SD) "Ser#: 0x%08lx", - card_extract_bits(card->cid, 47, 32)); - simplelist_addline(SIMPLELIST_ADD_LINE, - "M=%02x, O=%04x", + card_extract_bits(card->cid, 55, 32) +#elif (CONFIG_STORAGE & STORAGE_MMC) + "Ser#: 0x%04lx", + card_extract_bits(card->cid, 47, 16) +#endif + ); + + simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, " +#if (CONFIG_STORAGE & STORAGE_SD) + "O=%c%c", (int) card_extract_bits(card->cid, 127, 8), - (int) card_extract_bits(card->cid, 119, 16)); + card_extract_bits(card->cid, 119, 8), + card_extract_bits(card->cid, 111, 8) +#elif (CONFIG_STORAGE & STORAGE_MMC) + "O=%04x", + (int) card_extract_bits(card->cid, 127, 8), + (int) card_extract_bits(card->cid, 119, 16) +#endif + ); + +#if (CONFIG_STORAGE & STORAGE_MMC) int temp = card_extract_bits(card->csd, 125, 4); simplelist_addline(SIMPLELIST_ADD_LINE, - CARDTYPE " v%s", temp < 5 ? - spec_vers[temp] : "?.?"); + "MMC v%s", temp < 5 ? + mmc_spec_vers[temp] : "?.?"); +#endif simplelist_addline(SIMPLELIST_ADD_LINE, "Blocks: 0x%08lx", card->numblocks); output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000, diff --git a/firmware/SOURCES b/firmware/SOURCES index 36f5070413..609521a4de 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -134,6 +134,8 @@ target/arm/ata-nand-telechips.c target/arm/s5l8700/ata-nand-s5l8700.c #elif (CONFIG_STORAGE & STORAGE_ATA) drivers/ata.c +#elif (CONFIG_STORAGE & STORAGE_SD) +drivers/sd.c #elif (CONFIG_STORAGE & STORAGE_RAMDISK) drivers/ramdisk.c #endif /* CONFIG_STORAGE */ diff --git a/firmware/drivers/sd.c b/firmware/drivers/sd.c new file mode 100644 index 0000000000..834d8a19fd --- /dev/null +++ b/firmware/drivers/sd.c @@ -0,0 +1,64 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 by Rafaël Carré + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "hotswap.h" + +static const unsigned char sd_mantissa[] = { /* *10 */ + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; +static const unsigned int sd_exponent[] = { /* use varies */ + 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; + +void sd_parse_csd(tCardInfo *card) +{ + unsigned int c_size, c_mult; + const int csd_version = card_extract_bits(card->csd, 127, 2); + if(csd_version == 0) + { + /* CSD version 1.0 */ + int max_read_bl_len; + + c_size = card_extract_bits(card->csd, 73, 12) + 1; + c_mult = 4 << card_extract_bits(card->csd, 49, 3); + max_read_bl_len = 1 << card_extract_bits(card->csd, 83, 4); + card->numblocks = c_size * c_mult * (max_read_bl_len/512); + } +#ifdef HAVE_MULTIVOLUME + else if(csd_version == 1) + { + /* CSD version 2.0 */ + c_size = card_extract_bits(card->csd, 69, 22) + 1; + card->numblocks = c_size << 10; + } +#endif + + card->blocksize = 512; /* Always use 512 byte blocks */ + + card->speed = sd_mantissa[card_extract_bits(card->csd, 102, 4)] * + sd_exponent[card_extract_bits(card->csd, 98, 3) + 4]; + + card->nsac = 100 * card_extract_bits(card->csd, 111, 8); + + card->taac = sd_mantissa[card_extract_bits(card->csd, 118, 4)] * + sd_exponent[card_extract_bits(card->csd, 114, 3)]; + + card->r2w_factor = card_extract_bits(card->csd, 28, 3); +} diff --git a/firmware/export/hotswap.h b/firmware/export/hotswap.h index a9bb745f38..455dee6bcc 100644 --- a/firmware/export/hotswap.h +++ b/firmware/export/hotswap.h @@ -56,6 +56,7 @@ typedef struct #define card_detect card_detect_target #define card_get_info card_get_info_target tCardInfo *card_get_info_target(int card_no); +void sd_parse_csd(tCardInfo *card); #ifdef HAVE_HOTSWAP #define card_enable_monitoring card_enable_monitoring_target diff --git a/firmware/export/sd.h b/firmware/export/sd.h index 9d47290d85..6c848c34cf 100644 --- a/firmware/export/sd.h +++ b/firmware/export/sd.h @@ -25,6 +25,8 @@ #include #include "mv.h" /* for HAVE_MULTIVOLUME or not */ +#define SD_BLOCK_SIZE 512 /* XXX : support other sizes ? */ + struct storage_info; void sd_enable(bool on); @@ -51,11 +53,6 @@ bool card_detect_target(void); long sd_last_disk_activity(void); -static const unsigned char sd_mantissa[] = { /* *10 */ - 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; -static const unsigned int sd_exponent[] = { /* use varies */ - 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; - /* SD States */ #define SD_IDLE 0 #define SD_READY 1 diff --git a/firmware/hotswap.c b/firmware/hotswap.c index ec298f7243..79595e4591 100644 --- a/firmware/hotswap.c +++ b/firmware/hotswap.c @@ -36,7 +36,7 @@ unsigned long card_extract_bits( unsigned int long_index, bit_index; unsigned long result; - /* we assume words of CSD/CID are stored least significant word first */ + /* we assume words of CSD/CID are stored most significant word first */ start = 127 - start; long_index = start / 32; diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index c0fad722b6..74bdb90ed0 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c @@ -94,9 +94,7 @@ static const int pl180_base[NUM_VOLUMES] = { static int sd_select_bank(signed char bank); static int sd_init_card(const int drive); static void init_pl180_controller(const int drive); -/* TODO : BLOCK_SIZE != SECTOR_SIZE ? */ -#define BLOCK_SIZE 512 -#define SECTOR_SIZE 512 +#define SECTOR_SIZE 512 /* XXX: different sector sizes ? */ #define BLOCKS_PER_BANK 0x7a7800 static tCardInfo card_info[NUM_VOLUMES]; @@ -241,12 +239,11 @@ static bool send_cmd(const int drive, const int cmd, const int arg, static int sd_init_card(const int drive) { - unsigned int c_size; - unsigned long c_mult; unsigned long response; int max_tries = 100; /* max acmd41 attemps */ bool sdhc; - unsigned char temp; + unsigned long temp_reg[4]; + int i; if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL)) return -1; @@ -284,17 +281,11 @@ static int sd_init_card(const int drive) /* send CID */ if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, - card_info[drive].cid)) + temp_reg)) return -5; - /* ascii chars here */ - card_info[drive].cid[0] = htobe32(card_info[drive].cid[0]); - card_info[drive].cid[1] = htobe32(card_info[drive].cid[1]); - - /* adjust year<=>month, 1997 <=> 2000 */ - temp = *((char*)card_info[drive].cid+13); - *((char*)card_info[drive].cid+13) = - (unsigned char)((temp >> 4) | (temp << 4)) + 3; + for(i=0; i<4; i++) + card_info[drive].cid[3-i] = temp_reg[i]; /* send RCA */ if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, @@ -303,29 +294,13 @@ static int sd_init_card(const int drive) /* send CSD */ if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, - MCI_RESP|MCI_LONG_RESP|MCI_ARG, card_info[drive].csd)) + MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) return -7; - /* These calculations come from the Sandisk SD card product manual */ - if( (card_info[drive].csd[3]>>30) == 0) - { - int max_read_bl_len; - /* CSD version 1.0 */ - c_size = ((card_info[drive].csd[2] & 0x3ff) << 2) + (card_info[drive].csd[1]>>30) + 1; - c_mult = 4 << ((card_info[drive].csd[1] >> 15) & 7); - max_read_bl_len = 1 << ((card_info[drive].csd[2] >> 16) & 15); - card_info[drive].blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ - card_info[drive].numblocks = c_size * c_mult * (max_read_bl_len/512); - } -#ifdef HAVE_MULTIVOLUME - else if( (card_info[drive].csd[3]>>30) == 1) - { - /* CSD version 2.0 */ - c_size = ((card_info[drive].csd[2] & 0x3f) << 16) + (card_info[drive].csd[1]>>16) + 1; - card_info[drive].blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ - card_info[drive].numblocks = c_size << 10; - } -#endif + for(i=0; i<4; i++) + card_info[drive].csd[3-i] = temp_reg[i]; + + sd_parse_csd(&card_info[drive]); if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) return -9; @@ -723,7 +698,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, /* Set bank_start to the correct unit (blocks or bytes) */ if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ - bank_start *= BLOCK_SIZE; + bank_start *= SD_BLOCK_SIZE; if(!send_cmd(drive, cmd, bank_start, MCI_ARG, NULL)) { @@ -877,22 +852,7 @@ void sd_enable(bool on) tCardInfo *card_get_info_target(int card_no) { - unsigned char temp; - tCardInfo *card = &card_info[card_no]; - - temp = card->csd[3]; - card->speed = sd_mantissa[temp & 7] * sd_exponent[(temp >> 3) & 0xf]; - - temp = card->csd[3] >> 8; - card->nsac = 100 * temp; - - temp = (card->csd[3] >> 16) & 0x7f; /* bit 7 reserved */ - card->taac = sd_mantissa[temp >> 3] * sd_exponent[temp & 7]; - - temp = (card->csd[0] >> 26) & 7; - card->r2w_factor = temp; - - return card; + return &card_info[card_no]; } bool card_detect_target(void) diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c index 8f30195791..df13a119f8 100644 --- a/firmware/target/arm/ata-sd-pp.c +++ b/firmware/target/arm/ata-sd-pp.c @@ -36,7 +36,6 @@ #include "sd.h" #include "storage.h" -#define BLOCK_SIZE 512 #define SECTOR_SIZE 512 #define BLOCKS_PER_BANK 0x7a7800 @@ -552,7 +551,7 @@ static int sd_select_bank(unsigned char bank) /* Write the card data */ write_buf = card_data; - for (i = 0; i < BLOCK_SIZE/2; i += FIFO_LEN) + for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN) { /* Wait for the FIFO to empty */ if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 10000)) @@ -652,10 +651,9 @@ static void sd_init_device(int card_no) unsigned long response = 0; #endif unsigned int i; - unsigned int c_size; - unsigned long c_mult; unsigned char carddata[512]; unsigned char *dataptr; + unsigned long temp_reg[4]; int ret; /* Enable and initialise controller */ @@ -733,38 +731,25 @@ static void sd_init_device(int card_no) } } - ret = sd_command(SD_ALL_SEND_CID, 0, currcard->cid, CMDAT_RES_TYPE2); + ret = sd_command(SD_ALL_SEND_CID, 0, temp_reg, CMDAT_RES_TYPE2); if (ret < 0) goto card_init_error; + for(i=0; i<4; i++) + currcard->cid[i] = temp_reg[3-i]; + ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, CMDAT_RES_TYPE1); if (ret < 0) goto card_init_error; - ret = sd_command(SD_SEND_CSD, currcard->rca, currcard->csd, CMDAT_RES_TYPE2); + ret = sd_command(SD_SEND_CSD, currcard->rca, temp_reg, CMDAT_RES_TYPE2); if (ret < 0) goto card_init_error; - /* These calculations come from the Sandisk SD card product manual */ - if( (currcard->csd[3]>>30) == 0) - { - int max_read_bl_len; - /* CSD version 1.0 */ - c_size = ((currcard->csd[2] & 0x3ff) << 2) + (currcard->csd[1]>>30) + 1; - c_mult = 4 << ((currcard->csd[1] >> 15) & 7); - max_read_bl_len = 1 << ((currcard->csd[2] >> 16) & 15); - currcard->blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ - currcard->numblocks = c_size * c_mult * (max_read_bl_len/512); - } -#ifdef HAVE_HOTSWAP - else if( (currcard->csd[3]>>30) == 1) - { - /* CSD version 2.0 */ - c_size = ((currcard->csd[2] & 0x3f) << 16) + (currcard->csd[1]>>16) + 1; - currcard->blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ - currcard->numblocks = c_size << 10; - } -#endif /* HAVE_HOTSWAP */ + for(i=0; i<4; i++) + currcard->csd[i] = temp_reg[3-i]; + + sd_parse_csd(currcard); MMC_CLKRT = 0; /* switch to highest clock rate */ @@ -805,7 +790,7 @@ static void sd_init_device(int card_no) The first 512 bits contain the status information TODO: Do something useful with this! */ dataptr = carddata; - for (i = 0; i < BLOCK_SIZE/2; i += FIFO_LEN) + for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN) { /* Wait for the FIFO to be full */ if (sd_poll_status(STAT_RECV_FIFO_FULL, 100000)) @@ -924,13 +909,13 @@ sd_read_retry: else #endif { - ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, + ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * SD_BLOCK_SIZE, NULL, 0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1); } if (ret < 0) goto sd_read_error; - /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ + /* TODO: Don't assume SD_BLOCK_SIZE == SECTOR_SIZE */ buf_end = (unsigned char *)inbuf + incount * currcard->blocksize; for (buf = inbuf; buf < buf_end;) @@ -1042,7 +1027,7 @@ sd_write_retry: else #endif { - ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, + ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*SD_BLOCK_SIZE, NULL, CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1); } if (ret < 0) @@ -1290,35 +1275,9 @@ int sd_init(void) return ret; } -/* move the sd-card info to mmc struct */ tCardInfo *card_get_info_target(int card_no) { - int i, temp; - static tCardInfo card; - static const char mantissa[] = { /* *10 */ - 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; - static const int exponent[] = { /* use varies */ - 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; - - card.initialized = card_info[card_no].initialized; - card.ocr = card_info[card_no].ocr; - for(i=0; i<4; i++) card.csd[i] = card_info[card_no].csd[3-i]; - for(i=0; i<4; i++) card.cid[i] = card_info[card_no].cid[3-i]; - card.numblocks = card_info[card_no].numblocks; - card.blocksize = card_info[card_no].blocksize; - temp = card_extract_bits(card.csd, 98, 3); - card.speed = mantissa[card_extract_bits(card.csd, 102, 4)] - * exponent[temp > 2 ? 7 : temp + 4]; - card.nsac = 100 * card_extract_bits(card.csd, 111, 8); - temp = card_extract_bits(card.csd, 114, 3); - card.taac = mantissa[card_extract_bits(card.csd, 118, 4)] - * exponent[temp] / 10; - card.cid[0] = htobe32(card.cid[0]); /* ascii chars here */ - card.cid[1] = htobe32(card.cid[1]); /* ascii chars here */ - temp = *((char*)card.cid+13); /* adjust year<=>month, 1997 <=> 2000 */ - *((char*)card.cid+13) = (unsigned char)((temp >> 4) | (temp << 4)) + 3; - - return &card; + return &card_info[card_no]; } bool card_detect_target(void) diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c index 6e7f62a2e5..d14715c192 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c @@ -41,8 +41,6 @@ static long last_disk_activity = -1; #define DEBUG(x...) logf(x) -#define BLOCK_SIZE 512 - #define MMC_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) #define MMC_RESET() __msc_reset() @@ -1668,7 +1666,12 @@ tCardInfo* card_get_info_target(int card_no) (void)card_no; int i, temp; static tCardInfo card; - + + static const unsigned char sd_mantissa[] = { /* *10 */ + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; + static const unsigned int sd_exponent[] = { /* use varies */ + 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; + card.initialized = true; card.ocr = mmcinfo.ocr; for(i=0; i<4; i++) @@ -1707,22 +1710,22 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) return retval; - mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, BLOCK_SIZE, RESPONSE_R1); + mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1); if ((retval = mmc_unpack_r1(&request, &r1))) return retval; if (sd2_0) { mmc_send_cmd(&request, MMC_READ_MULTIPLE_BLOCK, start, - count, BLOCK_SIZE, RESPONSE_R1, buf); + count, SD_BLOCK_SIZE, RESPONSE_R1, buf); if ((retval = mmc_unpack_r1(&request, &r1))) return retval; } else { mmc_send_cmd(&request, MMC_READ_MULTIPLE_BLOCK, - start * BLOCK_SIZE, count, - BLOCK_SIZE, RESPONSE_R1, buf); + start * SD_BLOCK_SIZE, count, + SD_BLOCK_SIZE, RESPONSE_R1, buf); if ((retval = mmc_unpack_r1(&request, &r1))) return retval; } @@ -1757,14 +1760,14 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) return retval; - mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, BLOCK_SIZE, RESPONSE_R1); + mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1); if ((retval = mmc_unpack_r1(&request, &r1))) return retval; if (sd2_0) { mmc_send_cmd(&request, MMC_WRITE_MULTIPLE_BLOCK, start, - count, BLOCK_SIZE, RESPONSE_R1, + count, SD_BLOCK_SIZE, RESPONSE_R1, (void*)buf); if ((retval = mmc_unpack_r1(&request, &r1))) return retval; @@ -1772,8 +1775,8 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo else { mmc_send_cmd(&request, MMC_WRITE_MULTIPLE_BLOCK, - start * BLOCK_SIZE, count, - BLOCK_SIZE, RESPONSE_R1, (void*)buf); + start * SD_BLOCK_SIZE, count, + SD_BLOCK_SIZE, RESPONSE_R1, (void*)buf); if ((retval = mmc_unpack_r1(&request, &r1))) return retval; }