more sd code simplification, removing bsd cruft

This commit is contained in:
bushing 2009-10-26 02:19:37 -07:00
parent 1fcd51701f
commit d7e80776a2
6 changed files with 112 additions and 262 deletions

View File

@ -23,11 +23,6 @@ typedef u8 u_char;
typedef u32 bus_space_tag_t;
typedef u32 bus_space_handle_t;
struct device {
char dv_xname[255];
void *dummy;
};
#define MIN(a, b) (((a)>(b))?(b):(a))
#define wakeup(...)

View File

@ -18,34 +18,34 @@ Copyright (C) 2008, 2009 Haxx Enterprises <bushing@gmail.com>
#endif
static u8 buffer[512] MEM2_BSS ALIGNED(32);
// Initialize a Drive
DSTATUS disk_initialize (BYTE drv) {
if (sdmmc_check_card(SDMMC_DEFAULT_DEVICE) == SDMMC_NO_CARD)
return STA_NOINIT;
sdmmc_ack_card(SDMMC_DEFAULT_DEVICE);
return disk_status(drv);
}
// Return Disk Status
DSTATUS disk_status (BYTE drv) {
(void)drv;
if (sdmmc_check_card(SDMMC_DEFAULT_DEVICE) == SDMMC_INSERTED)
return 0;
else
return STA_NODISK;
// Initialize a Drive
DSTATUS disk_initialize (BYTE drv) {
if (sdmmc_check_card() == SDMMC_NO_CARD)
return STA_NOINIT;
sdmmc_ack_card();
return disk_status(drv);
}
// Return Disk Status
DSTATUS disk_status (BYTE drv) {
(void)drv;
if (sdmmc_check_card() == SDMMC_INSERTED)
return 0;
else
return STA_NODISK;
}
// Read Sector(s)
DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count) {
int i;
(void)drv;
for (i = 0; i < count; i++) {
if (sdmmc_read(SDMMC_DEFAULT_DEVICE, sector+i, 1, buffer) != 0)
return RES_ERROR;
memcpy(buff + i * 512, buffer, 512);
}
int i;
(void)drv;
for (i = 0; i < count; i++) {
if (sdmmc_read(sector+i, 1, buffer) != 0)
return RES_ERROR;
memcpy(buff + i * 512, buffer, 512);
}
return RES_OK;
}
@ -55,13 +55,13 @@ DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count) {
DRESULT disk_write (BYTE drv, const BYTE *buff, DWORD sector, BYTE count) {
int i;
for (i = 0; i < count; i++) {
memcpy(buffer, buff + i * 512, 512);
if(sdmmc_write(SDMMC_DEFAULT_DEVICE, sector + i, 1, buffer) != 0)
return RES_ERROR;
}
for (i = 0; i < count; i++) {
memcpy(buffer, buff + i * 512, 512);
if(sdmmc_write(sector + i, 1, buffer) != 0)
return RES_ERROR;
}
return RES_OK;
}
#endif /* _READONLY */

91
sdhc.c
View File

@ -41,7 +41,6 @@
#define SDHC_COMMAND_TIMEOUT 500
#define SDHC_TRANSFER_TIMEOUT 5000
#define HDEVNAME(hp) ((hp)->sc->sc_dev.dv_xname)
#define sdmmc_delay(t) udelay(t)
#define sdhc_wait_intr(a,b,c) sdhc_wait_intr_debug(__func__, __LINE__, a, b, c)
@ -138,24 +137,6 @@ void sdhc_dump_regs(struct sdhc_host *);
#define DPRINTF(n,s) do {} while(0)
#endif
struct sdmmc_chip_functions sdhc_functions = {
/* host controller reset */
sdhc_host_reset,
/* host controller capabilities */
sdhc_host_ocr,
sdhc_host_maxblklen,
/* card detection */
sdhc_card_detect,
/* bus power and clock frequency */
sdhc_bus_power,
sdhc_bus_clock,
/* command execution */
sdhc_exec_command,
/* card interrupt */
sdhc_card_intr_mask,
sdhc_card_intr_ack
};
/*
* Called by attachment driver. For each SD card slot there is one SD
* host controller standard register set. (1.3)
@ -169,13 +150,12 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
u_int32_t caps;
int error = 1;
strlcpy(sc->sc_dev.dv_xname, "sdhc", 5);
#ifdef SDHC_DEBUG
u_int16_t version;
version = bus_space_read_2(ioh, SDHC_HOST_CTL_VERSION);
gecko_printf("%s: SD Host Specification/Vendor Version ",
sc->sc_dev.dv_xname);
gecko_printf("sdhc: SD Host Specification/Vendor Version ");
switch(SDHC_SPEC_VERSION(version)) {
case 0x00:
gecko_printf("1.0/%u\n", SDHC_VENDOR_VERSION(version));
@ -220,13 +200,12 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
hp->clkbase = SDHC_BASE_FREQ_KHZ(caps);
if (hp->clkbase == 0) {
/* The attachment driver must tell us. */
gecko_printf("%s: base clock frequency unknown\n",
sc->sc_dev.dv_xname);
gecko_printf("sdhc: base clock frequency unknown\n");
goto err;
} else if (hp->clkbase < 10000 || hp->clkbase > 63000) {
/* SDHC 1.0 supports only 10-63 MHz. */
gecko_printf("%s: base clock frequency out of range: %u MHz\n",
sc->sc_dev.dv_xname, hp->clkbase / 1000);
gecko_printf("sdhc: base clock frequency out of range: %u MHz\n",
hp->clkbase / 1000);
goto err;
}
@ -262,10 +241,9 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
*/
bzero(&saa, sizeof(saa));
saa.saa_busname = "sdmmc";
saa.sct = &sdhc_functions;
saa.sch = hp;
hp->sdmmc = sdmmc_attach(&sdhc_functions, hp, "sdhc", ioh);
sdmmc_attach(hp, "sdhc", ioh);
return 0;
@ -463,6 +441,7 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
sdmmc_delay(10);
}
if (timo == 0) {
gecko_printf("sdhc: internal clock never stabilized\n");
error = ETIMEDOUT;
goto ret;
}
@ -510,8 +489,7 @@ sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value)
return 0;
sdmmc_delay(10000);
}
DPRINTF(0,("%s: timeout waiting for %x (state=%d)\n",
HDEVNAME(hp), value, state));
DPRINTF(0,("sdhc: timeout waiting for %x (state=%d)\n", value, state));
return ETIMEDOUT;
}
@ -588,8 +566,8 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
/* Turn off the LED. */
HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d prev state=%d)\n",
HDEVNAME(hp), cmd->c_opcode, cmd->c_flags, cmd->c_error, (cmd->c_resp[0] >> 9) & 15));
DPRINTF(1,("sdhc: cmd %u done (flags=%#x error=%d prev state=%d)\n",
cmd->c_opcode, cmd->c_flags, cmd->c_error, (cmd->c_resp[0] >> 9) & 15));
SET(cmd->c_flags, SCF_ITSDONE);
hp->data_command = 0;
}
@ -603,9 +581,8 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
u_int16_t command;
int error;
DPRINTF(1,("%s: start cmd %u arg=%#x data=%p dlen=%d flags=%#x "
"proc=\"%s\"\n", HDEVNAME(hp), cmd->c_opcode, cmd->c_arg,
cmd->c_data, cmd->c_datalen, cmd->c_flags, ""));
DPRINTF(1,("sdhc: start cmd %u arg=%#x data=%p dlen=%d flags=%#x\n",
cmd->c_opcode, cmd->c_arg, cmd->c_data, cmd->c_datalen, cmd->c_flags));
/*
* The maximum block length for commands should be the minimum
@ -618,15 +595,14 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
blkcount = cmd->c_datalen / blksize;
if (cmd->c_datalen % blksize > 0) {
/* XXX: Split this command. (1.7.4) */
gecko_printf("%s: data not a multiple of %d bytes\n",
HDEVNAME(hp), blksize);
gecko_printf("sdhc: data not a multiple of %d bytes\n", blksize);
return EINVAL;
}
}
/* Check limit imposed by 9-bit block count. (1.7.2) */
if (blkcount > SDHC_BLOCK_COUNT_MAX) {
gecko_printf("%s: too much data\n", HDEVNAME(hp));
gecko_printf("sdhc: too much data\n");
return EINVAL;
}
@ -687,8 +663,8 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
HWRITE4(hp, SDHC_DMA_ADDR, (u32)cmd->c_data);
}
DPRINTF(1,("%s: cmd=%#x mode=%#x blksize=%d blkcount=%d\n",
HDEVNAME(hp), command, mode, blksize, blkcount));
DPRINTF(1,("sdhc: cmd=%#x mode=%#x blksize=%d blkcount=%d\n",
command, mode, blksize, blkcount));
/*
* Start a CPU data transfer. Writing to the high order byte
@ -713,8 +689,7 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
error = 0;
DPRINTF(1,("%s: resp=%#x datalen=%d\n", HDEVNAME(hp),
MMC_R1(cmd->c_resp), cmd->c_datalen));
DPRINTF(1,("resp=%#x datalen=%d\n", MMC_R1(cmd->c_resp), cmd->c_datalen));
if (ISSET(hp->flags, SHF_USE_DMA)) {
for(;;) {
status = sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE |
@ -731,8 +706,7 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
break;
}
if (ISSET(status, SDHC_DMA_INTERRUPT)) {
DPRINTF(2,("%s: dma left:%#x\n", HDEVNAME(hp),
HREAD2(hp, SDHC_BLOCK_COUNT)));
DPRINTF(2,("sdhc: dma left:%#x\n", HREAD2(hp, SDHC_BLOCK_COUNT)));
// this works because our virtual memory
// addresses are equal to the physical memory
// addresses and because we require the target
@ -751,8 +725,8 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
/* XXX I forgot why I wanted to know when this happens :-( */
if ((cmd->c_opcode == 52 || cmd->c_opcode == 53) &&
ISSET(MMC_R1(cmd->c_resp), 0xcb00))
gecko_printf("%s: CMD52/53 error response flags %#x\n",
HDEVNAME(hp), MMC_R1(cmd->c_resp) & 0xff00);
gecko_printf("sdhc: CMD52/53 error response flags %#x\n",
MMC_R1(cmd->c_resp) & 0xff00);
#endif
if (ISSET(cmd->c_flags, SCF_CMD_READ))
ahb_flush_from(AHB_SDHC);
@ -761,8 +735,7 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
cmd->c_error = error;
SET(cmd->c_flags, SCF_ITSDONE);
DPRINTF(1,("%s: data transfer done (error=%d)\n",
HDEVNAME(hp), cmd->c_error));
DPRINTF(1,("sdhc: data transfer done (error=%d)\n", cmd->c_error));
return;
}
@ -772,7 +745,7 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask)
{
int timo;
DPRINTF(1,("%s: software reset reg=%#x\n", HDEVNAME(hp), mask));
DPRINTF(1,("sdhc: software reset reg=%#x\n", mask));
HWRITE1(hp, SDHC_SOFTWARE_RESET, mask);
for (timo = 10; timo > 0; timo--) {
@ -782,8 +755,7 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask)
HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
}
if (timo == 0) {
DPRINTF(1,("%s: timeout reg=%#x\n", HDEVNAME(hp),
HREAD1(hp, SDHC_SOFTWARE_RESET)));
DPRINTF(1,("sdhc: timeout reg=%#x\n", HREAD1(hp, SDHC_SOFTWARE_RESET)));
HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
return (ETIMEDOUT);
}
@ -823,9 +795,9 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m
}
hp->intr_status &= ~status;
DPRINTF(2,("%s: funcname=%s, line=%d, timo=%d status=%#x intr status=%#x error %#x\n",
HDEVNAME(hp), funcname, line, timo, status, hp->intr_status, hp->intr_error_status));
DPRINTF(2,("sdhc: funcname=%s, line=%d, timo=%d status=%#x intr status=%#x error %#x\n",
funcname, line, timo, status, hp->intr_status, hp->intr_error_status));
/* Command timeout has higher priority than command complete. */
if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
gecko_printf("resetting due to error interrupt\n");
@ -877,8 +849,7 @@ sdhc_intr(void *arg)
/* Acknowledge the interrupts we are about to handle. */
HWRITE2(hp, SDHC_NINTR_STATUS, status);
DPRINTF(2,("%s: interrupt status=%d\n", HDEVNAME(hp),
status));
DPRINTF(2,("sdhc: interrupt status=%d\n", status));
/* Claim this interrupt. */
@ -906,8 +877,7 @@ sdhc_intr(void *arg)
HWRITE2(hp, SDHC_EINTR_STATUS, error);
HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, signal);
DPRINTF(2,("%s: error interrupt, status=%d\n",
HDEVNAME(hp), error));
DPRINTF(2,("sdhc: error interrupt, status=%d\n", error));
if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
SDHC_DATA_TIMEOUT_ERROR)) {
@ -923,8 +893,7 @@ sdhc_intr(void *arg)
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
// this pushes a request to the slow queue so that we
// don't block other IRQs.
ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 1,
(u32) hp->sdmmc);
ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 0);
}
#endif
@ -1013,7 +982,7 @@ void sdhc_ipc(volatile ipc_request *req)
{
switch (req->req) {
case IPC_SDHC_DISCOVER:
sdmmc_needs_discover((struct device *)req->args[0]);
sdmmc_needs_discover();
break;
case IPC_SDHC_EXIT:
sdhc_exit();

1
sdhc.h
View File

@ -44,7 +44,6 @@ struct sdhc_host {
};
struct sdhc_softc {
struct device sc_dev;
struct sdhc_host sc_host[SDHC_MAX_HOSTS];
int sc_nhosts;
};

152
sdmmc.c
View File

@ -48,23 +48,18 @@ static struct sdmmc_card cards[SDHC_MAX_HOSTS] MEM2_BSS;
static int n_cards = 0;
struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
sdmmc_chipset_handle_t handle, const char *name, int no)
void sdmmc_attach(sdmmc_chipset_handle_t handle, const char *name, int no)
{
struct sdmmc_card *c;
if (n_cards >= SDHC_MAX_HOSTS) {
gecko_printf("n_cards(%d) >= %d!\n", n_cards, SDHC_MAX_HOSTS);
gecko_printf("starlet is soo going to crash very soon...\n");
// HACK
return (struct device *)-1;
}
c = &cards[n_cards++];
memset(c, 0, sizeof(*c));
c->functions = functions;
c->handle = handle;
c->no = no;
strlcpy(c->name, name, sizeof(c->name));
@ -76,11 +71,8 @@ struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
if (sdhc_card_detect(c->handle)) {
DPRINTF(1, ("card is inserted. starting init sequence.\n"));
sdmmc_needs_discover((struct device *)(n_cards-1));
sdmmc_needs_discover();
}
// HACK
return (struct device *)(n_cards-1);
}
void sdmmc_abort(void) {
@ -94,36 +86,35 @@ void sdmmc_abort(void) {
sdhc_exec_command(&cards[0].handle, &cmd);
}
void sdmmc_needs_discover(struct device *dev)
void sdmmc_needs_discover(void)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
struct sdmmc_command cmd;
u32 ocr;
DPRINTF(0, ("sdmmc: card %d needs discovery.\n", no));
DPRINTF(0, ("sdmmc: card needs discovery.\n"));
sdhc_host_reset(c->handle);
c->new_card = 1;
if (!sdhc_card_detect(c->handle)) {
DPRINTF(1, ("sdmmc: card %d (no longer?) inserted.\n", no));
DPRINTF(1, ("sdmmc: card (no longer?) inserted.\n"));
c->inserted = 0;
return;
}
DPRINTF(1, ("sdmmc: enabling power for %d\n", no));
DPRINTF(1, ("sdmmc: enabling power\n"));
if (sdhc_bus_power(c->handle, 1) != 0) {
gecko_printf("sdmmc: powerup failed for card %d\n", no);
gecko_printf("sdmmc: powerup failed for card\n");
goto out;
}
DPRINTF(1, ("sdmmc: enabling clock for %d\n", no));
DPRINTF(1, ("sdmmc: enabling clock\n"));
if (sdhc_bus_clock(c->handle, SDMMC_DEFAULT_CLOCK) != 0) {
gecko_printf("sdmmc: could not enable clock for card %d\n", no);
gecko_printf("sdmmc: could not enable clock for card\n");
goto out_power;
}
DPRINTF(1, ("sdmmc: sending GO_IDLE_STATE for %d\n", no));
DPRINTF(1, ("sdmmc: sending GO_IDLE_STATE\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_GO_IDLE_STATE;
@ -131,14 +122,12 @@ void sdmmc_needs_discover(struct device *dev)
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: GO_IDLE_STATE failed with %d for card %d\n",
cmd.c_error, no);
gecko_printf("sdmmc: GO_IDLE_STATE failed with %d\n", cmd.c_error);
goto out_clock;
}
DPRINTF(2, ("sdmmc: GO_IDLE_STATE response for %d: %x\n", no,
MMC_R1(cmd.c_resp)));
DPRINTF(2, ("sdmmc: GO_IDLE_STATE response: %x\n", MMC_R1(cmd.c_resp)));
DPRINTF(1, ("sdmmc: sending SEND_IF_COND for %d\n", no));
DPRINTF(1, ("sdmmc: sending SEND_IF_COND\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = SD_SEND_IF_COND;
@ -181,7 +170,7 @@ void sdmmc_needs_discover(struct device *dev)
break;
}
if (!ISSET(cmd.c_resp[0], MMC_OCR_MEM_READY)) {
gecko_printf("sdmmc: card %d failed to powerup.\n", no);
gecko_printf("sdmmc: card failed to powerup.\n");
goto out_power;
}
@ -199,8 +188,7 @@ void sdmmc_needs_discover(struct device *dev)
cmd.c_flags = SCF_RSP_R2;
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_ALL_SEND_CID failed with %d for card %d\n",
cmd.c_error, no);
gecko_printf("sdmmc: MMC_ALL_SEND_CID failed with %d\n", cmd.c_error);
goto out_clock;
}
@ -217,8 +205,7 @@ void sdmmc_needs_discover(struct device *dev)
cmd.c_flags = SCF_RSP_R6;
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: SD_SEND_RCA failed with %d for card %d\n",
cmd.c_error, no);
gecko_printf("sdmmc: SD_SEND_RCA failed with %d\n", cmd.c_error);
goto out_clock;
}
@ -234,8 +221,7 @@ void sdmmc_needs_discover(struct device *dev)
cmd.c_flags = SCF_RSP_R2;
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_SEND_CSD failed for "
"card %d with %d\n", no, cmd.c_error);
gecko_printf("sdmmc: MMC_SEND_CSD failed with %d\n", cmd.c_error);
goto out_power;
}
@ -272,7 +258,7 @@ void sdmmc_needs_discover(struct device *dev)
c->num_sectors = (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len) / 512;
}
sdmmc_select(dev);
sdmmc_select();
DPRINTF(2, ("sdmmc: MMC_SET_BLOCKLEN\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_SET_BLOCKLEN;
@ -280,63 +266,25 @@ void sdmmc_needs_discover(struct device *dev)
cmd.c_flags = SCF_RSP_R1;
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_SET_BLOCKLEN failed with %d for card %d\n",
cmd.c_error, no);
gecko_printf("sdmmc: MMC_SET_BLOCKLEN failed with %d\n", cmd.c_error);
c->inserted = c->selected = 0;
goto out_clock;
}
return;
out_clock:
sdhc_bus_clock(c->handle, SDMMC_SDCLK_OFF);
out_power:
sdhc_bus_power(c->handle, 0);
out:
return;
#if 0
// struct sdmmc_task c_task; /* task queue entry */
u_int16_t c_opcode; /* SD or MMC command index */
u_int32_t c_arg; /* SD/MMC command argument */
sdmmc_response c_resp; /* response buffer */
void *c_data; /* buffer to send or read into */
int c_datalen; /* length of data buffer */
int c_blklen; /* block length */
int c_flags; /* see below */
#define SCF_ITSDONE 0x0001 /* command is complete */
#define SCF_CMD(flags) ((flags) & 0x00f0)
#define SCF_CMD_AC 0x0000
#define SCF_CMD_ADTC 0x0010
#define SCF_CMD_BC 0x0020
#define SCF_CMD_BCR 0x0030
#define SCF_CMD_READ 0x0040 /* read command (data expected) */
#define SCF_RSP_BSY 0x0100
#define SCF_RSP_136 0x0200
#define SCF_RSP_CRC 0x0400
#define SCF_RSP_IDX 0x0800
#define SCF_RSP_PRESENT 0x1000
/* response types */
#define SCF_RSP_R0 0 /* none */
#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R2 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_136)
#define SCF_RSP_R3 (SCF_RSP_PRESENT)
#define SCF_RSP_R4 (SCF_RSP_PRESENT)
#define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
int c_error; /* errno value on completion */
/* Host controller owned fields for data xfer in progress */
int c_resid; /* remaining I/O */
u_char *c_buf; /* remaining data */
#endif
}
int sdmmc_select(struct device *dev)
int sdmmc_select(void)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
struct sdmmc_command cmd;
DPRINTF(2, ("sdmmc: MMC_SELECT_CARD\n"));
@ -350,8 +298,7 @@ int sdmmc_select(struct device *dev)
// gecko_printf("present state = %x\n", HREAD4(hp, SDHC_PRESENT_STATE));
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_SELECT card failed with %d for %d.\n",
cmd.c_error, no);
gecko_printf("sdmmc: MMC_SELECT card failed with %d.\n", cmd.c_error);
return -1;
}
@ -359,10 +306,9 @@ int sdmmc_select(struct device *dev)
return 0;
}
int sdmmc_check_card(struct device *dev)
int sdmmc_check_card(void)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
if (c->inserted == 0)
return SDMMC_NO_CARD;
@ -373,10 +319,9 @@ int sdmmc_check_card(struct device *dev)
return SDMMC_INSERTED;
}
int sdmmc_ack_card(struct device *dev)
int sdmmc_ack_card(void)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
if (c->new_card == 1) {
c->new_card = 0;
@ -386,10 +331,9 @@ int sdmmc_ack_card(struct device *dev)
return -1;
}
int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
int sdmmc_read(u32 blk_start, u32 blk_count, void *data)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
struct sdmmc_command cmd;
gecko_printf("%s(%u, %u, %p)\n", __FUNCTION__, blk_start, blk_count, data);
@ -399,7 +343,7 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
}
if (c->selected == 0) {
if (sdmmc_select(dev) < 0) {
if (sdmmc_select() < 0) {
gecko_printf("sdmmc: READ: cannot select card.\n");
return -1;
}
@ -424,8 +368,7 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed for "
"card %d with %d\n", no, cmd.c_error);
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed with %d\n", cmd.c_error);
return -1;
}
DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE done\n"));
@ -434,10 +377,9 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
}
#ifndef LOADER
int sdmmc_write(struct device *dev, u32 blk_start, u32 blk_count, void *data)
int sdmmc_write(u32 blk_start, u32 blk_count, void *data)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
struct sdmmc_command cmd;
if (c->inserted == 0) {
@ -446,7 +388,7 @@ int sdmmc_write(struct device *dev, u32 blk_start, u32 blk_count, void *data)
}
if (c->selected == 0) {
if (sdmmc_select(dev) < 0) {
if (sdmmc_select() < 0) {
gecko_printf("sdmmc: READ: cannot select card.\n");
return -1;
}
@ -471,8 +413,7 @@ int sdmmc_write(struct device *dev, u32 blk_start, u32 blk_count, void *data)
sdhc_exec_command(c->handle, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed for "
"card %d with %d\n", no, cmd.c_error);
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed with %d\n", cmd.c_error);
return -1;
}
DPRINTF(2, ("sdmmc: MMC_WRITE_BLOCK_MULTIPLE done\n"));
@ -480,10 +421,9 @@ int sdmmc_write(struct device *dev, u32 blk_start, u32 blk_count, void *data)
return 0;
}
int sdmmc_get_sectors(struct device *dev)
int sdmmc_get_sectors(void)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_card *c = &cards[0];
if (c->inserted == 0) {
gecko_printf("sdmmc: READ: no card inserted.\n");
@ -507,12 +447,11 @@ void sdmmc_ipc(volatile ipc_request *req)
int ret;
switch (req->req) {
case IPC_SDMMC_ACK:
ret = sdmmc_ack_card(SDMMC_DEFAULT_DEVICE);
ret = sdmmc_ack_card();
ipc_post(req->code, req->tag, 1, ret);
break;
case IPC_SDMMC_READ:
ret = sdmmc_read(SDMMC_DEFAULT_DEVICE, req->args[0],
req->args[1], (void *)req->args[2]);
ret = sdmmc_read(req->args[0], req->args[1], (void *)req->args[2]);
dc_flushrange((void *)req->args[2],
req->args[1]*SDMMC_DEFAULT_BLOCKLEN);
ipc_post(req->code, req->tag, 1, ret);
@ -520,17 +459,16 @@ void sdmmc_ipc(volatile ipc_request *req)
case IPC_SDMMC_WRITE:
dc_invalidaterange((void *)req->args[2],
req->args[1]*SDMMC_DEFAULT_BLOCKLEN);
ret = sdmmc_write(SDMMC_DEFAULT_DEVICE, req->args[0],
req->args[1], (void *)req->args[2]);
ret = sdmmc_write(req->args[0], req->args[1], (void *)req->args[2]);
ipc_post(req->code, req->tag, 1, ret);
break;
case IPC_SDMMC_STATE:
ipc_post(req->code, req->tag, 1,
sdmmc_check_card(SDMMC_DEFAULT_DEVICE));
sdmmc_check_card());
break;
case IPC_SDMMC_SIZE:
ipc_post(req->code, req->tag, 1,
sdmmc_get_sectors(SDMMC_DEFAULT_DEVICE));
sdmmc_get_sectors());
break;
}
}

63
sdmmc.h
View File

@ -18,50 +18,6 @@ struct sdmmc_command;
typedef struct sdmmc_chip_functions *sdmmc_chipset_tag_t;
typedef void *sdmmc_chipset_handle_t;
struct sdmmc_chip_functions {
/* host controller reset */
int (*host_reset)(sdmmc_chipset_handle_t);
/* host capabilities */
u_int32_t (*host_ocr)(sdmmc_chipset_handle_t);
int (*host_maxblklen)(sdmmc_chipset_handle_t);
/* card detection */
int (*card_detect)(sdmmc_chipset_handle_t);
/* bus power and clock frequency */
int (*bus_power)(sdmmc_chipset_handle_t, u_int32_t);
int (*bus_clock)(sdmmc_chipset_handle_t, int);
/* command execution */
void (*exec_command)(sdmmc_chipset_handle_t,
struct sdmmc_command *);
/* card interrupt */
void (*card_intr_mask)(sdmmc_chipset_handle_t, int);
void (*card_intr_ack)(sdmmc_chipset_handle_t);
};
/* host controller reset */
#define sdmmc_chip_host_reset(tag, handle) \
((tag)->host_reset((handle)))
/* host capabilities */
#define sdmmc_chip_host_ocr(tag, handle) \
((tag)->host_ocr((handle)))
#define sdmmc_chip_host_maxblklen(tag, handle) \
((tag)->host_maxblklen((handle)))
/* card detection */
#define sdmmc_chip_card_detect(tag, handle) \
((tag)->card_detect((handle)))
/* bus power and clock frequency */
#define sdmmc_chip_bus_power(tag, handle, ocr) \
((tag)->bus_power((handle), (ocr)))
#define sdmmc_chip_bus_clock(tag, handle, freq) \
((tag)->bus_clock((handle), (freq)))
/* command execution */
#define sdmmc_chip_exec_command(tag, handle, cmdp) \
((tag)->exec_command((handle), (cmdp)))
/* card interrupt */
#define sdmmc_chip_card_intr_mask(tag, handle, enable) \
((tag)->card_intr_mask((handle), (enable)))
#define sdmmc_chip_card_intr_ack(tag, handle) \
((tag)->card_intr_ack((handle)))
/* clock frequencies for sdmmc_chip_bus_clock() */
#define SDMMC_SDCLK_OFF 0
#define SDMMC_SDCLK_400KHZ 400
@ -189,7 +145,6 @@ struct sdmmc_function {
#define SFF_SDHC 0x0002 /* SD High Capacity card */
/* SD card I/O function members */
int number; /* I/O function number or -1 */
struct device *child; /* function driver */
struct sdmmc_cis cis; /* decoded CIS */
/* SD/MMC memory card members */
struct sdmmc_csd csd; /* decoded CSD value */
@ -201,8 +156,6 @@ struct sdmmc_function {
* Structure describing a single SD/MMC/SDIO card slot.
*/
struct sdmmc_softc {
struct device sc_dev; /* base device */
#define SDMMCDEVNAME(sc) ((sc)->sc_dev.dv_xname)
sdmmc_chipset_tag_t sct; /* host controller chipset tag */
sdmmc_chipset_handle_t sch; /* host controller chipset handle */
#define SMF_SD_MODE 0x0001 /* host in SD mode (MMC otherwise) */
@ -248,16 +201,12 @@ struct sdmmc_attach_args {
#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,
sdmmc_chipset_handle_t handle, const char *name, int no);
void sdmmc_needs_discover(struct device *dev);
int sdmmc_select(struct device *dev);
int sdmmc_check_card(struct device *dev);
int sdmmc_ack_card(struct device *dev);
int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data);
void sdmmc_attach(sdmmc_chipset_handle_t handle, const char *name, int no);
void sdmmc_needs_discover(void);
int sdmmc_select(void);
int sdmmc_check_card(void);
int sdmmc_ack_card(void);
int sdmmc_read(u32 blk_start, u32 blk_count, void *data);
#ifdef CAN_HAZ_IPC
void sdmmc_ipc(volatile ipc_request *req);
#endif