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
					
				| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
							
								
								
									
										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 | ||||
| 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; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Kees Jongenburger
						Kees Jongenburger