1 /* kernel headers */
2 #include <minix/blockdriver.h>
3 #include <minix/minlib.h>
4 #include <minix/log.h>
5 
6 /* usr headers */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <assert.h>
11 #include <unistd.h>
12 
13 /* local headers */
14 #include "mmchost.h"
15 #include "sdmmcreg.h"
16 
17 /*
18  * Define a structure to be used for logging
19  */
20 static struct log log = {
21 	.name = "mmc_host_memory",
22 	.log_level = LEVEL_INFO,
23 	.log_func = default_log
24 };
25 
26 /* This is currently a dummy driver using an in-memory structure */
27 #define DUMMY_SIZE_IN_BLOCKS 0xFFFFFu
28 #define DUMMY_BLOCK_SIZE 512
29 static char *dummy_data = NULL;
30 
31 static struct sd_card *
init_dummy_sdcard(struct sd_slot * slot)32 init_dummy_sdcard(struct sd_slot *slot)
33 {
34 	int i;
35 	struct sd_card *card;
36 
37 	assert(slot != NULL);
38 
39 	log_info(&log, "Using a dummy card \n");
40 	if (dummy_data == NULL) {
41 		dummy_data = malloc(DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS);
42 		if (dummy_data == NULL) {
43 			panic
44 			    ("Failed to allocate data for dummy mmc driver\n");
45 		}
46 	}
47 
48 	card = &slot->card;
49 	memset(card, 0, sizeof(struct sd_card));
50 	card->slot = slot;
51 
52 	for (i = 0; i < MINOR_PER_DISK + PARTITONS_PER_DISK; i++) {
53 		card->part[i].dv_base = 0;
54 		card->part[i].dv_size = 0;
55 	}
56 
57 	for (i = 0; i < PARTITONS_PER_DISK * SUBPARTITION_PER_PARTITION; i++) {
58 		card->subpart[i].dv_base = 0;
59 		card->subpart[i].dv_size = 0;
60 	}
61 
62 	card->part[0].dv_base = 0;
63 	card->part[0].dv_size = DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS;
64 	return card;
65 }
66 
67 int
dummy_host_init(struct mmc_host * host)68 dummy_host_init(struct mmc_host *host)
69 {
70 	return 0;
71 }
72 
73 void
dummy_set_log_level(int level)74 dummy_set_log_level(int level)
75 {
76 	if (level >= 0 && level <= 4) {
77 		log.log_level = level;
78 	}
79 }
80 
81 int
dummy_host_set_instance(struct mmc_host * host,int instance)82 dummy_host_set_instance(struct mmc_host *host, int instance)
83 {
84 	log_info(&log, "Using instance number %d\n", instance);
85 	if (instance != 0) {
86 		return EIO;
87 	}
88 	return OK;
89 }
90 
91 int
dummy_host_reset(struct mmc_host * host)92 dummy_host_reset(struct mmc_host *host)
93 {
94 	return 0;
95 }
96 
97 int
dummy_card_detect(struct sd_slot * slot)98 dummy_card_detect(struct sd_slot *slot)
99 {
100 	return 1;
101 }
102 
103 struct sd_card *
dummy_card_initialize(struct sd_slot * slot)104 dummy_card_initialize(struct sd_slot *slot)
105 {
106 	slot->card.blk_size = DUMMY_BLOCK_SIZE;
107 	slot->card.blk_count = DUMMY_SIZE_IN_BLOCKS;
108 	slot->card.state = SD_MODE_DATA_TRANSFER_MODE;
109 
110 	memset(slot->card.part, 0, sizeof(slot->card.part));
111 	memset(slot->card.subpart, 0, sizeof(slot->card.subpart));
112 	slot->card.part[0].dv_base = 0;
113 	slot->card.part[0].dv_size = DUMMY_BLOCK_SIZE * DUMMY_SIZE_IN_BLOCKS;
114 	return &slot->card;
115 }
116 
117 int
dummy_card_release(struct sd_card * card)118 dummy_card_release(struct sd_card *card)
119 {
120 	assert(card->open_ct == 1);
121 	card->open_ct--;
122 	card->state = SD_MODE_UNINITIALIZED;
123 	/* TODO:Set card state */
124 	return OK;
125 }
126 
127 /* read count blocks into existing buf */
128 int
dummy_host_read(struct sd_card * card,uint32_t blknr,uint32_t count,unsigned char * buf)129 dummy_host_read(struct sd_card *card,
130     uint32_t blknr, uint32_t count, unsigned char *buf)
131 {
132 	memcpy(buf, &dummy_data[blknr * DUMMY_BLOCK_SIZE],
133 	    count * DUMMY_BLOCK_SIZE);
134 	return OK;
135 }
136 
137 /* write count blocks */
138 int
dummy_host_write(struct sd_card * card,uint32_t blknr,uint32_t count,unsigned char * buf)139 dummy_host_write(struct sd_card *card,
140     uint32_t blknr, uint32_t count, unsigned char *buf)
141 {
142 	memcpy(&dummy_data[blknr * DUMMY_BLOCK_SIZE], buf,
143 	    count * DUMMY_BLOCK_SIZE);
144 	return OK;
145 }
146 
147 void
host_initialize_host_structure_dummy(struct mmc_host * host)148 host_initialize_host_structure_dummy(struct mmc_host *host)
149 {
150 	/* Initialize the basic data structures host slots and cards */
151 	int i;
152 
153 	host->host_set_instance = dummy_host_set_instance;
154 	host->host_init = dummy_host_init;
155 	host->set_log_level = dummy_set_log_level;
156 	host->host_reset = dummy_host_reset;
157 	host->card_detect = dummy_card_detect;
158 	host->card_initialize = dummy_card_initialize;
159 	host->card_release = dummy_card_release;
160 	host->read = dummy_host_read;
161 	host->write = dummy_host_write;
162 
163 	/* initialize data structures */
164 	for (i = 0; i < sizeof(host->slot) / sizeof(host->slot[0]); i++) {
165 		// @TODO set initial card and slot state
166 		host->slot[i].host = host;
167 		host->slot[i].card.slot = &host->slot[i];
168 	}
169 	init_dummy_sdcard(&host->slot[0]);
170 }
171