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:
parent
23907fa712
commit
de291cdb60
6 changed files with 184 additions and 13 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
161
drivers/mmc/mmchost_dummy.c
Normal 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]);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue