minix/drivers/mmc/mmchost_dummy.c
Kees Jongenburger de291cdb60 mmc:driver development added dummy driver.
* Add dummy driver to allow independent testing of mmcblk.
* Always build the mmc driver to prevent breakage.
* Allow to specify the mmc driver to be used at load time.

Change-Id: I4e14b912fb8f3612e252864b53733968b23ac023
2012-10-19 14:55:03 +02:00

162 lines
3.5 KiB
C

/* kernel headers */
#include <minix/blockdriver.h>
/* usr headers */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
/* local headers */
#include "mmclog.h"
#include "mmchost.h"
#include "sdmmcreg.h"
/*
* Define a structure to be used for logging
*/
static struct mmclog log = {
.name = "mmc_host_memory",
.log_level = LEVEL_TRACE,
.log_func = default_log
};
/* This is currently a dummy driver using an in-memory structure */
#define DUMMY_SIZE_IN_BLOCKS 0xFFFu
#define DUMMY_BLOCK_SIZE 512
static char dummy_data[DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS];
static struct sd_card *
init_dummy_sdcard(struct sd_slot *slot)
{
int i;
struct sd_card *card;
assert(slot != NULL);
mmc_log_info(&log, "Using a dummy card \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)
{
mmc_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]);
}