*************** *** 65,245 **** #define FIFO_SIZE 16 /* FIFO is 16 words deep */ /* SD Commands */ - #define GO_IDLE_STATE 0 - #define ALL_SEND_CID 2 - #define SEND_RELATIVE_ADDR 3 - #define SET_DSR 4 - #define SWITCH_FUNC 6 - #define SELECT_CARD 7 - #define DESELECT_CARD 7 - #define SEND_CSD 9 - #define SEND_CID 10 - #define STOP_TRANSMISSION 12 - #define SEND_STATUS 13 - #define GO_INACTIVE_STATE 15 - #define SET_BLOCKLEN 16 - #define READ_SINGLE_BLOCK 17 - #define READ_MULTIPLE_BLOCK 18 - #define WRITE_BLOCK 24 - #define WRITE_MULTIPLE_BLOCK 25 - #define ERASE_WR_BLK_START 32 - #define ERASE_WR_BLK_END 33 - #define ERASE 38 /* Application Specific commands */ #define SET_BUS_WIDTH 6 #define SD_APP_OP_COND 41 - #define READ_TIMEOUT 5*HZ - #define WRITE_TIMEOUT 0.5*HZ - - static unsigned short identify_info[SECTOR_SIZE]; - int ata_spinup_time = 0; long last_disk_activity = -1; - static bool initialized = false; - - static unsigned char current_bank = 0; /* The bank that we are working with */ static tSDCardInfo card_info[2]; - - /* For multi volume support */ - static int current_card = 0; static struct mutex sd_mtx; - static long sd_stack [(DEFAULT_STACK_SIZE*2)/sizeof(long)]; static const char sd_thread_name[] = "sd"; - static struct event_queue sd_queue; /* Private Functions */ - bool sd_send_command(unsigned int cmd, unsigned long arg1, unsigned int arg2) { - bool result = false; - do { - CMD_REG0 = cmd; - CMD_REG1 = (unsigned int)((arg1 & 0xffff0000) >> 16); - CMD_REG2 = (unsigned int)((arg1 & 0xffff)); - UNKNOWN = arg2; - while ((STATUS_REG & CMD_DONE) == 0) { - /* Busy wait */ } - if ((STATUS_REG & ERROR_BITS) == 0) - { - result = true; - } - } while ((STATUS_REG & ERROR_BITS) != 0); - return result; } - void sd_read_response(unsigned int *response, int type) { - int i; - int words; /* Number of 16 bit words to read from RESPONSE_REG */ - unsigned int response_from_card[9]; - if(type == 2) - { - words = 9; /* R2 types are 8.5 16-bit words long */ - } else { - words = 3; - } for (i = 0; i < words; i++) /* RESPONSE_REG is read MSB first */ { - response_from_card[i] = RESPONSE_REG; /* Read most significant 16-bit word */ } - switch (type) { - case 1: - /* Response type 1 has the following structure: - Start bit - Transmission bit - Command index (6 bits) - Card Status (32 bits) - CRC7 (7 bits) - Stop bit - */ - /* TODO: Sanity checks */ - response[0] = ((response_from_card[0] & 0xff) << 24) - + (response_from_card[1] << 8) - + ((response_from_card[2] & 0xff00) >> 8); - break; - case 2: - /* Response type 2 has the following structure: - Start bit - Transmission bit - Reserved (6 bits) - CSD/CID register (127 bits) - Stop bit - */ - response[3] = ((response_from_card[0]&0xff)<<24) + - (response_from_card[1]<<8) + - ((response_from_card[2]&0xff00)>>8); - response[2] = ((response_from_card[2]&0xff)<<24) + - (response_from_card[3]<<8) + - ((response_from_card[4]&0xff00)>>8); - response[1] = ((response_from_card[4]&0xff)<<24) + - (response_from_card[5]<<8) + - ((response_from_card[6]&0xff00)>>8); - response[0] = ((response_from_card[6]&0xff)<<24) + - (response_from_card[7]<<8) + - ((response_from_card[8]&0xff00)>>8); - break; - case 3: - /* Response type 3 has the following structure: - Start bit - Transmission bit - Reserved (6 bits) - OCR register (32 bits) - Reserved (7 bits) - Stop bit - */ - response[0] = ((response_from_card[0] & 0xff) << 24) - + (response_from_card[1] << 8) - + ((response_from_card[2] & 0xff00) >> 8); - /* Types 4-6 not supported yet */ - } - } - - bool sd_send_acommand(unsigned int cmd, unsigned long arg1, unsigned int arg2) - { - unsigned int returncode; - if (sd_send_command(55, (card_info[current_card].rca)<<16, 1) == false) - return false; - sd_read_response(&returncode, 1); - if (sd_send_command(cmd, arg1, arg2) == false) - return false; return true; } - void sd_wait_for_state(tSDCardInfo* card, unsigned int state) { unsigned int response = 0; while(((response >> 9) & 0xf) != state) { - sd_send_command(SEND_STATUS, (card->rca) << 16, 1); - sd_read_response(&response, 1); - /* TODO: Add a timeout and error handling */ } SD_STATE_REG = state; } - STATICIRAM void copy_read_sectors(unsigned char* buf, int wordcount) - NOINLINE_ATTR ICODE_ATTR; - - STATICIRAM void copy_read_sectors(unsigned char* buf, int wordcount) { - unsigned int tmp = 0; - - if ( (unsigned long)buf & 1) { /* not 16-bit aligned, copy byte by byte */ - unsigned char* bufend = buf + wordcount*2; do { tmp = DATA_REG; --- 67,237 ---- #define FIFO_SIZE 16 /* FIFO is 16 words deep */ /* SD Commands */ + #define GO_IDLE_STATE 0 + #define ALL_SEND_CID 2 + #define SEND_RELATIVE_ADDR 3 + #define SET_DSR 4 + #define SWITCH_FUNC 6 + #define SELECT_CARD 7 + #define DESELECT_CARD 7 + #define SEND_CSD 9 + #define SEND_CID 10 + #define STOP_TRANSMISSION 12 + #define SEND_STATUS 13 + #define GO_INACTIVE_STATE 15 + #define SET_BLOCKLEN 16 + #define READ_SINGLE_BLOCK 17 + #define READ_MULTIPLE_BLOCK 18 + #define SEND_NUM_WR_BLOCKS 22 + #define WRITE_BLOCK 24 + #define WRITE_MULTIPLE_BLOCK 25 + #define ERASE_WR_BLK_START 32 + #define ERASE_WR_BLK_END 33 + #define ERASE 38 + + #define EC_POWER_UP 1 /* error code */ + #define EC_READ_TIMEOUT 2 /* error code */ + #define EC_WRITE_TIMEOUT 3 /* error code */ + #define EC_TRAN_SEL_BANK 4 /* error code */ + #define EC_TRAN_READ_ENTRY 5 /* error code */ + #define EC_TRAN_READ_EXIT 6 /* error code */ + #define EC_TRAN_WRITE_ENTRY 7 /* error code */ + #define EC_TRAN_WRITE_EXIT 8 /* error code */ + #define DO_PANIC 32 /* marker */ + #define NO_PANIC 0 /* marker */ + #define EC_COMMAND 10 /* error code */ + #define EC_FIFO_SEL_BANK_EMPTY 11 /* error code */ + #define EC_FIFO_SEL_BANK_DONE 12 /* error code */ + #define EC_FIFO_ENA_BANK_EMPTY 13 /* error code */ + #define EC_FIFO_READ_FULL 14 /* error code */ + #define EC_FIFO_WR_EMPTY 15 /* error code */ + #define EC_FIFO_WR_DONE 16 /* error code */ /* Application Specific commands */ #define SET_BUS_WIDTH 6 #define SD_APP_OP_COND 41 long last_disk_activity = -1; + static bool sd_thread_initialized = false; static tSDCardInfo card_info[2]; + static tSDCardInfo *currcard; /* current active card */ static struct mutex sd_mtx; + static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x800)/sizeof(long)]; static const char sd_thread_name[] = "sd"; + static struct event_queue sd_queue; + static int sd_countdown; /* for sd switch debouncing */ + static bool sd_monitor_enabled = true; + static int last_sd_status = 0; + static enum {SD_UNKNOWN, SD_UNTOUCHED, SD_TOUCHED} sd_status = SD_UNKNOWN; + static void sd_tick(void); /* Private Functions */ + static unsigned int check_time[10]; + + static inline void sd_check_timeout(unsigned int timeout, int id) { + if(USEC_TIMER > check_time[id] + timeout) + panicf("Error SDCard: %d", id); + } + + static inline bool sd_poll_status(unsigned int trigger, unsigned int timeout, + int id) + { + unsigned int t = USEC_TIMER; + + while ((STATUS_REG & trigger) == 0) { + if(USEC_TIMER > t + timeout) { + if(id & DO_PANIC) + panicf("Error SDCard: %d", id & 31); + + return false; } + } + + return true; } + + bool sd_command(unsigned int cmd, unsigned long arg1, unsigned int *response, + unsigned int type) { + int i, words; /* Number of 16 bit words to read from RESPONSE_REG */ + unsigned int data[9]; + + do + { CMD_REG0 = cmd; + CMD_REG1 = (unsigned int)((arg1 & 0xffff0000) >> 16); + CMD_REG2 = (unsigned int)((arg1 & 0xffff)); + UNKNOWN = type; + + sd_poll_status(CMD_DONE, 100000, EC_COMMAND | DO_PANIC); + + } while (STATUS_REG & ERROR_BITS); + + if(cmd == GO_IDLE_STATE) return true; /* no response here */ + + words = (type == 2) ? 9 : 3; for (i = 0; i < words; i++) /* RESPONSE_REG is read MSB first */ { + data[i] = RESPONSE_REG; /* Read most significant 16-bit word */ } + if(type == 2) { + /* Response type 2 has the following structure: + Start bit + Transmission bit + Reserved (6 bits) + CSD/CID register (127 bits) + Stop bit */ + response[3] = (data[0]<<24) + (data[1]<<8) + ((data[2]&0xff00)>>8); + response[2] = (data[2]<<24) + (data[3]<<8) + ((data[4]&0xff00)>>8); + response[1] = (data[4]<<24) + (data[5]<<8) + ((data[6]&0xff00)>>8); + response[0] = (data[6]<<24) + (data[7]<<8) + ((data[8]&0xff00)>>8); + } + else + { + /* Response types 1,3 have the following structure: + Start bit Transmission bit + Command index (6 bits) + Card data (32 bits) + CRC7 (7 bits) + Stop bit */ + response[0] = (data[0]<<24) + (data[1]<<8) + ((data[2]&0xff00)>>8); + } + return true; } + void sd_wait_for_state(unsigned int state, unsigned int id) { unsigned int response = 0; + + check_time[id] = USEC_TIMER; while(((response >> 9) & 0xf) != state) { + sd_command(SEND_STATUS, currcard->rca, &response, 1); + sd_check_timeout(0x80000, id); } SD_STATE_REG = state; } + static inline void copy_read_sectors(unsigned char* buf) { + if ( (int)buf & 1) { /* not 16-bit aligned, copy byte by byte */ + unsigned int tmp = 0; + unsigned char* bufend = buf + FIFO_SIZE*2; do { tmp = DATA_REG; *************** *** 436,449 **** for (i = 0; i < BLOCK_SIZE / 2; i += FIFO_SIZE) { /* Wait for the FIFO to be full */ - while((STATUS_REG & FIFO_FULL) == 0) {} - copy_read_sectors(dataptr, FIFO_SIZE); dataptr += (FIFO_SIZE*2); /* Advance one chunk of 16 words */ } } - mutex_init(&sd_mtx); } /* API Functions */ --- 417,430 ---- for (i = 0; i < BLOCK_SIZE / 2; i += FIFO_SIZE) { /* Wait for the FIFO to be full */ + sd_poll_status(FIFO_FULL, 100000, EC_FIFO_ENA_BANK_EMPTY | DO_PANIC); + copy_read_sectors(dataptr); /* Copy one chunk of 16 words */ dataptr += (FIFO_SIZE*2); /* Advance one chunk of 16 words */ } } + currcard->initialized = true; } /* API Functions */ *************** *** 453,533 **** (void)onoff; } - int ata_read_sectors(IF_MV2(int drive,) - unsigned long start, - int incount, void* inbuf) { - int ret = 0; - long timeout; - int count; - void* buf; - long spinup_start; unsigned int dummy; - unsigned int response; - unsigned int i; - tSDCardInfo *card = &card_info[current_card]; - /* TODO: Add DMA support. */ - #ifdef HAVE_MULTIVOLUME - (void)drive; /* unused for now */ - #endif mutex_lock(&sd_mtx); - last_disk_activity = current_tick; - spinup_start = current_tick; - ata_enable(true); ata_led(true); - timeout = current_tick + READ_TIMEOUT; - - /* TODO: Select device */ - if(current_card == 0) { - if(start >= BLOCKS_PER_BANK) - { - sd_select_bank(1); - start -= BLOCKS_PER_BANK; - } else { - sd_select_bank(0); - } } - buf = inbuf; - count = incount; - while (TIME_BEFORE(current_tick, timeout)) { - ret = 0; - last_disk_activity = current_tick; - SD_STATE_REG = TRAN; - BLOCK_COUNT_REG = count; - sd_send_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, 0x1c25); - sd_read_response(&dummy, 1); - /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ - for (i = 0; i < count * card->block_size / 2; i += FIFO_SIZE) - { - /* Wait for the FIFO to be full */ - while((STATUS_REG & FIFO_FULL) == 0) {} - copy_read_sectors(buf, FIFO_SIZE); - buf += FIFO_SIZE*2; /* Advance one chunk of 16 words */ - /* TODO: Switch bank if necessary */ - last_disk_activity = current_tick; - } - udelay(75); - sd_send_command(STOP_TRANSMISSION, 0, 1); - sd_read_response(&dummy, 1); - - response = 0; - sd_wait_for_state(card, TRAN); - break; } ata_led(false); ata_enable(false); --- 434,495 ---- (void)onoff; } + int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, void* inbuf) { + int ret = 0; + void *buf, *buf_end; unsigned int dummy; + /* TODO: Add DMA support. */ mutex_lock(&sd_mtx); ata_enable(true); ata_led(true); + if(drive && (GPIOA_INPUT_VAL & 0x80)) /* no external sd-card inserted */ { + ret = -9; + goto error; } + if((card_info+drive != currcard) || !card_info[drive].initialized) + sd_init_device(drive); + last_disk_activity = current_tick; + if(start >= BLOCKS_PER_BANK) + { + sd_select_bank(1); + start -= BLOCKS_PER_BANK; + } + else + sd_select_bank(0); + ret = 0; + sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY); + BLOCK_COUNT_REG = incount; + sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, &dummy, 0x1c25); + /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ + buf_end = inbuf + incount * currcard->block_size; + for (buf = inbuf; buf < buf_end; buf += FIFO_SIZE*2) + { + /* Wait for the FIFO to be full */ + sd_poll_status(FIFO_FULL, 0x80000, EC_FIFO_READ_FULL | DO_PANIC); + copy_read_sectors(buf); /* Copy one chunk of 16 words */ + /* TODO: Switch bank if necessary */ } + + last_disk_activity = current_tick; + // udelay(75); + sd_command(STOP_TRANSMISSION, 0, &dummy, 1); + sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT); + + error: ata_led(false); ata_enable(false); *************** *** 537,611 **** } - int ata_write_sectors(IF_MV2(int drive,) - unsigned long start, - int count, - const void* buf) { /* Write support is not finished yet */ - /* TODO: The standard suggests using ACMD23 prior to writing multiple blocks to improve performance */ unsigned int response; - void const* write_buf; int ret = 0; - unsigned int i; - long timeout; - tSDCardInfo *card = &card_info[current_card]; mutex_lock(&sd_mtx); ata_enable(true); ata_led(true); - if(current_card == 0) { - if(start < BLOCKS_PER_BANK) - { - sd_select_bank(0); - } else { - sd_select_bank(1); - start -= BLOCKS_PER_BANK; - } } - retry: - sd_wait_for_state(card, TRAN); BLOCK_COUNT_REG = count; - sd_send_command(WRITE_MULTIPLE_BLOCK, start * SECTOR_SIZE, 0x1c2d); - sd_read_response(&response, 1); - write_buf = buf; - for (i = 0; i < count * card->block_size / 2; i += FIFO_SIZE) { - if(i >= (count * card->block_size / 2)-FIFO_SIZE) { /* Set SD_STATE_REG to PRG for the last buffer fill */ SD_STATE_REG = PRG; } - /* Wait for the FIFO to be empty */ - while((STATUS_REG & FIFO_EMPTY) == 0) {} - /* Perhaps we could use bit 8 of card status (READY_FOR_DATA)? */ - copy_write_sectors(write_buf, FIFO_SIZE); - write_buf += FIFO_SIZE*2; /* Advance one chunk of 16 words */ - /* TODO: Switch bank if necessary */ - last_disk_activity = current_tick; } - timeout = current_tick + WRITE_TIMEOUT; - while((STATUS_REG & DATA_DONE) == 0) { - if(current_tick >= timeout) - { - sd_send_command(STOP_TRANSMISSION, 0, 1); - sd_read_response(&response, 1); - goto retry; - } - } - sd_send_command(STOP_TRANSMISSION, 0, 1); - sd_read_response(&response, 1); - sd_wait_for_state(card, TRAN); ata_led(false); ata_enable(false); mutex_unlock(&sd_mtx); --- 499,569 ---- } + int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, + const void* outbuf) { /* Write support is not finished yet */ + /* TODO: The standard suggests using ACMD23 prior to writing multiple blocks to improve performance */ unsigned int response; + void const* buf, *buf_end; int ret = 0; mutex_lock(&sd_mtx); + ata_enable(true); ata_led(true); + + if(drive && (GPIOA_INPUT_VAL & 0x80)) /* no external sd-card inserted */ { + ret = -9; + goto error; } + if((card_info+drive != currcard) || !card_info[drive].initialized) + sd_init_device(drive); + + if(start >= BLOCKS_PER_BANK) + { + sd_select_bank(1); + start -= BLOCKS_PER_BANK; + } + else + sd_select_bank(0); + + check_time[EC_WRITE_TIMEOUT] = USEC_TIMER; + sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY); BLOCK_COUNT_REG = count; + sd_command(WRITE_MULTIPLE_BLOCK, start * SECTOR_SIZE, &response, 0x1c2d); + + buf_end = outbuf + count * currcard->block_size; + for (buf = outbuf; buf < buf_end; buf += 2 * FIFO_SIZE) { + if(buf >= buf_end - 2 * FIFO_SIZE) { /* Set SD_STATE_REG to PRG for the last buffer fill */ SD_STATE_REG = PRG; } + udelay(2); /* needed here (loop is too fast :-) */ + /* Wait for the FIFO to empty */ + sd_poll_status(FIFO_EMPTY, 0x80000, EC_FIFO_WR_EMPTY | DO_PANIC); + copy_write_sectors(buf); /* Copy one chunk of 16 words */ + /* TODO: Switch bank if necessary */ } + last_disk_activity = current_tick; + + sd_poll_status(DATA_DONE, 0x80000, EC_FIFO_WR_DONE | DO_PANIC); + sd_check_timeout(0x80000, EC_WRITE_TIMEOUT); + sd_command(STOP_TRANSMISSION, 0, &response, 1); + sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT); + error: ata_led(false); ata_enable(false); mutex_unlock(&sd_mtx);