From: Kees Jongenburger Date: Fri, 19 Oct 2012 09:09:52 +0000 (+0200) Subject: mmc:driver development added dummy driver. X-Git-Tag: v3.2.1~266 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/dnssec-keyfromlabel.html?a=commitdiff_plain;h=de291cdb6037bcf8106adadcee2ff1e21951a2e7;p=minix.git 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 --- diff --git a/drivers/Makefile b/drivers/Makefile index 774f65e86..5f5b56d01 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -12,7 +12,7 @@ SUBDIR= at_wini floppy log tty pci ramdisk memory # memory driver must be last for ramdisk image 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 \ memory ramdisk .endif diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 52afdb272..2e8f9df89 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -1,6 +1,6 @@ # Makefile for the mmc driver. 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} LDADD+= -lblockdriver -lsys diff --git a/drivers/mmc/mmcblk.c b/drivers/mmc/mmcblk.c index 829566beb..b2ef7f9e7 100644 --- a/drivers/mmc/mmcblk.c +++ b/drivers/mmc/mmcblk.c @@ -96,17 +96,29 @@ static struct blockdriver mmc_driver = { static int 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 * log_level=[0-4] (NONE,WARNING,INFO,DEBUG,TRACE) instance=[0-3] * instance/bus number to use for this driver Passing these arguments * is done when starting the driver using the service command in the - * following way service up /sbin/mmcblk -args "log_level=2 - * instance=1" */ + * following way service up /sbin/mmc -args "log_level=2 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; - + /* 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. */ v = 0; if (env_parse("log_level", "d", 0, &v, LEVEL_NONE, @@ -642,9 +654,6 @@ set_log_level(int level) int 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 */ env_setargs(argc, argv); diff --git a/drivers/mmc/mmchost.h b/drivers/mmc/mmchost.h index 081fad2d5..37e44c4fa 100644 --- a/drivers/mmc/mmchost.h +++ b/drivers/mmc/mmchost.h @@ -145,4 +145,5 @@ struct mmc_command #endif /* 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); diff --git a/drivers/mmc/mmchost_dummy.c b/drivers/mmc/mmchost_dummy.c new file mode 100644 index 000000000..3d560abae --- /dev/null +++ b/drivers/mmc/mmchost_dummy.c @@ -0,0 +1,161 @@ +/* kernel headers */ +#include + +/* usr headers */ +#include +#include +#include +#include + +/* 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]); +} diff --git a/drivers/mmc/mmchost_mmchs.c b/drivers/mmc/mmchost_mmchs.c index 0445c2184..cbf5a8384 100644 --- a/drivers/mmc/mmchost_mmchs.c +++ b/drivers/mmc/mmchost_mmchs.c @@ -773,7 +773,7 @@ mmchs_card_release(struct sd_card *card) } 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 */ int i;