171 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* kernel headers */
 | |
| #include <minix/blockdriver.h>
 | |
| #include <minix/minlib.h>
 | |
| #include <minix/log.h>
 | |
| 
 | |
| /* usr headers */
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdarg.h>
 | |
| #include <assert.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| /* local headers */
 | |
| #include "mmchost.h"
 | |
| #include "sdmmcreg.h"
 | |
| 
 | |
| /*
 | |
|  * Define a structure to be used for logging
 | |
|  */
 | |
| static struct log log = {
 | |
| 	.name = "mmc_host_memory",
 | |
| 	.log_level = LEVEL_INFO,
 | |
| 	.log_func = default_log
 | |
| };
 | |
| 
 | |
| /* This is currently a dummy driver using an in-memory structure */
 | |
| #define DUMMY_SIZE_IN_BLOCKS 0xFFFFFu
 | |
| #define DUMMY_BLOCK_SIZE 512
 | |
| static char *dummy_data = NULL;
 | |
| 
 | |
| static struct sd_card *
 | |
| init_dummy_sdcard(struct sd_slot *slot)
 | |
| {
 | |
| 	int i;
 | |
| 	struct sd_card *card;
 | |
| 
 | |
| 	assert(slot != NULL);
 | |
| 
 | |
| 	log_info(&log, "Using a dummy card \n");
 | |
| 	if (dummy_data == NULL) {
 | |
| 		dummy_data = malloc(DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS);
 | |
| 		if (dummy_data == NULL) {
 | |
| 			panic
 | |
| 			    ("Failed to allocate data for dummy mmc driver\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)
 | |
| {
 | |
| 	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]);
 | |
| }
 | 
