mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-28 06:04:19 +01:00
sdhc/sdmmc is getting closer to read valid data :>
This commit is contained in:
parent
cccd6f5332
commit
2ad64f59a8
22
diskio.c
22
diskio.c
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "sdmmc.h"
|
||||||
//#include "sdhc.h"
|
//#include "sdhc.h"
|
||||||
|
|
||||||
#ifndef MEM2_BSS
|
#ifndef MEM2_BSS
|
||||||
@ -23,15 +24,11 @@ DSTATUS disk_initialize (
|
|||||||
BYTE drv /* Physical drive nmuber (0..) */
|
BYTE drv /* Physical drive nmuber (0..) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
s32 ret;
|
if (sdmmc_check_card(SDMMC_DEFAULT_DEVICE) == SDMMC_NO_CARD)
|
||||||
|
|
||||||
// sd_init(&sdhci, 0);
|
|
||||||
// ret = sd_mount(&sdhci);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
return STA_NOINIT;
|
return STA_NOINIT;
|
||||||
else
|
|
||||||
return disk_status(drv);
|
sdmmc_ack_card(SDMMC_DEFAULT_DEVICE);
|
||||||
|
return disk_status(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +43,10 @@ DSTATUS disk_status (
|
|||||||
// if (sd_inserted(&sdhci) == 0)
|
// if (sd_inserted(&sdhci) == 0)
|
||||||
// return STA_NODISK;
|
// return STA_NODISK;
|
||||||
|
|
||||||
return 0;
|
if (sdmmc_check_card(SDMMC_DEFAULT_DEVICE) == SDMMC_INSERTED)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return STA_NODISK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,10 +66,10 @@ DRESULT disk_read (
|
|||||||
|
|
||||||
res = RES_OK;
|
res = RES_OK;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
/* if (sd_read(&sdhci, sector + i, 1, buffer) != 0) {
|
if (sdmmc_read(SDMMC_DEFAULT_DEVICE, sector+i, 1, buffer) != 0){
|
||||||
res = RES_ERROR;
|
res = RES_ERROR;
|
||||||
break;
|
break;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
memcpy(buff + i * 512, buffer, 512);
|
memcpy(buff + i * 512, buffer, 512);
|
||||||
}
|
}
|
||||||
|
2
mini.ld
2
mini.ld
@ -5,7 +5,7 @@ EXTERN(__ipc_info)
|
|||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
__stack_size = 0x800;
|
__stack_size = 0x800;
|
||||||
__irqstack_size = 0x400; /* blame the bsd's sdhc_intr function */
|
__irqstack_size = 0x200; /* blame the bsd's sdhc_intr function */
|
||||||
__excstack_size = 0x100;
|
__excstack_size = 0x100;
|
||||||
|
|
||||||
MEMORY {
|
MEMORY {
|
||||||
|
24
sdhc.c
24
sdhc.c
@ -45,7 +45,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
|
|
||||||
#define SDHC_DEBUG 0
|
#define SDHC_DEBUG 1
|
||||||
|
|
||||||
#define SDHC_COMMAND_TIMEOUT 0
|
#define SDHC_COMMAND_TIMEOUT 0
|
||||||
#define SDHC_BUFFER_TIMEOUT 0
|
#define SDHC_BUFFER_TIMEOUT 0
|
||||||
@ -159,7 +159,7 @@ void sdhc_read_data(struct sdhc_host *, u_char *, int);
|
|||||||
void sdhc_write_data(struct sdhc_host *, u_char *, int);
|
void sdhc_write_data(struct sdhc_host *, u_char *, int);
|
||||||
|
|
||||||
#ifdef SDHC_DEBUG
|
#ifdef SDHC_DEBUG
|
||||||
int sdhcdebug = 0;
|
int sdhcdebug = 2;
|
||||||
#define DPRINTF(n,s) do { if ((n) <= sdhcdebug) gecko_printf s; } while (0)
|
#define DPRINTF(n,s) do { if ((n) <= sdhcdebug) gecko_printf s; } while (0)
|
||||||
void sdhc_dump_regs(struct sdhc_host *);
|
void sdhc_dump_regs(struct sdhc_host *);
|
||||||
#else
|
#else
|
||||||
@ -972,8 +972,8 @@ sdhc_intr(void *arg)
|
|||||||
|
|
||||||
/* Acknowledge the interrupts we are about to handle. */
|
/* Acknowledge the interrupts we are about to handle. */
|
||||||
HWRITE2(hp, SDHC_NINTR_STATUS, status);
|
HWRITE2(hp, SDHC_NINTR_STATUS, status);
|
||||||
DPRINTF(2,("%s: interrupt status=%d\n", HDEVNAME(hp),
|
// DPRINTF(2,("%s: interrupt status=%d\n", HDEVNAME(hp),
|
||||||
status));
|
// status));
|
||||||
|
|
||||||
|
|
||||||
/* Claim this interrupt. */
|
/* Claim this interrupt. */
|
||||||
@ -988,11 +988,11 @@ sdhc_intr(void *arg)
|
|||||||
/* Acknowledge error interrupts. */
|
/* Acknowledge error interrupts. */
|
||||||
error = HREAD2(hp, SDHC_EINTR_STATUS);
|
error = HREAD2(hp, SDHC_EINTR_STATUS);
|
||||||
HWRITE2(hp, SDHC_EINTR_STATUS, error);
|
HWRITE2(hp, SDHC_EINTR_STATUS, error);
|
||||||
DPRINTF(2,("%s: error interrupt, status=%d\n",
|
// DPRINTF(2,("%s: error interrupt, status=%d\n",
|
||||||
HDEVNAME(hp), error));
|
// HDEVNAME(hp), error));
|
||||||
|
|
||||||
if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
|
if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
|
||||||
SDHC_DATA_TIMEOUT_ERROR)) {
|
SDHC_DATA_TIMEOUT_ERROR)) {
|
||||||
hp->intr_error_status |= error;
|
hp->intr_error_status |= error;
|
||||||
hp->intr_status |= status;
|
hp->intr_status |= status;
|
||||||
wakeup(&hp->intr_status);
|
wakeup(&hp->intr_status);
|
||||||
@ -1004,7 +1004,7 @@ sdhc_intr(void *arg)
|
|||||||
* TODO: move request to slow queue to make sure that
|
* TODO: move request to slow queue to make sure that
|
||||||
* we're not blocking other IRQs
|
* we're not blocking other IRQs
|
||||||
*/
|
*/
|
||||||
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
|
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
|
||||||
ipc_request req;
|
ipc_request req;
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.device = IPC_DEV_SD;
|
req.device = IPC_DEV_SD;
|
||||||
@ -1019,7 +1019,7 @@ sdhc_intr(void *arg)
|
|||||||
*/
|
*/
|
||||||
if (ISSET(status, SDHC_BUFFER_READ_READY|
|
if (ISSET(status, SDHC_BUFFER_READ_READY|
|
||||||
SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
|
SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
|
||||||
SDHC_TRANSFER_COMPLETE)) {
|
SDHC_TRANSFER_COMPLETE)) {
|
||||||
hp->intr_status |= status;
|
hp->intr_status |= status;
|
||||||
wakeup(&hp->intr_status);
|
wakeup(&hp->intr_status);
|
||||||
}
|
}
|
||||||
@ -1027,8 +1027,8 @@ sdhc_intr(void *arg)
|
|||||||
/*
|
/*
|
||||||
* Service SD card interrupts.
|
* Service SD card interrupts.
|
||||||
*/
|
*/
|
||||||
if (ISSET(status, SDHC_CARD_INTERRUPT)) {
|
if (ISSET(status, SDHC_CARD_INTERRUPT)) {
|
||||||
DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp)));
|
// DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp)));
|
||||||
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||||
// sdmmc_card_intr(hp->sdmmc);
|
// sdmmc_card_intr(hp->sdmmc);
|
||||||
}
|
}
|
||||||
@ -1064,7 +1064,7 @@ sdhc_dump_regs(struct sdhc_host *hp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "hollywood.h"
|
#include "hollywood.h"
|
||||||
static struct sdhc_softc __softc;
|
static struct sdhc_softc __softc MEM2_BSS;
|
||||||
|
|
||||||
void sdhc_irq(void)
|
void sdhc_irq(void)
|
||||||
{
|
{
|
||||||
|
111
sdmmc.c
111
sdmmc.c
@ -47,12 +47,14 @@ struct sdmmc_card {
|
|||||||
int no;
|
int no;
|
||||||
int inserted;
|
int inserted;
|
||||||
int sdhc_blockmode;
|
int sdhc_blockmode;
|
||||||
|
int selected;
|
||||||
|
int new_card; // set to 1 everytime a new card is inserted
|
||||||
|
|
||||||
u32 cid;
|
u32 cid;
|
||||||
u16 rca;
|
u16 rca;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sdmmc_card cards[SDHC_MAX_HOSTS];
|
static struct sdmmc_card cards[SDHC_MAX_HOSTS] MEM2_BSS;
|
||||||
static int n_cards = 0;
|
static int n_cards = 0;
|
||||||
|
|
||||||
static inline int sdmmc_host_reset(struct sdmmc_card *card)
|
static inline int sdmmc_host_reset(struct sdmmc_card *card)
|
||||||
@ -129,6 +131,7 @@ void sdmmc_needs_discover(struct device *dev)
|
|||||||
|
|
||||||
DPRINTF(0, ("sdmmc: card %d needs discovery.\n", no));
|
DPRINTF(0, ("sdmmc: card %d needs discovery.\n", no));
|
||||||
sdmmc_host_reset(c);
|
sdmmc_host_reset(c);
|
||||||
|
c->new_card = 1;
|
||||||
|
|
||||||
if (!sdmmc_host_card_detect(c)) {
|
if (!sdmmc_host_card_detect(c)) {
|
||||||
DPRINTF(1, ("sdmmc: card %d (no longer?) inserted.\n", no));
|
DPRINTF(1, ("sdmmc: card %d (no longer?) inserted.\n", no));
|
||||||
@ -209,6 +212,11 @@ void sdmmc_needs_discover(struct device *dev)
|
|||||||
goto out_power;
|
goto out_power;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ISSET(MMC_R1(cmd.c_resp), SD_OCR_SDHC_CAP))
|
||||||
|
c->sdhc_blockmode = 1;
|
||||||
|
else
|
||||||
|
c->sdhc_blockmode = 0;
|
||||||
|
|
||||||
DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n"));
|
DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n"));
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
cmd.c_opcode = MMC_ALL_SEND_CID;
|
cmd.c_opcode = MMC_ALL_SEND_CID;
|
||||||
@ -237,7 +245,23 @@ void sdmmc_needs_discover(struct device *dev)
|
|||||||
|
|
||||||
c->rca = MMC_R1(cmd.c_resp)>>16;
|
c->rca = MMC_R1(cmd.c_resp)>>16;
|
||||||
DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca));
|
DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca));
|
||||||
|
|
||||||
|
c->selected = 0;
|
||||||
c->inserted = 1;
|
c->inserted = 1;
|
||||||
|
|
||||||
|
sdmmc_select(dev);
|
||||||
|
DPRINTF(2, ("sdmmc: MMC_SET_BLOCKLEN\n"));
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.c_opcode = MMC_SET_BLOCKLEN;
|
||||||
|
cmd.c_arg = SDMMC_DEFAULT_BLOCKLEN;
|
||||||
|
cmd.c_flags = SCF_RSP_R1;
|
||||||
|
sdmmc_host_exec_command(c, &cmd);
|
||||||
|
if (cmd.c_error) {
|
||||||
|
gecko_printf("sdmmc: MMC_SET_BLOCKLEN failed with %d for card %d\n",
|
||||||
|
cmd.c_error, no);
|
||||||
|
c->inserted = c->selected = 0;
|
||||||
|
goto out_clock;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
out_clock:
|
out_clock:
|
||||||
@ -286,3 +310,88 @@ out:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sdmmc_select(struct device *dev)
|
||||||
|
{
|
||||||
|
int no = (int)dev;
|
||||||
|
struct sdmmc_card *c = &cards[no];
|
||||||
|
struct sdmmc_command cmd;
|
||||||
|
|
||||||
|
DPRINTF(2, ("sdmmc: MMC_SELECT_CARD\n"));
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.c_opcode = MMC_SELECT_CARD;
|
||||||
|
cmd.c_arg = ((u32)c->rca)<<16;;
|
||||||
|
cmd.c_flags = SCF_RSP_R1;
|
||||||
|
sdmmc_host_exec_command(c, &cmd);
|
||||||
|
if (cmd.c_error) {
|
||||||
|
gecko_printf("sdmmc: MMC_SELECT card failed with %d for %d.\n",
|
||||||
|
cmd.c_error, no);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->selected = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sdmmc_check_card(struct device *dev)
|
||||||
|
{
|
||||||
|
int no = (int)dev;
|
||||||
|
struct sdmmc_card *c = &cards[no];
|
||||||
|
if (c->inserted == 0)
|
||||||
|
return SDMMC_NO_CARD;
|
||||||
|
if (c->new_card == 1)
|
||||||
|
return SDMMC_NEW_CARD;
|
||||||
|
return SDMMC_INSERTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sdmmc_ack_card(struct device *dev)
|
||||||
|
{
|
||||||
|
int no = (int)dev;
|
||||||
|
struct sdmmc_card *c = &cards[no];
|
||||||
|
c->new_card = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
|
||||||
|
{
|
||||||
|
int no = (int)dev;
|
||||||
|
struct sdmmc_card *c = &cards[no];
|
||||||
|
struct sdmmc_command cmd;
|
||||||
|
|
||||||
|
if (c->inserted == 0) {
|
||||||
|
gecko_printf("sdmmc: READ: no card inserted.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->selected == 0) {
|
||||||
|
if (sdmmc_select(dev) < 0) {
|
||||||
|
gecko_printf("sdmmc: READ: cannot select card.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->new_card == 1) {
|
||||||
|
gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE\n"));
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE;
|
||||||
|
if (c->sdhc_blockmode)
|
||||||
|
cmd.c_arg = blk_start;
|
||||||
|
else
|
||||||
|
cmd.c_arg = blk_start * SDMMC_DEFAULT_BLOCKLEN;
|
||||||
|
cmd.c_data = data;
|
||||||
|
cmd.c_datalen = blk_count * SDMMC_DEFAULT_BLOCKLEN;
|
||||||
|
cmd.c_blklen = SDMMC_DEFAULT_BLOCKLEN;
|
||||||
|
cmd.c_flags = SCF_RSP_R1 | SCF_CMD_READ;
|
||||||
|
sdmmc_host_exec_command(c, &cmd);
|
||||||
|
|
||||||
|
if (cmd.c_error) {
|
||||||
|
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed for "
|
||||||
|
"card %d with %d", no, cmd.c_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
gecko_printf("success!!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
15
sdmmc.h
15
sdmmc.h
@ -22,12 +22,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#ifndef __SDMMC_H__
|
#ifndef __SDMMC_H__
|
||||||
#define __SDMMC_H__ 1
|
#define __SDMMC_H__ 1
|
||||||
|
|
||||||
#include "sdmmcvar.h"
|
#include "bsdtypes.h"
|
||||||
#include "sdmmcchip.h"
|
#include "sdmmcchip.h"
|
||||||
|
#include "sdmmcvar.h"
|
||||||
|
|
||||||
#define SDMMC_DEFAULT_CLOCK 25000
|
#define SDMMC_DEFAULT_CLOCK 25000
|
||||||
|
#define SDMMC_DEFAULT_BLOCKLEN 512
|
||||||
|
|
||||||
|
#define SDMMC_NO_CARD 1
|
||||||
|
#define SDMMC_NEW_CARD 2
|
||||||
|
#define SDMMC_INSERTED 3
|
||||||
|
|
||||||
|
// HACK
|
||||||
|
#define SDMMC_DEFAULT_DEVICE ((struct device *)0)
|
||||||
|
|
||||||
struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
|
struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
|
||||||
sdmmc_chipset_handle_t handle, const char *name, int no);
|
sdmmc_chipset_handle_t handle, const char *name, int no);
|
||||||
void sdmmc_needs_discover(struct device *dev);
|
void sdmmc_needs_discover(struct device *dev);
|
||||||
|
int sdmmc_select(struct device *dev);
|
||||||
|
int sdmmc_check_card(struct device *dev);
|
||||||
|
void sdmmc_ack_card(struct device *dev);
|
||||||
|
int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user