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,
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);
--- /dev/null
+/* 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]);
+}