minix/drivers/mmc/mmchost_dummy.c
Kees Jongenburger 061fed753e arm:mmc driver refactor and timeout fix for BeagleBoneBlack.
When we send MMC commads that contain data the controller provides no
description of the order of events and we need to be able to send data
from and to the controller "when needed". Changed the code to react
on buffer read and buffer write ready based on interrupts.

Change-Id: I60c9140bf0e45b74be6475054564d4e1bd89f21e
2013-06-24 09:12:10 +02:00

170 lines
3.6 KiB
C

/* kernel headers */
#include <minix/blockdriver.h>
#include <minix/minlib.h>
#include <minix/log.h>
/* usr headers */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <unistd.h>
/* local headers */
#include "mmchost.h"
#include "sdmmcreg.h"
/*
* Define a structure to be used for logging
*/
static struct log log = {
.name = "mmc_host_memory",
.log_level = LEVEL_INFO,
.log_func = default_log
};
/* This is currently a dummy driver using an in-memory structure */
#define DUMMY_SIZE_IN_BLOCKS 0xFFFFFu
#define DUMMY_BLOCK_SIZE 512
static char *dummy_data = NULL;
static struct sd_card *
init_dummy_sdcard(struct sd_slot *slot)
{
int i;
struct sd_card *card;
assert(slot != NULL);
log_info(&log, "Using a dummy card \n");
if (dummy_data == NULL) {
dummy_data = malloc(DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS);
if (dummy_data == NULL) {
panic
("Failed to allocate data for dummy mmc driver\n");
}
}
card = &slot->card;
memset(card, 0, sizeof(struct sd_card));
card->slot = slot;
for (i = 0; i < MINOR_PER_DISK + PARTITONS_PER_DISK; i++) {
card->part[i].dv_base = 0;
card->part[i].dv_size = 0;
}
for (i = 0; i < PARTITONS_PER_DISK * SUBPARTITION_PER_PARTITION; i++) {
card->subpart[i].dv_base = 0;
card->subpart[i].dv_size = 0;
}
card->part[0].dv_base = 0;
card->part[0].dv_size = DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS;
return card;
}
int
dummy_host_init(struct mmc_host *host)
{
return 0;
}
void
dummy_set_log_level(int level)
{
if (level >= 0 && level <= 4) {
log.log_level = level;
}
}
int
dummy_host_set_instance(struct mmc_host *host, int instance)
{
log_info(&log, "Using instance number %d\n", instance);
if (instance != 0) {
return EIO;
}
return OK;
}
int
dummy_host_reset(struct mmc_host *host)
{
return 0;
}
int
dummy_card_detect(struct sd_slot *slot)
{
return 1;
}
struct sd_card *
dummy_card_initialize(struct sd_slot *slot)
{
slot->card.blk_size = DUMMY_BLOCK_SIZE;
slot->card.blk_count = DUMMY_SIZE_IN_BLOCKS;
slot->card.state = SD_MODE_DATA_TRANSFER_MODE;
memset(slot->card.part, 0, sizeof(slot->card.part));
memset(slot->card.subpart, 0, sizeof(slot->card.subpart));
slot->card.part[0].dv_base = 0;
slot->card.part[0].dv_size = DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS;
return &slot->card;
}
int
dummy_card_release(struct sd_card *card)
{
assert(card->open_ct == 1);
card->open_ct--;
card->state = SD_MODE_UNINITIALIZED;
/* TODO:Set card state */
return OK;
}
/* read count blocks into existing buf */
int
dummy_host_read(struct sd_card *card,
uint32_t blknr, uint32_t count, unsigned char *buf)
{
memcpy(buf, &dummy_data[blknr * DUMMY_BLOCK_SIZE],
count * DUMMY_BLOCK_SIZE);
return OK;
}
/* write count blocks */
int
dummy_host_write(struct sd_card *card,
uint32_t blknr, uint32_t count, unsigned char *buf)
{
memcpy(&dummy_data[blknr * DUMMY_BLOCK_SIZE], buf,
count * DUMMY_BLOCK_SIZE);
return OK;
}
void
host_initialize_host_structure_dummy(struct mmc_host *host)
{
/* Initialize the basic data structures host slots and cards */
int i;
host->host_set_instance = dummy_host_set_instance;
host->host_init = dummy_host_init;
host->set_log_level = dummy_set_log_level;
host->host_reset = dummy_host_reset;
host->card_detect = dummy_card_detect;
host->card_initialize = dummy_card_initialize;
host->card_release = dummy_card_release;
host->read = dummy_host_read;
host->write = dummy_host_write;
/* initialize data structures */
for (i = 0; i < sizeof(host->slot) / sizeof(host->slot[0]); i++) {
// @TODO set initial card and slot state
host->slot[i].host = host;
host->slot[i].card.slot = &host->slot[i];
}
init_dummy_sdcard(&host->slot[0]);
}