less sd fail.

This commit is contained in:
Sven Peter 2009-04-12 02:21:32 +02:00 committed by bushing
parent 6b5ca1a194
commit cccd6f5332
4 changed files with 51 additions and 12 deletions

1
ipc.h
View File

@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define IPC_NAND_ERASE 0x0004
#define IPC_NAND_STATUS 0x0005
#define IPC_SD_DISCOVER 0x0000
/*#define IPC_SD_MOUNT 0x0000
#define IPC_SD_SELECT 0x0001
#define IPC_SD_GETSTATE 0x0002

2
irq.c
View File

@ -100,7 +100,7 @@ void irq_handler(void)
write32(HW_ARMIRQFLAG, IRQF_AES);
}
if (flags & IRQF_SDHC) {
gecko_printf("IRQ: SDHC\n");
// gecko_printf("IRQ: SDHC\n");
write32(HW_ARMIRQFLAG, IRQF_SDHC);
sdhc_irq();
}

14
sdhc.c
View File

@ -1004,8 +1004,14 @@ sdhc_intr(void *arg)
* TODO: move request to slow queue to make sure that
* we're not blocking other IRQs
*/
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION))
sdmmc_needs_discover(hp->sdmmc);
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
ipc_request req;
memset(&req, 0, sizeof(req));
req.device = IPC_DEV_SD;
req.req = IPC_SD_DISCOVER;
req.args[0] = hp->sdmmc;
ipc_add_slow(&req);
}
/*
* Wake up the blocking process to service command
@ -1062,7 +1068,6 @@ static struct sdhc_softc __softc;
void sdhc_irq(void)
{
ipc_request req;
sdhc_intr(&__softc);
}
@ -1078,5 +1083,8 @@ void sdhc_init(void)
void sdhc_ipc(volatile ipc_request *req)
{
switch (req->req) {
case IPC_SD_DISCOVER:
sdmmc_needs_discover((struct device *)req->args[0]);
break;
}
}

46
sdmmc.c
View File

@ -47,6 +47,9 @@ struct sdmmc_card {
int no;
int inserted;
int sdhc_blockmode;
u32 cid;
u16 rca;
};
static struct sdmmc_card cards[SDHC_MAX_HOSTS];
@ -125,6 +128,7 @@ void sdmmc_needs_discover(struct device *dev)
u32 ocr;
DPRINTF(0, ("sdmmc: card %d needs discovery.\n", no));
sdmmc_host_reset(c);
if (!sdmmc_host_card_detect(c)) {
DPRINTF(1, ("sdmmc: card %d (no longer?) inserted.\n", no));
@ -167,20 +171,16 @@ void sdmmc_needs_discover(struct device *dev)
cmd.c_flags = SCF_RSP_R7;
sdmmc_host_exec_command(c, &cmd);
gecko_printf("response: %08x %08x %08x %08x\n", cmd.c_resp[0],
cmd.c_resp[1], cmd.c_resp[2], cmd.c_resp[3]);
ocr = sdmmc_host_ocr(c);
if (cmd.c_error || (cmd.c_resp[0] & 0xff) != 0xaa)
ocr &= ~SD_OCR_SDHC_CAP;
else
ocr |= SD_OCR_SDHC_CAP;
gecko_printf("-----> ocr: %x\n", ocr);
DPRINTF(2, ("sdmmc: SEND_IF_COND ocr: %x\n", ocr));
int tries;
for (tries = 10; tries > 0; tries--) {
udelay(10000);
for (tries = 100; tries > 0; tries--) {
udelay(100000);
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_APP_CMD;
@ -199,8 +199,9 @@ void sdmmc_needs_discover(struct device *dev)
if (cmd.c_error)
continue;
gecko_printf("response: %08x\n", cmd.c_resp[0]);
if (ISSET(cmd.c_resp[0], MMC_OCR_MEM_READY))
DPRINTF(3, ("sdmmc: response for SEND_IF_COND: %08x\n",
MMC_R1(cmd.c_resp)));
if (ISSET(MMC_R1(cmd.c_resp), MMC_OCR_MEM_READY))
break;
}
if (!ISSET(cmd.c_resp[0], MMC_OCR_MEM_READY)) {
@ -208,6 +209,35 @@ void sdmmc_needs_discover(struct device *dev)
goto out_power;
}
DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_ALL_SEND_CID;
cmd.c_arg = 0;
cmd.c_flags = SCF_RSP_R2;
sdmmc_host_exec_command(c, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_ALL_SEND_CID failed with %d for card %d\n",
cmd.c_error, no);
goto out_clock;
}
c->cid = MMC_R1(cmd.c_resp);
DPRINTF(2, ("sdmmc: SD_SEND_RELATIVE_ADDRESS\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = SD_SEND_RELATIVE_ADDR;
cmd.c_arg = 0;
cmd.c_flags = SCF_RSP_R6;
sdmmc_host_exec_command(c, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: SD_SEND_RCA failed with %d for card %d\n",
cmd.c_error, no);
goto out_clock;
}
c->rca = MMC_R1(cmd.c_resp)>>16;
DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca));
c->inserted = 1;
return;
out_clock: