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