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
This commit is contained in:
Kees Jongenburger 2012-10-19 11:09:52 +02:00
parent 23907fa712
commit de291cdb60
6 changed files with 184 additions and 13 deletions

View file

@ -12,7 +12,7 @@ SUBDIR= at_wini floppy log tty pci ramdisk memory
# memory driver must be last for ramdisk image # memory driver must be last for ramdisk image
SUBDIR+= ahci amddev atl2 at_wini audio dec21140A dp8390 dpeth \ SUBDIR+= ahci amddev atl2 at_wini audio dec21140A dp8390 dpeth \
e1000 fbd filter floppy fxp hello lance log orinoco pci printer \ e1000 fbd filter floppy fxp hello lance log mmc orinoco pci printer \
random readclock rtl8139 rtl8169 ti1225 tty vbox acpi \ random readclock rtl8139 rtl8169 ti1225 tty vbox acpi \
memory ramdisk memory ramdisk
.endif .endif

View file

@ -1,6 +1,6 @@
# Makefile for the mmc driver. # Makefile for the mmc driver.
PROG= mmc PROG= mmc
SRCS= mmcblk.c mmchost_mmchs.c mmclog.h sdhcreg.h sdmmcreg.h SRCS= mmcblk.c mmchost_mmchs.c mmchost_dummy.c mmclog.h sdhcreg.h sdmmcreg.h
DPADD+= ${LIBBLOCKDRIVER} ${LIBSYS} DPADD+= ${LIBBLOCKDRIVER} ${LIBSYS}
LDADD+= -lblockdriver -lsys LDADD+= -lblockdriver -lsys

View file

@ -96,17 +96,29 @@ static struct blockdriver mmc_driver = {
static int static int
apply_env() apply_env()
{ {
#if 0
/* @TODO: re-enable this function when __aeabi_idiv will be present
* The following code(env_parse) uses strtol.c and needs __aeabi_idiv */
/* apply the env setting passed to this driver parameters accepted /* apply the env setting passed to this driver parameters accepted
* log_level=[0-4] (NONE,WARNING,INFO,DEBUG,TRACE) instance=[0-3] * log_level=[0-4] (NONE,WARNING,INFO,DEBUG,TRACE) instance=[0-3]
* instance/bus number to use for this driver Passing these arguments * instance/bus number to use for this driver Passing these arguments
* is done when starting the driver using the service command in the * is done when starting the driver using the service command in the
* following way service up /sbin/mmcblk -args "log_level=2 * following way service up /sbin/mmc -args "log_level=2 instance=1"
* instance=1" */ * -dev /dev/c1d0 */
char driver[16];
memset(driver, '\0', 16);
(void) env_get_param("driver", driver, 16);
if (strlen(driver) == 0
|| strncmp(driver, "mmchs", strlen("mmchs") + 1) == 0) {
/* early init of host mmc host controller. This code should
* depend on knowing the hardware that is running bellow. */
host_initialize_host_structure_mmchs(&host);
} else if (strncmp(driver, "dummy", strlen("dummy") + 1) == 0) {
host_initialize_host_structure_dummy(&host);
} else {
mmc_log_warn(&log, "Unknown driver %s\n", driver);
}
#if 0
long v; long v;
/* The following code(env_parse) uses strtol.c and needs __aeabi_idiv */
/* @TODO: re-enable this function when __aeabi_idiv will be present */
/* Initialize the verbosity level. */ /* Initialize the verbosity level. */
v = 0; v = 0;
if (env_parse("log_level", "d", 0, &v, LEVEL_NONE, if (env_parse("log_level", "d", 0, &v, LEVEL_NONE,
@ -642,9 +654,6 @@ set_log_level(int level)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
/* early init of host mmc host controller. This code should depend on
* knowing the hardware that is running bellow. */
host_initialize_host_structure(&host);
/* Set and apply the environment */ /* Set and apply the environment */
env_setargs(argc, argv); env_setargs(argc, argv);

View file

@ -145,4 +145,5 @@ struct mmc_command
#endif #endif
/* Hack done for driver registration */ /* Hack done for driver registration */
void host_initialize_host_structure(struct mmc_host *host); void host_initialize_host_structure_mmchs(struct mmc_host *host);
void host_initialize_host_structure_dummy(struct mmc_host *host);

161
drivers/mmc/mmchost_dummy.c Normal file
View file

@ -0,0 +1,161 @@
/* 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]);
}

View file

@ -773,7 +773,7 @@ mmchs_card_release(struct sd_card *card)
} }
void void
host_initialize_host_structure(struct mmc_host *host) host_initialize_host_structure_mmchs(struct mmc_host *host)
{ {
/* Initialize the basic data structures host slots and cards */ /* Initialize the basic data structures host slots and cards */
int i; int i;