mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 05:05:20 -05:00
Merge branch 'hotswap'
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23759 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
b2dc7f004e
commit
d052ced874
7 changed files with 282 additions and 125 deletions
|
|
@ -22,25 +22,40 @@
|
|||
#include "config.h"
|
||||
#include "jz4740.h"
|
||||
#include "ata.h"
|
||||
#include "ata_idle_notify.h"
|
||||
#include "ata-sd-target.h"
|
||||
#include "disk.h"
|
||||
#include "fat.h"
|
||||
#include "led.h"
|
||||
#include "hotswap.h"
|
||||
#include "logf.h"
|
||||
#include "sd.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "panic.h"
|
||||
#include "debug.h"
|
||||
#include "storage.h"
|
||||
#include "string.h"
|
||||
#include "led.h"
|
||||
#include "usb.h"
|
||||
|
||||
static struct wakeup sd_wakeup;
|
||||
static long last_disk_activity = -1;
|
||||
static tCardInfo card;
|
||||
static long last_disk_activity = -1;
|
||||
static int sd_drive_nr = 0;
|
||||
static tCardInfo card;
|
||||
|
||||
static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
|
||||
static const char sd_thread_name[] = "ata/sd";
|
||||
static struct event_queue sd_queue;
|
||||
static struct mutex sd_mtx;
|
||||
static struct wakeup sd_wakeup;
|
||||
static void sd_thread(void) __attribute__((noreturn));
|
||||
|
||||
static int use_4bit;
|
||||
static int num_6;
|
||||
static int sd2_0;
|
||||
|
||||
//#define SD_DMA_ENABLE
|
||||
#define SD_DMA_INTERRUPT 0
|
||||
|
||||
#define DEBUG(x...) logf(x)
|
||||
//#define DEBUG(x...) logf(x)
|
||||
#define DEBUG(x, ...)
|
||||
|
||||
#define SD_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN)
|
||||
#define SD_RESET() __msc_reset()
|
||||
|
|
@ -117,7 +132,6 @@ enum sd_rsp_t
|
|||
RESPONSE_R7 = 9,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
MMC status in R1
|
||||
Type
|
||||
|
|
@ -199,10 +213,6 @@ struct sd_request
|
|||
#define SD_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
|
||||
#define SD_EVENT_PROG_DONE 0x04 /* Programming is done */
|
||||
|
||||
static int use_4bit = 1; /* Use 4-bit data bus */
|
||||
static int num_6 = 0;
|
||||
static int sd2_0 = 0;
|
||||
|
||||
/**************************************************************************
|
||||
* Utility functions
|
||||
**************************************************************************/
|
||||
|
|
@ -214,7 +224,7 @@ static int sd2_0 = 0;
|
|||
#define PARSE_U16(_buf,_index) \
|
||||
(((unsigned short)_buf[_index]) << 8) | ((unsigned short)_buf[_index+1]);
|
||||
|
||||
int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1)
|
||||
static int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1)
|
||||
{
|
||||
unsigned char *buf = request->response;
|
||||
|
||||
|
|
@ -253,32 +263,22 @@ int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sd_unpack_scr(struct sd_request *request, struct sd_response_r1 *r1, unsigned int *scr)
|
||||
{
|
||||
unsigned char *buf = request->response;
|
||||
if (request->result)
|
||||
return request->result;
|
||||
|
||||
*scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
|
||||
return sd_unpack_r1(request, r1);
|
||||
}
|
||||
|
||||
static inline int sd_unpack_r6(struct sd_request *request, struct sd_response_r1 *r1, unsigned long *rca)
|
||||
static int sd_unpack_r6(struct sd_request *request, struct sd_response_r1 *r1, unsigned long *rca)
|
||||
{
|
||||
unsigned char *buf = request->response;
|
||||
|
||||
if (request->result)
|
||||
return request->result;
|
||||
|
||||
|
||||
*rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
|
||||
|
||||
|
||||
*(buf+1) = 0;
|
||||
*(buf+2) = 0;
|
||||
|
||||
return sd_unpack_r1(request, r1);
|
||||
}
|
||||
|
||||
int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3)
|
||||
return sd_unpack_r1(request, r1);
|
||||
}
|
||||
|
||||
static int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3)
|
||||
{
|
||||
unsigned char *buf = request->response;
|
||||
|
||||
|
|
@ -287,7 +287,9 @@ int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3)
|
|||
r3->ocr = PARSE_U32(buf,1);
|
||||
DEBUG("sd_unpack_r3: ocr=%08x", r3->ocr);
|
||||
|
||||
if (buf[0] != 0x3f) return SD_ERROR_HEADER_MISMATCH;
|
||||
if (buf[0] != 0x3f)
|
||||
return SD_ERROR_HEADER_MISMATCH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -917,7 +919,6 @@ static void jz_sd_tx_handler(unsigned int arg)
|
|||
}
|
||||
if (__dmac_channel_transmit_end_detected(arg))
|
||||
{
|
||||
|
||||
__dmac_channel_clear_transmit_end(arg);
|
||||
OSSemPost(sd_dma_tx_sem);
|
||||
}
|
||||
|
|
@ -945,6 +946,14 @@ void MSC(void)
|
|||
logf("MSC interrupt");
|
||||
}
|
||||
|
||||
static void sd_gpio_setup_irq(bool inserted)
|
||||
{
|
||||
if(inserted)
|
||||
__gpio_as_irq_rise_edge(MMC_CD_PIN);
|
||||
else
|
||||
__gpio_as_irq_fall_edge(MMC_CD_PIN);
|
||||
}
|
||||
|
||||
/*******************************************************************************************************************
|
||||
** Name: void sd_hardware_init()
|
||||
** Function: initialize the hardware condiction that access sd card
|
||||
|
|
@ -954,7 +963,8 @@ void MSC(void)
|
|||
static void jz_sd_hardware_init(void)
|
||||
{
|
||||
__cpm_start_msc(); /* enable mmc clock */
|
||||
mmc_init_gpio(); /* init GPIO */
|
||||
sd_init_gpio(); /* init GPIO */
|
||||
sd_gpio_setup_irq(jz_sd_chkcard());
|
||||
#ifdef SD_POWER_ON
|
||||
SD_POWER_ON(); /* turn on power of card */
|
||||
#endif
|
||||
|
|
@ -1000,7 +1010,6 @@ static void sd_simple_cmd(struct sd_request *request, int cmd, unsigned int arg,
|
|||
#define SD_INIT_DOING 0
|
||||
#define SD_INIT_PASSED 1
|
||||
#define SD_INIT_FAILED 2
|
||||
|
||||
static int sd_init_card_state(struct sd_request *request)
|
||||
{
|
||||
struct sd_response_r1 r1;
|
||||
|
|
@ -1026,41 +1035,42 @@ static int sd_init_card_state(struct sd_request *request)
|
|||
retval);
|
||||
limit_41++;
|
||||
sd_simple_cmd(request, SD_APP_OP_COND, ocr, RESPONSE_R3);
|
||||
} else if (limit_41 < 100) {
|
||||
}
|
||||
else if (limit_41 < 100)
|
||||
{
|
||||
limit_41++;
|
||||
sd_simple_cmd(request, SD_APP_OP_COND, ocr, RESPONSE_R3);
|
||||
} else{
|
||||
}
|
||||
else
|
||||
/* reset the card to idle*/
|
||||
sd_simple_cmd(request, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
|
||||
}
|
||||
break;
|
||||
|
||||
case SD_APP_OP_COND:
|
||||
retval = sd_unpack_r3(request, &r3);
|
||||
if (retval)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG("sd_init_card_state: read ocr value = 0x%08x", r3.ocr);
|
||||
card.ocr = r3.ocr;
|
||||
|
||||
if(!(r3.ocr & SD_CARD_BUSY || ocr == 0)){
|
||||
udelay(10000);
|
||||
if(!(r3.ocr & SD_CARD_BUSY || ocr == 0))
|
||||
{
|
||||
sleep(HZ / 100);
|
||||
sd_simple_cmd(request, SD_APP_CMD, 0, RESPONSE_R1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the data bus width to 4 bits */
|
||||
use_4bit = 1;
|
||||
sd_simple_cmd(request, SD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
|
||||
/* Set the data bus width to 4 bits */
|
||||
use_4bit = 1;
|
||||
sd_simple_cmd(request, SD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
|
||||
}
|
||||
break;
|
||||
|
||||
case SD_ALL_SEND_CID:
|
||||
for(i=0; i<4; i++)
|
||||
card.cid[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) |
|
||||
(request->response[3+i*4]<< 8) | request->response[4+i*4]);
|
||||
(request->response[3+i*4]<< 8) | request->response[4+i*4]);
|
||||
|
||||
logf("CID: %08lx%08lx%08lx%08lx", card.cid[0], card.cid[1], card.cid[2], card.cid[3]);
|
||||
sd_simple_cmd(request, SD_SEND_RELATIVE_ADDR, 0, RESPONSE_R6);
|
||||
|
|
@ -1068,7 +1078,7 @@ static int sd_init_card_state(struct sd_request *request)
|
|||
case SD_SEND_RELATIVE_ADDR:
|
||||
retval = sd_unpack_r6(request, &r1, &card.rca);
|
||||
card.rca = card.rca << 16;
|
||||
DEBUG("sd_init_card_state: Get RCA from SD: 0x%04x Status: %x", card.rca, r1.status);
|
||||
DEBUG("sd_init_card_state: Get RCA from SD: 0x%04lx Status: %x", card.rca, r1.status);
|
||||
if (retval)
|
||||
{
|
||||
DEBUG("sd_init_card_state: unable to SET_RELATIVE_ADDR error=%d",
|
||||
|
|
@ -1082,7 +1092,7 @@ static int sd_init_card_state(struct sd_request *request)
|
|||
case SD_SEND_CSD:
|
||||
for(i=0; i<4; i++)
|
||||
card.csd[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) |
|
||||
(request->response[3+i*4]<< 8) | request->response[4+i*4]);
|
||||
(request->response[3+i*4]<< 8) | request->response[4+i*4]);
|
||||
|
||||
sd_parse_csd(&card);
|
||||
sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1);
|
||||
|
|
@ -1091,6 +1101,7 @@ static int sd_init_card_state(struct sd_request *request)
|
|||
DEBUG("SD card is ready");
|
||||
jz_sd_set_clock(SD_CLOCK_FAST);
|
||||
return SD_INIT_PASSED;
|
||||
|
||||
default:
|
||||
DEBUG("sd_init_card_state: error! Illegal last cmd %d", request->cmd);
|
||||
return SD_INIT_FAILED;
|
||||
|
|
@ -1110,7 +1121,7 @@ static int sd_switch(struct sd_request *request, int mode, int group,
|
|||
arg &= ~(0xF << (group * 4));
|
||||
arg |= value << (group * 4);
|
||||
sd_send_cmd(request, 6, arg, 1, 64, RESPONSE_R1, resp);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1123,7 +1134,7 @@ static int sd_read_switch(struct sd_request *request)
|
|||
|
||||
memset((unsigned char *)status, 0, 64);
|
||||
sd_switch(request, 0, 0, 1, (unsigned char*) status);
|
||||
|
||||
|
||||
if (((unsigned char *)status)[13] & 0x02)
|
||||
return 0;
|
||||
else
|
||||
|
|
@ -1141,7 +1152,7 @@ static int sd_switch_hs(struct sd_request *request)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sd_select_card(void)
|
||||
static int sd_select_card(void)
|
||||
{
|
||||
struct sd_request request;
|
||||
struct sd_response_r1 r1;
|
||||
|
|
@ -1173,31 +1184,57 @@ int sd_select_card(void)
|
|||
if (retval)
|
||||
return retval;
|
||||
|
||||
card.initialized = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_init_device(void)
|
||||
{
|
||||
int retval;
|
||||
struct sd_request init_req;
|
||||
|
||||
mutex_lock(&sd_mtx);
|
||||
|
||||
/* Initialise card data as blank */
|
||||
memset(&card, 0, sizeof(tCardInfo));
|
||||
|
||||
sd2_0 = 0;
|
||||
num_6 = 0;
|
||||
use_4bit = 0;
|
||||
|
||||
/* reset mmc/sd controller */
|
||||
jz_sd_hardware_init();
|
||||
|
||||
sd_simple_cmd(&init_req, SD_CIM_RESET, 0, RESPONSE_NONE);
|
||||
sd_simple_cmd(&init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
|
||||
|
||||
sleep(HZ/2); /* Give the card/controller some rest */
|
||||
|
||||
while((retval = sd_init_card_state(&init_req)) == SD_INIT_DOING);
|
||||
retval = (retval == SD_INIT_PASSED ? sd_select_card() : -1);
|
||||
|
||||
mutex_unlock(&sd_mtx);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int sd_init(void)
|
||||
{
|
||||
int retval;
|
||||
static bool inited = false;
|
||||
struct sd_request init_req;
|
||||
if(!inited)
|
||||
{
|
||||
jz_sd_hardware_init();
|
||||
wakeup_init(&sd_wakeup);
|
||||
num_6 = 0;
|
||||
mutex_init(&sd_mtx);
|
||||
queue_init(&sd_queue, true);
|
||||
create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
|
||||
sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
|
||||
IF_COP(, CPU));
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
sd_simple_cmd(&init_req, SD_CIM_RESET, 0, RESPONSE_NONE);
|
||||
sd_simple_cmd(&init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
|
||||
|
||||
while ((retval = sd_init_card_state(&init_req)) == SD_INIT_DOING);
|
||||
|
||||
if (retval == SD_INIT_PASSED)
|
||||
return sd_select_card();
|
||||
else
|
||||
return -1;
|
||||
return sd_init_device();
|
||||
}
|
||||
|
||||
static inline bool card_detect_target(void)
|
||||
|
|
@ -1205,20 +1242,6 @@ static inline bool card_detect_target(void)
|
|||
return (jz_sd_chkcard() == 1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
void card_enable_monitoring_target(bool on)
|
||||
{
|
||||
if(on)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tCardInfo* card_get_info_target(int card_no)
|
||||
{
|
||||
(void)card_no;
|
||||
|
|
@ -1230,30 +1253,34 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf
|
|||
#ifdef HAVE_MULTIVOLUME
|
||||
(void)drive;
|
||||
#endif
|
||||
mutex_lock(&sd_mtx);
|
||||
led(true);
|
||||
|
||||
struct sd_request request;
|
||||
struct sd_response_r1 r1;
|
||||
int retval;
|
||||
int retval = -1;
|
||||
|
||||
if (!card_detect_target() || count == 0 || start > card.numblocks)
|
||||
return -1;
|
||||
|
||||
goto err;
|
||||
|
||||
if(card.initialized == 0 && !sd_init_device())
|
||||
goto err;
|
||||
|
||||
sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1);
|
||||
retval = sd_unpack_r1(&request, &r1);
|
||||
if (retval && (retval != SD_ERROR_STATE_MISMATCH))
|
||||
return retval;
|
||||
|
||||
goto err;
|
||||
|
||||
sd_simple_cmd(&request, SD_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
|
||||
goto err;
|
||||
|
||||
if (sd2_0)
|
||||
{
|
||||
sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start,
|
||||
count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1261,16 +1288,18 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf
|
|||
start * SD_BLOCK_SIZE, count,
|
||||
SD_BLOCK_SIZE, RESPONSE_R1, buf);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
|
||||
goto err;
|
||||
|
||||
err:
|
||||
led(false);
|
||||
mutex_unlock(&sd_mtx);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1280,23 +1309,27 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
|
|||
#ifdef HAVE_MULTIVOLUME
|
||||
(void)drive;
|
||||
#endif
|
||||
mutex_lock(&sd_mtx);
|
||||
led(true);
|
||||
|
||||
struct sd_request request;
|
||||
struct sd_response_r1 r1;
|
||||
int retval;
|
||||
int retval = -1;
|
||||
|
||||
if (!card_detect_target() || count == 0 || start > card.numblocks)
|
||||
return -1;
|
||||
goto err;
|
||||
|
||||
if(card.initialized == 0 && !sd_init_device())
|
||||
goto err;
|
||||
|
||||
sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1);
|
||||
retval = sd_unpack_r1(&request, &r1);
|
||||
if (retval && (retval != SD_ERROR_STATE_MISMATCH))
|
||||
return retval;
|
||||
goto err;
|
||||
|
||||
sd_simple_cmd(&request, SD_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
goto err;
|
||||
|
||||
if (sd2_0)
|
||||
{
|
||||
|
|
@ -1304,7 +1337,7 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
|
|||
count, SD_BLOCK_SIZE, RESPONSE_R1,
|
||||
(void*)buf);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1312,13 +1345,18 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
|
|||
start * SD_BLOCK_SIZE, count,
|
||||
SD_BLOCK_SIZE, RESPONSE_R1, (void*)buf);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
goto err;
|
||||
}
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
|
||||
if ((retval = sd_unpack_r1(&request, &r1)))
|
||||
return retval;
|
||||
goto err;
|
||||
|
||||
err:
|
||||
led(false);
|
||||
mutex_unlock(&sd_mtx);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1342,10 +1380,9 @@ void sd_sleepnow(void)
|
|||
{
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
bool sd_disk_is_active(void)
|
||||
{
|
||||
return false;
|
||||
return sd_mtx.locked;
|
||||
}
|
||||
|
||||
int sd_soft_reset(void)
|
||||
|
|
@ -1359,8 +1396,39 @@ bool sd_removable(IF_MV_NONVOID(int drive))
|
|||
#ifdef HAVE_MULTIVOLUME
|
||||
(void)drive;
|
||||
#endif
|
||||
//return true;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void card_enable_monitoring_target(bool on)
|
||||
{
|
||||
if(on)
|
||||
sd_gpio_setup_irq(card_detect_target());
|
||||
else
|
||||
__gpio_mask_irq(MMC_CD_PIN);
|
||||
}
|
||||
|
||||
static int sd_oneshot_callback(struct timeout *tmo)
|
||||
{
|
||||
(void)tmo;
|
||||
int state = card_detect_target();
|
||||
|
||||
/* This is called only if the state was stable for 300ms - check state
|
||||
* and post appropriate event. */
|
||||
if (state)
|
||||
queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
|
||||
else
|
||||
queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
|
||||
|
||||
sd_gpio_setup_irq(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* called on insertion/removal interrupt */
|
||||
void MMC_CD_IRQ(void)
|
||||
{
|
||||
static struct timeout sd_oneshot;
|
||||
timeout_register(&sd_oneshot, sd_oneshot_callback, (3*HZ/10), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1375,9 +1443,72 @@ bool sd_present(IF_MV_NONVOID(int drive))
|
|||
#ifdef CONFIG_STORAGE_MULTI
|
||||
int sd_num_drives(int first_drive)
|
||||
{
|
||||
/* We don't care which logical drive number(s) we have been assigned */
|
||||
(void)first_drive;
|
||||
|
||||
sd_drive_nr = first_drive;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sd_thread(void)
|
||||
{
|
||||
struct queue_event ev;
|
||||
bool idle_notified = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
queue_wait_w_tmo(&sd_queue, &ev, HZ);
|
||||
|
||||
switch (ev.id)
|
||||
{
|
||||
#ifdef HAVE_HOTSWAP
|
||||
case SYS_HOTSWAP_INSERTED:
|
||||
case SYS_HOTSWAP_EXTRACTED:
|
||||
fat_lock(); /* lock-out FAT activity first -
|
||||
prevent deadlocking via disk_mount that
|
||||
would cause a reverse-order attempt with
|
||||
another thread */
|
||||
mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
|
||||
into driver that bypass the fat cache */
|
||||
|
||||
/* We now have exclusive control of fat cache and ata */
|
||||
|
||||
disk_unmount(sd_drive_nr); /* release "by force", ensure file
|
||||
descriptors aren't leaked and any busy
|
||||
ones are invalid if mounting */
|
||||
|
||||
/* Force card init for new card, re-init for re-inserted one or
|
||||
* clear if the last attempt to init failed with an error. */
|
||||
card.initialized = 0;
|
||||
|
||||
if(ev.id == SYS_HOTSWAP_INSERTED)
|
||||
disk_mount(sd_drive_nr);
|
||||
|
||||
queue_broadcast(SYS_FS_CHANGED, 0);
|
||||
|
||||
/* Access is now safe */
|
||||
mutex_unlock(&sd_mtx);
|
||||
fat_unlock();
|
||||
break;
|
||||
#endif
|
||||
case SYS_TIMEOUT:
|
||||
if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
|
||||
idle_notified = false;
|
||||
else
|
||||
{
|
||||
if (!idle_notified)
|
||||
{
|
||||
call_storage_idle_notifys(false);
|
||||
idle_notified = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SYS_USB_CONNECTED:
|
||||
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
||||
/* Wait until the USB cable is extracted again */
|
||||
usb_wait_for_disconnect(&sd_queue);
|
||||
break;
|
||||
case SYS_USB_DISCONNECTED:
|
||||
usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,20 +22,19 @@
|
|||
#ifndef ATA_SD_TARGET_H
|
||||
#define ATA_SD_TARGET_H
|
||||
|
||||
#include "inttypes.h"
|
||||
#include "hotswap.h"
|
||||
#include "jz4740.h"
|
||||
|
||||
int _sd_read_sectors(unsigned long start, int count, void* buf);
|
||||
int _sd_write_sectors(unsigned long start, int count, const void* buf);
|
||||
int _sd_init(void);
|
||||
#include "system.h"
|
||||
|
||||
#define MMC_CD_PIN (32*1 + 29) /* Pin to check card insertion */
|
||||
#define MMC_CD_IRQ GPIO61
|
||||
|
||||
static inline void mmc_init_gpio(void)
|
||||
static inline void sd_init_gpio(void)
|
||||
{
|
||||
__gpio_as_msc();
|
||||
__gpio_enable_pull(MMC_CD_PIN);
|
||||
__gpio_as_input(MMC_CD_PIN);
|
||||
__gpio_mask_irq(MMC_CD_PIN);
|
||||
system_enable_irq(GPIO_IRQ(MMC_CD_PIN));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@
|
|||
/* This one returns the old status */
|
||||
static inline int set_interrupt_status(int status, int mask)
|
||||
{
|
||||
unsigned int res, oldstatus;
|
||||
|
||||
res = oldstatus = read_c0_status();
|
||||
res &= ~mask;
|
||||
res |= (status & mask);
|
||||
write_c0_status(res);
|
||||
|
||||
return oldstatus;
|
||||
unsigned int res, oldstatus;
|
||||
|
||||
res = oldstatus = read_c0_status();
|
||||
res &= ~mask;
|
||||
res |= (status & mask);
|
||||
write_c0_status(res);
|
||||
|
||||
return oldstatus;
|
||||
}
|
||||
|
||||
static inline void enable_interrupt(void)
|
||||
|
|
@ -71,9 +71,9 @@ static inline void restore_interrupt(int status)
|
|||
#define set_irq_level(status) set_interrupt_status((status), ST0_IE)
|
||||
#define disable_irq_save() disable_interrupt_save(ST0_IE)
|
||||
#define restore_irq(c0_status) restore_interrupt(c0_status)
|
||||
|
||||
#define swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff)
|
||||
#define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | \
|
||||
|
||||
#define swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff)
|
||||
#define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | \
|
||||
((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)
|
||||
|
||||
#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000)
|
||||
|
|
@ -94,6 +94,7 @@ void dma_disable(void);
|
|||
#define XDMA_CALLBACK(n) DMA ## n
|
||||
#define DMA_CALLBACK(n) XDMA_CALLBACK(n)
|
||||
|
||||
#define DMA_IRQ(n) (IRQ_DMA_0 + n)
|
||||
#define DMA_IRQ(n) (IRQ_DMA_0 + (n))
|
||||
#define GPIO_IRQ(n) (IRQ_GPIO_0 + (n))
|
||||
|
||||
#endif /* __SYSTEM_TARGET_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue