Statistics
| Branch: | Revision:

root / hw / sd.c @ 257514dd

History | View | Annotate | Download (40.9 kB)

1 5fafdf24 ths
/*
2 a1bb27b1 pbrook
 * SD Memory Card emulation as defined in the "SD Memory Card Physical
3 a1bb27b1 pbrook
 * layer specification, Version 1.10."
4 a1bb27b1 pbrook
 *
5 a1bb27b1 pbrook
 * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
6 a1bb27b1 pbrook
 * Copyright (c) 2007 CodeSourcery
7 a1bb27b1 pbrook
 *
8 a1bb27b1 pbrook
 * Redistribution and use in source and binary forms, with or without
9 a1bb27b1 pbrook
 * modification, are permitted provided that the following conditions
10 a1bb27b1 pbrook
 * are met:
11 a1bb27b1 pbrook
 *
12 a1bb27b1 pbrook
 * 1. Redistributions of source code must retain the above copyright
13 a1bb27b1 pbrook
 *    notice, this list of conditions and the following disclaimer.
14 a1bb27b1 pbrook
 * 2. Redistributions in binary form must reproduce the above copyright
15 a1bb27b1 pbrook
 *    notice, this list of conditions and the following disclaimer in
16 a1bb27b1 pbrook
 *    the documentation and/or other materials provided with the
17 a1bb27b1 pbrook
 *    distribution.
18 a1bb27b1 pbrook
 *
19 a1bb27b1 pbrook
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
20 a1bb27b1 pbrook
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 a1bb27b1 pbrook
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 a1bb27b1 pbrook
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR
23 a1bb27b1 pbrook
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 a1bb27b1 pbrook
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 a1bb27b1 pbrook
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 a1bb27b1 pbrook
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 a1bb27b1 pbrook
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 a1bb27b1 pbrook
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 a1bb27b1 pbrook
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 a1bb27b1 pbrook
 */
31 a1bb27b1 pbrook
32 a1bb27b1 pbrook
#include "sd.h"
33 a1bb27b1 pbrook
34 a1bb27b1 pbrook
//#define DEBUG_SD 1
35 a1bb27b1 pbrook
36 a1bb27b1 pbrook
#ifdef DEBUG_SD
37 a1bb27b1 pbrook
#define DPRINTF(fmt, args...) \
38 a1bb27b1 pbrook
do { printf("SD: " fmt , ##args); } while (0)
39 a1bb27b1 pbrook
#else
40 a1bb27b1 pbrook
#define DPRINTF(fmt, args...) do {} while(0)
41 a1bb27b1 pbrook
#endif
42 a1bb27b1 pbrook
43 a1bb27b1 pbrook
typedef enum {
44 a1bb27b1 pbrook
    sd_r0 = 0,    /* no response */
45 a1bb27b1 pbrook
    sd_r1,        /* normal response command */
46 a1bb27b1 pbrook
    sd_r2_i,      /* CID register */
47 a1bb27b1 pbrook
    sd_r2_s,      /* CSD register */
48 a1bb27b1 pbrook
    sd_r3,        /* OCR register */
49 a1bb27b1 pbrook
    sd_r6 = 6,    /* Published RCA response */
50 a1bb27b1 pbrook
    sd_r1b = -1,
51 a1bb27b1 pbrook
} sd_rsp_type_t;
52 a1bb27b1 pbrook
53 a1bb27b1 pbrook
struct SDState {
54 a1bb27b1 pbrook
    enum {
55 a1bb27b1 pbrook
        sd_inactive,
56 a1bb27b1 pbrook
        sd_card_identification_mode,
57 a1bb27b1 pbrook
        sd_data_transfer_mode,
58 a1bb27b1 pbrook
    } mode;
59 a1bb27b1 pbrook
    enum {
60 a1bb27b1 pbrook
        sd_inactive_state = -1,
61 a1bb27b1 pbrook
        sd_idle_state = 0,
62 a1bb27b1 pbrook
        sd_ready_state,
63 a1bb27b1 pbrook
        sd_identification_state,
64 a1bb27b1 pbrook
        sd_standby_state,
65 a1bb27b1 pbrook
        sd_transfer_state,
66 a1bb27b1 pbrook
        sd_sendingdata_state,
67 a1bb27b1 pbrook
        sd_receivingdata_state,
68 a1bb27b1 pbrook
        sd_programming_state,
69 a1bb27b1 pbrook
        sd_disconnect_state,
70 a1bb27b1 pbrook
    } state;
71 a1bb27b1 pbrook
    uint32_t ocr;
72 a1bb27b1 pbrook
    uint8_t scr[8];
73 a1bb27b1 pbrook
    uint8_t cid[16];
74 a1bb27b1 pbrook
    uint8_t csd[16];
75 a1bb27b1 pbrook
    uint16_t rca;
76 a1bb27b1 pbrook
    uint32_t card_status;
77 a1bb27b1 pbrook
    uint8_t sd_status[64];
78 a1bb27b1 pbrook
    int wp_switch;
79 a1bb27b1 pbrook
    int *wp_groups;
80 a1bb27b1 pbrook
    uint32_t size;
81 a1bb27b1 pbrook
    int blk_len;
82 a1bb27b1 pbrook
    uint32_t erase_start;
83 a1bb27b1 pbrook
    uint32_t erase_end;
84 a1bb27b1 pbrook
    uint8_t pwd[16];
85 a1bb27b1 pbrook
    int pwd_len;
86 a1bb27b1 pbrook
    int function_group[6];
87 a1bb27b1 pbrook
88 a1bb27b1 pbrook
    int current_cmd;
89 a1bb27b1 pbrook
    int blk_written;
90 a1bb27b1 pbrook
    uint32_t data_start;
91 a1bb27b1 pbrook
    uint32_t data_offset;
92 a1bb27b1 pbrook
    uint8_t data[512];
93 02ce600c balrog
    qemu_irq readonly_cb;
94 02ce600c balrog
    qemu_irq inserted_cb;
95 a1bb27b1 pbrook
    BlockDriverState *bdrv;
96 a1bb27b1 pbrook
};
97 a1bb27b1 pbrook
98 a1bb27b1 pbrook
static void sd_set_status(SDState *sd)
99 a1bb27b1 pbrook
{
100 a1bb27b1 pbrook
    switch (sd->state) {
101 a1bb27b1 pbrook
    case sd_inactive_state:
102 a1bb27b1 pbrook
        sd->mode = sd_inactive;
103 a1bb27b1 pbrook
        break;
104 a1bb27b1 pbrook
105 a1bb27b1 pbrook
    case sd_idle_state:
106 a1bb27b1 pbrook
    case sd_ready_state:
107 a1bb27b1 pbrook
    case sd_identification_state:
108 a1bb27b1 pbrook
        sd->mode = sd_card_identification_mode;
109 a1bb27b1 pbrook
        break;
110 a1bb27b1 pbrook
111 a1bb27b1 pbrook
    case sd_standby_state:
112 a1bb27b1 pbrook
    case sd_transfer_state:
113 a1bb27b1 pbrook
    case sd_sendingdata_state:
114 a1bb27b1 pbrook
    case sd_receivingdata_state:
115 a1bb27b1 pbrook
    case sd_programming_state:
116 a1bb27b1 pbrook
    case sd_disconnect_state:
117 a1bb27b1 pbrook
        sd->mode = sd_data_transfer_mode;
118 a1bb27b1 pbrook
        break;
119 a1bb27b1 pbrook
    }
120 a1bb27b1 pbrook
121 a1bb27b1 pbrook
    sd->card_status &= ~CURRENT_STATE;
122 a1bb27b1 pbrook
    sd->card_status |= sd->state << 9;
123 a1bb27b1 pbrook
}
124 a1bb27b1 pbrook
125 a1bb27b1 pbrook
const sd_cmd_type_t sd_cmd_type[64] = {
126 a1bb27b1 pbrook
    sd_bc,   sd_none, sd_bcr,  sd_bcr,  sd_none, sd_none, sd_none, sd_ac,
127 a1bb27b1 pbrook
    sd_none, sd_ac,   sd_ac,   sd_adtc, sd_ac,   sd_ac,   sd_none, sd_ac,
128 a1bb27b1 pbrook
    sd_ac,   sd_adtc, sd_adtc, sd_none, sd_none, sd_none, sd_none, sd_none,
129 a1bb27b1 pbrook
    sd_adtc, sd_adtc, sd_adtc, sd_adtc, sd_ac,   sd_ac,   sd_adtc, sd_none,
130 a1bb27b1 pbrook
    sd_ac,   sd_ac,   sd_none, sd_none, sd_none, sd_none, sd_ac,   sd_none,
131 a1bb27b1 pbrook
    sd_none, sd_none, sd_bc,   sd_none, sd_none, sd_none, sd_none, sd_none,
132 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_ac,
133 a1bb27b1 pbrook
    sd_adtc, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
134 a1bb27b1 pbrook
};
135 a1bb27b1 pbrook
136 a1bb27b1 pbrook
const sd_cmd_type_t sd_acmd_type[64] = {
137 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_ac,   sd_none,
138 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_adtc, sd_none, sd_none,
139 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_adtc, sd_ac,
140 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
141 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
142 a1bb27b1 pbrook
    sd_none, sd_bcr,  sd_ac,   sd_none, sd_none, sd_none, sd_none, sd_none,
143 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_adtc, sd_none, sd_none, sd_none, sd_none,
144 a1bb27b1 pbrook
    sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
145 a1bb27b1 pbrook
};
146 a1bb27b1 pbrook
147 a1bb27b1 pbrook
static const int sd_cmd_class[64] = {
148 a1bb27b1 pbrook
    0,  0,  0,  0,  0,  9, 10,  0,  0,  0,  0,  1,  0,  0,  0,  0,
149 a1bb27b1 pbrook
    2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  6,  6,  6,  6,
150 a1bb27b1 pbrook
    5,  5, 10, 10, 10, 10,  5,  9,  9,  9,  7,  7,  7,  7,  7,  7,
151 a1bb27b1 pbrook
    7,  7, 10,  7,  9,  9,  9,  8,  8, 10,  8,  8,  8,  8,  8,  8,
152 a1bb27b1 pbrook
};
153 a1bb27b1 pbrook
154 a1bb27b1 pbrook
static uint8_t sd_crc7(void *message, size_t width)
155 a1bb27b1 pbrook
{
156 a1bb27b1 pbrook
    int i, bit;
157 a1bb27b1 pbrook
    uint8_t shift_reg = 0x00;
158 a1bb27b1 pbrook
    uint8_t *msg = (uint8_t *) message;
159 a1bb27b1 pbrook
160 a1bb27b1 pbrook
    for (i = 0; i < width; i ++, msg ++)
161 a1bb27b1 pbrook
        for (bit = 7; bit >= 0; bit --) {
162 a1bb27b1 pbrook
            shift_reg <<= 1;
163 a1bb27b1 pbrook
            if ((shift_reg >> 7) ^ ((*msg >> bit) & 1))
164 a1bb27b1 pbrook
                shift_reg ^= 0x89;
165 a1bb27b1 pbrook
        }
166 a1bb27b1 pbrook
167 a1bb27b1 pbrook
    return shift_reg;
168 a1bb27b1 pbrook
}
169 a1bb27b1 pbrook
170 a1bb27b1 pbrook
static uint16_t sd_crc16(void *message, size_t width)
171 a1bb27b1 pbrook
{
172 a1bb27b1 pbrook
    int i, bit;
173 a1bb27b1 pbrook
    uint16_t shift_reg = 0x0000;
174 a1bb27b1 pbrook
    uint16_t *msg = (uint16_t *) message;
175 a1bb27b1 pbrook
    width <<= 1;
176 a1bb27b1 pbrook
177 a1bb27b1 pbrook
    for (i = 0; i < width; i ++, msg ++)
178 a1bb27b1 pbrook
        for (bit = 15; bit >= 0; bit --) {
179 a1bb27b1 pbrook
            shift_reg <<= 1;
180 a1bb27b1 pbrook
            if ((shift_reg >> 15) ^ ((*msg >> bit) & 1))
181 a1bb27b1 pbrook
                shift_reg ^= 0x1011;
182 a1bb27b1 pbrook
        }
183 a1bb27b1 pbrook
184 a1bb27b1 pbrook
    return shift_reg;
185 a1bb27b1 pbrook
}
186 a1bb27b1 pbrook
187 a1bb27b1 pbrook
static void sd_set_ocr(SDState *sd)
188 a1bb27b1 pbrook
{
189 a1bb27b1 pbrook
    sd->ocr = 0x80fffff0;
190 a1bb27b1 pbrook
}
191 a1bb27b1 pbrook
192 a1bb27b1 pbrook
static void sd_set_scr(SDState *sd)
193 a1bb27b1 pbrook
{
194 a1bb27b1 pbrook
    sd->scr[0] = 0x00;                /* SCR Structure */
195 a1bb27b1 pbrook
    sd->scr[1] = 0x2f;                /* SD Security Support */
196 a1bb27b1 pbrook
    sd->scr[2] = 0x00;
197 a1bb27b1 pbrook
    sd->scr[3] = 0x00;
198 a1bb27b1 pbrook
    sd->scr[4] = 0x00;
199 a1bb27b1 pbrook
    sd->scr[5] = 0x00;
200 a1bb27b1 pbrook
    sd->scr[6] = 0x00;
201 a1bb27b1 pbrook
    sd->scr[7] = 0x00;
202 a1bb27b1 pbrook
}
203 a1bb27b1 pbrook
204 a1bb27b1 pbrook
#define MID        0xaa
205 a1bb27b1 pbrook
#define OID        "XY"
206 a1bb27b1 pbrook
#define PNM        "QEMU!"
207 a1bb27b1 pbrook
#define PRV        0x01
208 a1bb27b1 pbrook
#define MDT_YR        2006
209 a1bb27b1 pbrook
#define MDT_MON        2
210 a1bb27b1 pbrook
211 a1bb27b1 pbrook
static void sd_set_cid(SDState *sd)
212 a1bb27b1 pbrook
{
213 a1bb27b1 pbrook
    sd->cid[0] = MID;                /* Fake card manufacturer ID (MID) */
214 a1bb27b1 pbrook
    sd->cid[1] = OID[0];        /* OEM/Application ID (OID) */
215 a1bb27b1 pbrook
    sd->cid[2] = OID[1];
216 a1bb27b1 pbrook
    sd->cid[3] = PNM[0];        /* Fake product name (PNM) */
217 a1bb27b1 pbrook
    sd->cid[4] = PNM[1];
218 a1bb27b1 pbrook
    sd->cid[5] = PNM[2];
219 a1bb27b1 pbrook
    sd->cid[6] = PNM[3];
220 a1bb27b1 pbrook
    sd->cid[7] = PNM[4];
221 a1bb27b1 pbrook
    sd->cid[8] = PRV;                /* Fake product revision (PRV) */
222 a1bb27b1 pbrook
    sd->cid[9] = 0xde;                /* Fake serial number (PSN) */
223 a1bb27b1 pbrook
    sd->cid[10] = 0xad;
224 a1bb27b1 pbrook
    sd->cid[11] = 0xbe;
225 a1bb27b1 pbrook
    sd->cid[12] = 0xef;
226 a1bb27b1 pbrook
    sd->cid[13] = 0x00 |        /* Manufacture date (MDT) */
227 a1bb27b1 pbrook
        ((MDT_YR - 2000) / 10);
228 a1bb27b1 pbrook
    sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
229 a1bb27b1 pbrook
    sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
230 a1bb27b1 pbrook
}
231 a1bb27b1 pbrook
232 a1bb27b1 pbrook
#define HWBLOCK_SHIFT        9                        /* 512 bytes */
233 a1bb27b1 pbrook
#define SECTOR_SHIFT        5                        /* 16 kilobytes */
234 a1bb27b1 pbrook
#define WPGROUP_SHIFT        7                        /* 2 megs */
235 a1bb27b1 pbrook
#define CMULT_SHIFT        9                        /* 512 times HWBLOCK_SIZE */
236 a1bb27b1 pbrook
#define BLOCK_SIZE        (1 << (HWBLOCK_SHIFT))
237 a1bb27b1 pbrook
#define SECTOR_SIZE        (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT))
238 a1bb27b1 pbrook
#define WPGROUP_SIZE        (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
239 a1bb27b1 pbrook
240 a1bb27b1 pbrook
static const uint8_t sd_csd_rw_mask[16] = {
241 a1bb27b1 pbrook
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 a1bb27b1 pbrook
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
243 a1bb27b1 pbrook
};
244 a1bb27b1 pbrook
245 a1bb27b1 pbrook
static void sd_set_csd(SDState *sd, uint32_t size)
246 a1bb27b1 pbrook
{
247 a1bb27b1 pbrook
    uint32_t csize = (size >> (CMULT_SHIFT + HWBLOCK_SHIFT)) - 1;
248 a1bb27b1 pbrook
    uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
249 a1bb27b1 pbrook
    uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
250 a1bb27b1 pbrook
251 a1bb27b1 pbrook
    sd->csd[0] = 0x00;                /* CSD structure */
252 a1bb27b1 pbrook
    sd->csd[1] = 0x26;                /* Data read access-time-1 */
253 a1bb27b1 pbrook
    sd->csd[2] = 0x00;                /* Data read access-time-2 */
254 a1bb27b1 pbrook
    sd->csd[3] = 0x5a;                /* Max. data transfer rate */
255 a1bb27b1 pbrook
    sd->csd[4] = 0x5f;                /* Card Command Classes */
256 a1bb27b1 pbrook
    sd->csd[5] = 0x50 |                /* Max. read data block length */
257 a1bb27b1 pbrook
        HWBLOCK_SHIFT;
258 a1bb27b1 pbrook
    sd->csd[6] = 0xe0 |                /* Partial block for read allowed */
259 a1bb27b1 pbrook
        ((csize >> 10) & 0x03);
260 a1bb27b1 pbrook
    sd->csd[7] = 0x00 |                /* Device size */
261 a1bb27b1 pbrook
        ((csize >> 2) & 0xff);
262 a1bb27b1 pbrook
    sd->csd[8] = 0x3f |                /* Max. read current */
263 a1bb27b1 pbrook
        ((csize << 6) & 0xc0);
264 a1bb27b1 pbrook
    sd->csd[9] = 0xfc |                /* Max. write current */
265 a1bb27b1 pbrook
        ((CMULT_SHIFT - 2) >> 1);
266 a1bb27b1 pbrook
    sd->csd[10] = 0x40 |        /* Erase sector size */
267 a1bb27b1 pbrook
        (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
268 a1bb27b1 pbrook
    sd->csd[11] = 0x00 |        /* Write protect group size */
269 a1bb27b1 pbrook
        ((sectsize << 7) & 0x80) | wpsize;
270 a1bb27b1 pbrook
    sd->csd[12] = 0x90 |        /* Write speed factor */
271 a1bb27b1 pbrook
        (HWBLOCK_SHIFT >> 2);
272 a1bb27b1 pbrook
    sd->csd[13] = 0x20 |        /* Max. write data block length */
273 a1bb27b1 pbrook
        ((HWBLOCK_SHIFT << 6) & 0xc0);
274 a1bb27b1 pbrook
    sd->csd[14] = 0x00;                /* File format group */
275 a1bb27b1 pbrook
    sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
276 a1bb27b1 pbrook
}
277 a1bb27b1 pbrook
278 a1bb27b1 pbrook
static void sd_set_rca(SDState *sd)
279 a1bb27b1 pbrook
{
280 a1bb27b1 pbrook
    sd->rca += 0x4567;
281 a1bb27b1 pbrook
}
282 a1bb27b1 pbrook
283 a1bb27b1 pbrook
#define CARD_STATUS_A        0x02004100
284 a1bb27b1 pbrook
#define CARD_STATUS_B        0x00c01e00
285 a1bb27b1 pbrook
#define CARD_STATUS_C        0xfd39a028
286 a1bb27b1 pbrook
287 a1bb27b1 pbrook
static void sd_set_cardstatus(SDState *sd)
288 a1bb27b1 pbrook
{
289 a1bb27b1 pbrook
    sd->card_status = 0x00000100;
290 a1bb27b1 pbrook
}
291 a1bb27b1 pbrook
292 a1bb27b1 pbrook
static void sd_set_sdstatus(SDState *sd)
293 a1bb27b1 pbrook
{
294 a1bb27b1 pbrook
    memset(sd->sd_status, 0, 64);
295 a1bb27b1 pbrook
}
296 a1bb27b1 pbrook
297 a1bb27b1 pbrook
static int sd_req_crc_validate(struct sd_request_s *req)
298 a1bb27b1 pbrook
{
299 a1bb27b1 pbrook
    uint8_t buffer[5];
300 a1bb27b1 pbrook
    buffer[0] = 0x40 | req->cmd;
301 a1bb27b1 pbrook
    buffer[1] = (req->arg >> 24) & 0xff;
302 a1bb27b1 pbrook
    buffer[2] = (req->arg >> 16) & 0xff;
303 a1bb27b1 pbrook
    buffer[3] = (req->arg >> 8) & 0xff;
304 a1bb27b1 pbrook
    buffer[4] = (req->arg >> 0) & 0xff;
305 a1bb27b1 pbrook
    return 0;
306 a1bb27b1 pbrook
    return sd_crc7(buffer, 5) != req->crc;        /* TODO */
307 a1bb27b1 pbrook
}
308 a1bb27b1 pbrook
309 a1bb27b1 pbrook
void sd_response_r1_make(SDState *sd,
310 a1bb27b1 pbrook
                         uint8_t *response, uint32_t last_status)
311 a1bb27b1 pbrook
{
312 a1bb27b1 pbrook
    uint32_t mask = CARD_STATUS_B ^ ILLEGAL_COMMAND;
313 a1bb27b1 pbrook
    uint32_t status;
314 a1bb27b1 pbrook
315 a1bb27b1 pbrook
    status = (sd->card_status & ~mask) | (last_status & mask);
316 a1bb27b1 pbrook
    sd->card_status &= ~CARD_STATUS_C | APP_CMD;
317 a1bb27b1 pbrook
318 a1bb27b1 pbrook
    response[0] = (status >> 24) & 0xff;
319 a1bb27b1 pbrook
    response[1] = (status >> 16) & 0xff;
320 a1bb27b1 pbrook
    response[2] = (status >> 8) & 0xff;
321 a1bb27b1 pbrook
    response[3] = (status >> 0) & 0xff;
322 a1bb27b1 pbrook
}
323 a1bb27b1 pbrook
324 a1bb27b1 pbrook
void sd_response_r3_make(SDState *sd, uint8_t *response)
325 a1bb27b1 pbrook
{
326 a1bb27b1 pbrook
    response[0] = (sd->ocr >> 24) & 0xff;
327 a1bb27b1 pbrook
    response[1] = (sd->ocr >> 16) & 0xff;
328 a1bb27b1 pbrook
    response[2] = (sd->ocr >> 8) & 0xff;
329 a1bb27b1 pbrook
    response[3] = (sd->ocr >> 0) & 0xff;
330 a1bb27b1 pbrook
}
331 a1bb27b1 pbrook
332 a1bb27b1 pbrook
void sd_response_r6_make(SDState *sd, uint8_t *response)
333 a1bb27b1 pbrook
{
334 a1bb27b1 pbrook
    uint16_t arg;
335 a1bb27b1 pbrook
    uint16_t status;
336 a1bb27b1 pbrook
337 a1bb27b1 pbrook
    arg = sd->rca;
338 a1bb27b1 pbrook
    status = ((sd->card_status >> 8) & 0xc000) |
339 a1bb27b1 pbrook
             ((sd->card_status >> 6) & 0x2000) |
340 a1bb27b1 pbrook
              (sd->card_status & 0x1fff);
341 a1bb27b1 pbrook
342 a1bb27b1 pbrook
    response[0] = (arg >> 8) & 0xff;
343 a1bb27b1 pbrook
    response[1] = arg & 0xff;
344 a1bb27b1 pbrook
    response[2] = (status >> 8) & 0xff;
345 a1bb27b1 pbrook
    response[3] = status & 0xff;
346 a1bb27b1 pbrook
}
347 a1bb27b1 pbrook
348 a1bb27b1 pbrook
static void sd_reset(SDState *sd, BlockDriverState *bdrv)
349 a1bb27b1 pbrook
{
350 a1bb27b1 pbrook
    uint32_t size;
351 a1bb27b1 pbrook
    uint64_t sect;
352 a1bb27b1 pbrook
353 a1bb27b1 pbrook
    bdrv_get_geometry(bdrv, &sect);
354 a1bb27b1 pbrook
    sect <<= 9;
355 a1bb27b1 pbrook
356 a1bb27b1 pbrook
    if (sect > 0x40000000)
357 a1bb27b1 pbrook
        size = 0x40000000;        /* 1 gig */
358 a1bb27b1 pbrook
    else
359 a1bb27b1 pbrook
        size = sect + 1;
360 a1bb27b1 pbrook
361 a1bb27b1 pbrook
    sect = (size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1;
362 a1bb27b1 pbrook
363 a1bb27b1 pbrook
    sd->state = sd_idle_state;
364 a1bb27b1 pbrook
    sd->rca = 0x0000;
365 a1bb27b1 pbrook
    sd_set_ocr(sd);
366 a1bb27b1 pbrook
    sd_set_scr(sd);
367 a1bb27b1 pbrook
    sd_set_cid(sd);
368 a1bb27b1 pbrook
    sd_set_csd(sd, size);
369 a1bb27b1 pbrook
    sd_set_cardstatus(sd);
370 a1bb27b1 pbrook
    sd_set_sdstatus(sd);
371 a1bb27b1 pbrook
372 a1bb27b1 pbrook
    sd->bdrv = bdrv;
373 a1bb27b1 pbrook
374 257514dd pbrook
    if (sd->wp_groups)
375 257514dd pbrook
        qemu_free(sd->wp_groups);
376 a1bb27b1 pbrook
    sd->wp_switch = bdrv_is_read_only(bdrv);
377 a1bb27b1 pbrook
    sd->wp_groups = (int *) qemu_mallocz(sizeof(int) * sect);
378 a1bb27b1 pbrook
    memset(sd->wp_groups, 0, sizeof(int) * sect);
379 a1bb27b1 pbrook
    memset(sd->function_group, 0, sizeof(int) * 6);
380 a1bb27b1 pbrook
    sd->erase_start = 0;
381 a1bb27b1 pbrook
    sd->erase_end = 0;
382 a1bb27b1 pbrook
    sd->size = size;
383 a1bb27b1 pbrook
    sd->blk_len = 0x200;
384 a1bb27b1 pbrook
    sd->pwd_len = 0;
385 a1bb27b1 pbrook
}
386 a1bb27b1 pbrook
387 a1bb27b1 pbrook
static void sd_cardchange(void *opaque)
388 a1bb27b1 pbrook
{
389 a1bb27b1 pbrook
    SDState *sd = opaque;
390 02ce600c balrog
    qemu_set_irq(sd->inserted_cb, bdrv_is_inserted(sd->bdrv));
391 a1bb27b1 pbrook
    if (bdrv_is_inserted(sd->bdrv)) {
392 a1bb27b1 pbrook
        sd_reset(sd, sd->bdrv);
393 257514dd pbrook
        qemu_set_irq(sd->readonly_cb, sd->wp_switch);
394 a1bb27b1 pbrook
    }
395 a1bb27b1 pbrook
}
396 a1bb27b1 pbrook
397 a1bb27b1 pbrook
SDState *sd_init(BlockDriverState *bs)
398 a1bb27b1 pbrook
{
399 a1bb27b1 pbrook
    SDState *sd;
400 a1bb27b1 pbrook
401 a1bb27b1 pbrook
    sd = (SDState *) qemu_mallocz(sizeof(SDState));
402 a1bb27b1 pbrook
    sd_reset(sd, bs);
403 02ce600c balrog
    bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd);
404 a1bb27b1 pbrook
    return sd;
405 a1bb27b1 pbrook
}
406 a1bb27b1 pbrook
407 02ce600c balrog
void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
408 a1bb27b1 pbrook
{
409 02ce600c balrog
    sd->readonly_cb = readonly;
410 02ce600c balrog
    sd->inserted_cb = insert;
411 02ce600c balrog
    qemu_set_irq(readonly, bdrv_is_read_only(sd->bdrv));
412 02ce600c balrog
    qemu_set_irq(insert, bdrv_is_inserted(sd->bdrv));
413 a1bb27b1 pbrook
}
414 a1bb27b1 pbrook
415 a1bb27b1 pbrook
static void sd_erase(SDState *sd)
416 a1bb27b1 pbrook
{
417 a1bb27b1 pbrook
    int i, start, end;
418 a1bb27b1 pbrook
    if (!sd->erase_start || !sd->erase_end) {
419 a1bb27b1 pbrook
        sd->card_status |= ERASE_SEQ_ERROR;
420 a1bb27b1 pbrook
        return;
421 a1bb27b1 pbrook
    }
422 a1bb27b1 pbrook
423 a1bb27b1 pbrook
    start = sd->erase_start >>
424 a1bb27b1 pbrook
            (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
425 a1bb27b1 pbrook
    end = sd->erase_end >>
426 a1bb27b1 pbrook
            (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
427 a1bb27b1 pbrook
    sd->erase_start = 0;
428 a1bb27b1 pbrook
    sd->erase_end = 0;
429 a1bb27b1 pbrook
    sd->csd[14] |= 0x40;
430 a1bb27b1 pbrook
431 a1bb27b1 pbrook
    for (i = start; i <= end; i ++)
432 a1bb27b1 pbrook
        if (sd->wp_groups[i])
433 a1bb27b1 pbrook
            sd->card_status |= WP_ERASE_SKIP;
434 a1bb27b1 pbrook
}
435 a1bb27b1 pbrook
436 a1bb27b1 pbrook
static uint32_t sd_wpbits(SDState *sd, uint32_t addr)
437 a1bb27b1 pbrook
{
438 a1bb27b1 pbrook
    uint32_t i, wpnum;
439 a1bb27b1 pbrook
    uint32_t ret = 0;
440 a1bb27b1 pbrook
441 a1bb27b1 pbrook
    wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
442 a1bb27b1 pbrook
443 a1bb27b1 pbrook
    for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE)
444 a1bb27b1 pbrook
        if (addr < sd->size && sd->wp_groups[wpnum])
445 a1bb27b1 pbrook
            ret |= (1 << i);
446 a1bb27b1 pbrook
447 a1bb27b1 pbrook
    return ret;
448 a1bb27b1 pbrook
}
449 a1bb27b1 pbrook
450 a1bb27b1 pbrook
static void sd_function_switch(SDState *sd, uint32_t arg)
451 a1bb27b1 pbrook
{
452 a1bb27b1 pbrook
    int i, mode, new_func, crc;
453 a1bb27b1 pbrook
    mode = !!(arg & 0x80000000);
454 a1bb27b1 pbrook
455 a1bb27b1 pbrook
    sd->data[0] = 0x00;                /* Maximum current consumption */
456 a1bb27b1 pbrook
    sd->data[1] = 0x01;
457 a1bb27b1 pbrook
    sd->data[2] = 0x80;                /* Supported group 6 functions */
458 a1bb27b1 pbrook
    sd->data[3] = 0x01;
459 a1bb27b1 pbrook
    sd->data[4] = 0x80;                /* Supported group 5 functions */
460 a1bb27b1 pbrook
    sd->data[5] = 0x01;
461 a1bb27b1 pbrook
    sd->data[6] = 0x80;                /* Supported group 4 functions */
462 a1bb27b1 pbrook
    sd->data[7] = 0x01;
463 a1bb27b1 pbrook
    sd->data[8] = 0x80;                /* Supported group 3 functions */
464 a1bb27b1 pbrook
    sd->data[9] = 0x01;
465 a1bb27b1 pbrook
    sd->data[10] = 0x80;        /* Supported group 2 functions */
466 a1bb27b1 pbrook
    sd->data[11] = 0x43;
467 a1bb27b1 pbrook
    sd->data[12] = 0x80;        /* Supported group 1 functions */
468 a1bb27b1 pbrook
    sd->data[13] = 0x03;
469 a1bb27b1 pbrook
    for (i = 0; i < 6; i ++) {
470 a1bb27b1 pbrook
        new_func = (arg >> (i * 4)) & 0x0f;
471 a1bb27b1 pbrook
        if (mode && new_func != 0x0f)
472 a1bb27b1 pbrook
            sd->function_group[i] = new_func;
473 a1bb27b1 pbrook
        sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
474 a1bb27b1 pbrook
    }
475 a1bb27b1 pbrook
    memset(&sd->data[17], 0, 47);
476 a1bb27b1 pbrook
    crc = sd_crc16(sd->data, 64);
477 a1bb27b1 pbrook
    sd->data[65] = crc >> 8;
478 a1bb27b1 pbrook
    sd->data[66] = crc & 0xff;
479 a1bb27b1 pbrook
}
480 a1bb27b1 pbrook
481 a1bb27b1 pbrook
static inline int sd_wp_addr(SDState *sd, uint32_t addr)
482 a1bb27b1 pbrook
{
483 a1bb27b1 pbrook
    return sd->wp_groups[addr >>
484 a1bb27b1 pbrook
            (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)];
485 a1bb27b1 pbrook
}
486 a1bb27b1 pbrook
487 a1bb27b1 pbrook
static void sd_lock_command(SDState *sd)
488 a1bb27b1 pbrook
{
489 a1bb27b1 pbrook
    int erase, lock, clr_pwd, set_pwd, pwd_len;
490 a1bb27b1 pbrook
    erase = !!(sd->data[0] & 0x08);
491 a1bb27b1 pbrook
    lock = sd->data[0] & 0x04;
492 a1bb27b1 pbrook
    clr_pwd = sd->data[0] & 0x02;
493 a1bb27b1 pbrook
    set_pwd = sd->data[0] & 0x01;
494 a1bb27b1 pbrook
495 a1bb27b1 pbrook
    if (sd->blk_len > 1)
496 a1bb27b1 pbrook
        pwd_len = sd->data[1];
497 a1bb27b1 pbrook
    else
498 a1bb27b1 pbrook
        pwd_len = 0;
499 a1bb27b1 pbrook
500 a1bb27b1 pbrook
    if (erase) {
501 a1bb27b1 pbrook
        if (!(sd->card_status & CARD_IS_LOCKED) || sd->blk_len > 1 ||
502 a1bb27b1 pbrook
                        set_pwd || clr_pwd || lock || sd->wp_switch ||
503 a1bb27b1 pbrook
                        (sd->csd[14] & 0x20)) {
504 a1bb27b1 pbrook
            sd->card_status |= LOCK_UNLOCK_FAILED;
505 a1bb27b1 pbrook
            return;
506 a1bb27b1 pbrook
        }
507 a1bb27b1 pbrook
        memset(sd->wp_groups, 0, sizeof(int) * (sd->size >>
508 a1bb27b1 pbrook
                        (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)));
509 a1bb27b1 pbrook
        sd->csd[14] &= ~0x10;
510 a1bb27b1 pbrook
        sd->card_status &= ~CARD_IS_LOCKED;
511 a1bb27b1 pbrook
        sd->pwd_len = 0;
512 a1bb27b1 pbrook
        /* Erasing the entire card here! */
513 a1bb27b1 pbrook
        printf("SD: Card force-erased by CMD42\n");
514 a1bb27b1 pbrook
        return;
515 a1bb27b1 pbrook
    }
516 a1bb27b1 pbrook
517 a1bb27b1 pbrook
    if (sd->blk_len < 2 + pwd_len ||
518 a1bb27b1 pbrook
                    pwd_len <= sd->pwd_len ||
519 a1bb27b1 pbrook
                    pwd_len > sd->pwd_len + 16) {
520 a1bb27b1 pbrook
        sd->card_status |= LOCK_UNLOCK_FAILED;
521 a1bb27b1 pbrook
        return;
522 a1bb27b1 pbrook
    }
523 a1bb27b1 pbrook
524 a1bb27b1 pbrook
    if (sd->pwd_len && memcmp(sd->pwd, sd->data + 2, sd->pwd_len)) {
525 a1bb27b1 pbrook
        sd->card_status |= LOCK_UNLOCK_FAILED;
526 a1bb27b1 pbrook
        return;
527 a1bb27b1 pbrook
    }
528 a1bb27b1 pbrook
529 a1bb27b1 pbrook
    pwd_len -= sd->pwd_len;
530 a1bb27b1 pbrook
    if ((pwd_len && !set_pwd) ||
531 a1bb27b1 pbrook
                    (clr_pwd && (set_pwd || lock)) ||
532 a1bb27b1 pbrook
                    (lock && !sd->pwd_len && !set_pwd) ||
533 a1bb27b1 pbrook
                    (!set_pwd && !clr_pwd &&
534 a1bb27b1 pbrook
                     (((sd->card_status & CARD_IS_LOCKED) && lock) ||
535 a1bb27b1 pbrook
                      (!(sd->card_status & CARD_IS_LOCKED) && !lock)))) {
536 a1bb27b1 pbrook
        sd->card_status |= LOCK_UNLOCK_FAILED;
537 a1bb27b1 pbrook
        return;
538 a1bb27b1 pbrook
    }
539 a1bb27b1 pbrook
540 a1bb27b1 pbrook
    if (set_pwd) {
541 a1bb27b1 pbrook
        memcpy(sd->pwd, sd->data + 2 + sd->pwd_len, pwd_len);
542 a1bb27b1 pbrook
        sd->pwd_len = pwd_len;
543 a1bb27b1 pbrook
    }
544 a1bb27b1 pbrook
545 a1bb27b1 pbrook
    if (clr_pwd) {
546 a1bb27b1 pbrook
        sd->pwd_len = 0;
547 a1bb27b1 pbrook
    }
548 a1bb27b1 pbrook
549 a1bb27b1 pbrook
    if (lock)
550 a1bb27b1 pbrook
        sd->card_status |= CARD_IS_LOCKED;
551 a1bb27b1 pbrook
    else
552 a1bb27b1 pbrook
        sd->card_status &= ~CARD_IS_LOCKED;
553 a1bb27b1 pbrook
}
554 a1bb27b1 pbrook
555 a1bb27b1 pbrook
static sd_rsp_type_t sd_normal_command(SDState *sd,
556 a1bb27b1 pbrook
                                       struct sd_request_s req)
557 a1bb27b1 pbrook
{
558 a1bb27b1 pbrook
    uint32_t rca = 0x0000;
559 a1bb27b1 pbrook
560 a1bb27b1 pbrook
    if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
561 a1bb27b1 pbrook
        rca = req.arg >> 16;
562 a1bb27b1 pbrook
563 a1bb27b1 pbrook
    DPRINTF("CMD%d 0x%08x state %d\n", req.cmd, req.arg, sd->state);
564 a1bb27b1 pbrook
    switch (req.cmd) {
565 a1bb27b1 pbrook
    /* Basic commands (Class 0 and Class 1) */
566 a1bb27b1 pbrook
    case 0:        /* CMD0:   GO_IDLE_STATE */
567 a1bb27b1 pbrook
        switch (sd->state) {
568 a1bb27b1 pbrook
        case sd_inactive_state:
569 a1bb27b1 pbrook
            return sd_r0;
570 a1bb27b1 pbrook
571 a1bb27b1 pbrook
        default:
572 a1bb27b1 pbrook
            sd->state = sd_idle_state;
573 a1bb27b1 pbrook
            sd_reset(sd, sd->bdrv);
574 a1bb27b1 pbrook
            return sd_r0;
575 a1bb27b1 pbrook
        }
576 a1bb27b1 pbrook
        break;
577 a1bb27b1 pbrook
578 a1bb27b1 pbrook
    case 2:        /* CMD2:   ALL_SEND_CID */
579 a1bb27b1 pbrook
        switch (sd->state) {
580 a1bb27b1 pbrook
        case sd_ready_state:
581 a1bb27b1 pbrook
            sd->state = sd_identification_state;
582 a1bb27b1 pbrook
            return sd_r2_i;
583 a1bb27b1 pbrook
584 a1bb27b1 pbrook
        default:
585 a1bb27b1 pbrook
            break;
586 a1bb27b1 pbrook
        }
587 a1bb27b1 pbrook
        break;
588 a1bb27b1 pbrook
589 a1bb27b1 pbrook
    case 3:        /* CMD3:   SEND_RELATIVE_ADDR */
590 a1bb27b1 pbrook
        switch (sd->state) {
591 a1bb27b1 pbrook
        case sd_identification_state:
592 a1bb27b1 pbrook
        case sd_standby_state:
593 a1bb27b1 pbrook
            sd->state = sd_standby_state;
594 a1bb27b1 pbrook
            sd_set_rca(sd);
595 a1bb27b1 pbrook
            return sd_r6;
596 a1bb27b1 pbrook
597 a1bb27b1 pbrook
        default:
598 a1bb27b1 pbrook
            break;
599 a1bb27b1 pbrook
        }
600 a1bb27b1 pbrook
        break;
601 a1bb27b1 pbrook
602 a1bb27b1 pbrook
    case 4:        /* CMD4:   SEND_DSR */
603 a1bb27b1 pbrook
        switch (sd->state) {
604 a1bb27b1 pbrook
        case sd_standby_state:
605 a1bb27b1 pbrook
            break;
606 a1bb27b1 pbrook
607 a1bb27b1 pbrook
        default:
608 a1bb27b1 pbrook
            break;
609 a1bb27b1 pbrook
        }
610 a1bb27b1 pbrook
        break;
611 a1bb27b1 pbrook
612 a1bb27b1 pbrook
    case 6:        /* CMD6:   SWITCH_FUNCTION */
613 a1bb27b1 pbrook
        switch (sd->mode) {
614 a1bb27b1 pbrook
        case sd_data_transfer_mode:
615 a1bb27b1 pbrook
            sd_function_switch(sd, req.arg);
616 a1bb27b1 pbrook
            sd->state = sd_sendingdata_state;
617 a1bb27b1 pbrook
            sd->data_start = 0;
618 a1bb27b1 pbrook
            sd->data_offset = 0;
619 a1bb27b1 pbrook
            return sd_r1;
620 a1bb27b1 pbrook
621 a1bb27b1 pbrook
        default:
622 a1bb27b1 pbrook
            break;
623 a1bb27b1 pbrook
        }
624 a1bb27b1 pbrook
        break;
625 a1bb27b1 pbrook
626 a1bb27b1 pbrook
    case 7:        /* CMD7:   SELECT/DESELECT_CARD */
627 a1bb27b1 pbrook
        switch (sd->state) {
628 a1bb27b1 pbrook
        case sd_standby_state:
629 a1bb27b1 pbrook
            if (sd->rca != rca)
630 a1bb27b1 pbrook
                return sd_r0;
631 a1bb27b1 pbrook
632 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
633 a1bb27b1 pbrook
            return sd_r1b;
634 a1bb27b1 pbrook
635 a1bb27b1 pbrook
        case sd_transfer_state:
636 a1bb27b1 pbrook
        case sd_sendingdata_state:
637 a1bb27b1 pbrook
            if (sd->rca == rca)
638 a1bb27b1 pbrook
                break;
639 a1bb27b1 pbrook
640 a1bb27b1 pbrook
            sd->state = sd_standby_state;
641 a1bb27b1 pbrook
            return sd_r1b;
642 a1bb27b1 pbrook
643 a1bb27b1 pbrook
        case sd_disconnect_state:
644 a1bb27b1 pbrook
            if (sd->rca != rca)
645 a1bb27b1 pbrook
                return sd_r0;
646 a1bb27b1 pbrook
647 a1bb27b1 pbrook
            sd->state = sd_programming_state;
648 a1bb27b1 pbrook
            return sd_r1b;
649 a1bb27b1 pbrook
650 a1bb27b1 pbrook
        case sd_programming_state:
651 a1bb27b1 pbrook
            if (sd->rca == rca)
652 a1bb27b1 pbrook
                break;
653 a1bb27b1 pbrook
654 a1bb27b1 pbrook
            sd->state = sd_disconnect_state;
655 a1bb27b1 pbrook
            return sd_r1b;
656 a1bb27b1 pbrook
657 a1bb27b1 pbrook
        default:
658 a1bb27b1 pbrook
            break;
659 a1bb27b1 pbrook
        }
660 a1bb27b1 pbrook
        break;
661 a1bb27b1 pbrook
662 a1bb27b1 pbrook
    case 9:        /* CMD9:   SEND_CSD */
663 a1bb27b1 pbrook
        switch (sd->state) {
664 a1bb27b1 pbrook
        case sd_standby_state:
665 a1bb27b1 pbrook
            if (sd->rca != rca)
666 a1bb27b1 pbrook
                return sd_r0;
667 a1bb27b1 pbrook
668 a1bb27b1 pbrook
            return sd_r2_s;
669 a1bb27b1 pbrook
670 a1bb27b1 pbrook
        default:
671 a1bb27b1 pbrook
            break;
672 a1bb27b1 pbrook
        }
673 a1bb27b1 pbrook
        break;
674 a1bb27b1 pbrook
675 a1bb27b1 pbrook
    case 10:        /* CMD10:  SEND_CID */
676 a1bb27b1 pbrook
        switch (sd->state) {
677 a1bb27b1 pbrook
        case sd_standby_state:
678 a1bb27b1 pbrook
            if (sd->rca != rca)
679 a1bb27b1 pbrook
                return sd_r0;
680 a1bb27b1 pbrook
681 a1bb27b1 pbrook
            return sd_r2_i;
682 a1bb27b1 pbrook
683 a1bb27b1 pbrook
        default:
684 a1bb27b1 pbrook
            break;
685 a1bb27b1 pbrook
        }
686 a1bb27b1 pbrook
        break;
687 a1bb27b1 pbrook
688 a1bb27b1 pbrook
    case 11:        /* CMD11:  READ_DAT_UNTIL_STOP */
689 a1bb27b1 pbrook
        switch (sd->state) {
690 a1bb27b1 pbrook
        case sd_transfer_state:
691 a1bb27b1 pbrook
            sd->state = sd_sendingdata_state;
692 a1bb27b1 pbrook
            sd->data_start = req.arg;
693 a1bb27b1 pbrook
            sd->data_offset = 0;
694 a1bb27b1 pbrook
695 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size)
696 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
697 a1bb27b1 pbrook
            return sd_r0;
698 a1bb27b1 pbrook
699 a1bb27b1 pbrook
        default:
700 a1bb27b1 pbrook
            break;
701 a1bb27b1 pbrook
        }
702 a1bb27b1 pbrook
        break;
703 a1bb27b1 pbrook
704 a1bb27b1 pbrook
    case 12:        /* CMD12:  STOP_TRANSMISSION */
705 a1bb27b1 pbrook
        switch (sd->state) {
706 a1bb27b1 pbrook
        case sd_sendingdata_state:
707 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
708 a1bb27b1 pbrook
            return sd_r1b;
709 a1bb27b1 pbrook
710 a1bb27b1 pbrook
        case sd_receivingdata_state:
711 a1bb27b1 pbrook
            sd->state = sd_programming_state;
712 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
713 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
714 a1bb27b1 pbrook
            return sd_r1b;
715 a1bb27b1 pbrook
716 a1bb27b1 pbrook
        default:
717 a1bb27b1 pbrook
            break;
718 a1bb27b1 pbrook
        }
719 a1bb27b1 pbrook
        break;
720 a1bb27b1 pbrook
721 a1bb27b1 pbrook
    case 13:        /* CMD13:  SEND_STATUS */
722 a1bb27b1 pbrook
        switch (sd->mode) {
723 a1bb27b1 pbrook
        case sd_data_transfer_mode:
724 a1bb27b1 pbrook
            if (sd->rca != rca)
725 a1bb27b1 pbrook
                return sd_r0;
726 a1bb27b1 pbrook
727 a1bb27b1 pbrook
            return sd_r1;
728 a1bb27b1 pbrook
729 a1bb27b1 pbrook
        default:
730 a1bb27b1 pbrook
            break;
731 a1bb27b1 pbrook
        }
732 a1bb27b1 pbrook
        break;
733 a1bb27b1 pbrook
734 a1bb27b1 pbrook
    case 15:        /* CMD15:  GO_INACTIVE_STATE */
735 a1bb27b1 pbrook
        switch (sd->mode) {
736 a1bb27b1 pbrook
        case sd_data_transfer_mode:
737 a1bb27b1 pbrook
            if (sd->rca != rca)
738 a1bb27b1 pbrook
                return sd_r0;
739 a1bb27b1 pbrook
740 a1bb27b1 pbrook
            sd->state = sd_inactive_state;
741 a1bb27b1 pbrook
            return sd_r0;
742 a1bb27b1 pbrook
743 a1bb27b1 pbrook
        default:
744 a1bb27b1 pbrook
            break;
745 a1bb27b1 pbrook
        }
746 a1bb27b1 pbrook
        break;
747 a1bb27b1 pbrook
748 a1bb27b1 pbrook
    /* Block read commands (Classs 2) */
749 a1bb27b1 pbrook
    case 16:        /* CMD16:  SET_BLOCKLEN */
750 a1bb27b1 pbrook
        switch (sd->state) {
751 a1bb27b1 pbrook
        case sd_transfer_state:
752 a1bb27b1 pbrook
            if (req.arg > (1 << HWBLOCK_SHIFT))
753 a1bb27b1 pbrook
                sd->card_status |= BLOCK_LEN_ERROR;
754 a1bb27b1 pbrook
            else
755 a1bb27b1 pbrook
                sd->blk_len = req.arg;
756 a1bb27b1 pbrook
757 a1bb27b1 pbrook
            return sd_r1;
758 a1bb27b1 pbrook
759 a1bb27b1 pbrook
        default:
760 a1bb27b1 pbrook
            break;
761 a1bb27b1 pbrook
        }
762 a1bb27b1 pbrook
        break;
763 a1bb27b1 pbrook
764 a1bb27b1 pbrook
    case 17:        /* CMD17:  READ_SINGLE_BLOCK */
765 a1bb27b1 pbrook
        switch (sd->state) {
766 a1bb27b1 pbrook
        case sd_transfer_state:
767 a1bb27b1 pbrook
            sd->state = sd_sendingdata_state;
768 a1bb27b1 pbrook
            sd->data_start = req.arg;
769 a1bb27b1 pbrook
            sd->data_offset = 0;
770 a1bb27b1 pbrook
771 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size)
772 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
773 a1bb27b1 pbrook
            return sd_r1;
774 a1bb27b1 pbrook
775 a1bb27b1 pbrook
        default:
776 a1bb27b1 pbrook
            break;
777 a1bb27b1 pbrook
        }
778 a1bb27b1 pbrook
        break;
779 a1bb27b1 pbrook
780 a1bb27b1 pbrook
    case 18:        /* CMD18:  READ_MULTIPLE_BLOCK */
781 a1bb27b1 pbrook
        switch (sd->state) {
782 a1bb27b1 pbrook
        case sd_transfer_state:
783 a1bb27b1 pbrook
            sd->state = sd_sendingdata_state;
784 a1bb27b1 pbrook
            sd->data_start = req.arg;
785 a1bb27b1 pbrook
            sd->data_offset = 0;
786 a1bb27b1 pbrook
787 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size)
788 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
789 a1bb27b1 pbrook
            return sd_r1;
790 a1bb27b1 pbrook
791 a1bb27b1 pbrook
        default:
792 a1bb27b1 pbrook
            break;
793 a1bb27b1 pbrook
        }
794 a1bb27b1 pbrook
        break;
795 a1bb27b1 pbrook
796 a1bb27b1 pbrook
    /* Block write commands (Class 4) */
797 a1bb27b1 pbrook
    case 24:        /* CMD24:  WRITE_SINGLE_BLOCK */
798 a1bb27b1 pbrook
        switch (sd->state) {
799 a1bb27b1 pbrook
        case sd_transfer_state:
800 a1bb27b1 pbrook
            sd->state = sd_receivingdata_state;
801 a1bb27b1 pbrook
            sd->data_start = req.arg;
802 a1bb27b1 pbrook
            sd->data_offset = 0;
803 a1bb27b1 pbrook
            sd->blk_written = 0;
804 a1bb27b1 pbrook
805 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size)
806 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
807 a1bb27b1 pbrook
            if (sd_wp_addr(sd, sd->data_start))
808 a1bb27b1 pbrook
                sd->card_status |= WP_VIOLATION;
809 a1bb27b1 pbrook
            if (sd->csd[14] & 0x30)
810 a1bb27b1 pbrook
                sd->card_status |= WP_VIOLATION;
811 a1bb27b1 pbrook
            return sd_r1;
812 a1bb27b1 pbrook
813 a1bb27b1 pbrook
        default:
814 a1bb27b1 pbrook
            break;
815 a1bb27b1 pbrook
        }
816 a1bb27b1 pbrook
        break;
817 a1bb27b1 pbrook
818 a1bb27b1 pbrook
    case 25:        /* CMD25:  WRITE_MULTIPLE_BLOCK */
819 a1bb27b1 pbrook
        switch (sd->state) {
820 a1bb27b1 pbrook
        case sd_transfer_state:
821 a1bb27b1 pbrook
            sd->state = sd_receivingdata_state;
822 a1bb27b1 pbrook
            sd->data_start = req.arg;
823 a1bb27b1 pbrook
            sd->data_offset = 0;
824 a1bb27b1 pbrook
            sd->blk_written = 0;
825 a1bb27b1 pbrook
826 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size)
827 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
828 a1bb27b1 pbrook
            if (sd_wp_addr(sd, sd->data_start))
829 a1bb27b1 pbrook
                sd->card_status |= WP_VIOLATION;
830 a1bb27b1 pbrook
            if (sd->csd[14] & 0x30)
831 a1bb27b1 pbrook
                sd->card_status |= WP_VIOLATION;
832 a1bb27b1 pbrook
            return sd_r1;
833 a1bb27b1 pbrook
834 a1bb27b1 pbrook
        default:
835 a1bb27b1 pbrook
            break;
836 a1bb27b1 pbrook
        }
837 a1bb27b1 pbrook
        break;
838 a1bb27b1 pbrook
839 a1bb27b1 pbrook
    case 26:        /* CMD26:  PROGRAM_CID */
840 a1bb27b1 pbrook
        switch (sd->state) {
841 a1bb27b1 pbrook
        case sd_transfer_state:
842 a1bb27b1 pbrook
            sd->state = sd_receivingdata_state;
843 a1bb27b1 pbrook
            sd->data_start = 0;
844 a1bb27b1 pbrook
            sd->data_offset = 0;
845 a1bb27b1 pbrook
            return sd_r1;
846 a1bb27b1 pbrook
847 a1bb27b1 pbrook
        default:
848 a1bb27b1 pbrook
            break;
849 a1bb27b1 pbrook
        }
850 a1bb27b1 pbrook
        break;
851 a1bb27b1 pbrook
852 a1bb27b1 pbrook
    case 27:        /* CMD27:  PROGRAM_CSD */
853 a1bb27b1 pbrook
        switch (sd->state) {
854 a1bb27b1 pbrook
        case sd_transfer_state:
855 a1bb27b1 pbrook
            sd->state = sd_receivingdata_state;
856 a1bb27b1 pbrook
            sd->data_start = 0;
857 a1bb27b1 pbrook
            sd->data_offset = 0;
858 a1bb27b1 pbrook
            return sd_r1;
859 a1bb27b1 pbrook
860 a1bb27b1 pbrook
        default:
861 a1bb27b1 pbrook
            break;
862 a1bb27b1 pbrook
        }
863 a1bb27b1 pbrook
        break;
864 a1bb27b1 pbrook
865 a1bb27b1 pbrook
    /* Write protection (Class 6) */
866 a1bb27b1 pbrook
    case 28:        /* CMD28:  SET_WRITE_PROT */
867 a1bb27b1 pbrook
        switch (sd->state) {
868 a1bb27b1 pbrook
        case sd_transfer_state:
869 a1bb27b1 pbrook
            if (req.arg >= sd->size) {
870 a1bb27b1 pbrook
                sd->card_status = ADDRESS_ERROR;
871 a1bb27b1 pbrook
                return sd_r1b;
872 a1bb27b1 pbrook
            }
873 a1bb27b1 pbrook
874 a1bb27b1 pbrook
            sd->state = sd_programming_state;
875 a1bb27b1 pbrook
            sd->wp_groups[req.arg >> (HWBLOCK_SHIFT +
876 a1bb27b1 pbrook
                            SECTOR_SHIFT + WPGROUP_SHIFT)] = 1;
877 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
878 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
879 a1bb27b1 pbrook
            return sd_r1b;
880 a1bb27b1 pbrook
881 a1bb27b1 pbrook
        default:
882 a1bb27b1 pbrook
            break;
883 a1bb27b1 pbrook
        }
884 a1bb27b1 pbrook
        break;
885 a1bb27b1 pbrook
886 a1bb27b1 pbrook
    case 29:        /* CMD29:  CLR_WRITE_PROT */
887 a1bb27b1 pbrook
        switch (sd->state) {
888 a1bb27b1 pbrook
        case sd_transfer_state:
889 a1bb27b1 pbrook
            if (req.arg >= sd->size) {
890 a1bb27b1 pbrook
                sd->card_status = ADDRESS_ERROR;
891 a1bb27b1 pbrook
                return sd_r1b;
892 a1bb27b1 pbrook
            }
893 a1bb27b1 pbrook
894 a1bb27b1 pbrook
            sd->state = sd_programming_state;
895 a1bb27b1 pbrook
            sd->wp_groups[req.arg >> (HWBLOCK_SHIFT +
896 a1bb27b1 pbrook
                            SECTOR_SHIFT + WPGROUP_SHIFT)] = 0;
897 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
898 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
899 a1bb27b1 pbrook
            return sd_r1b;
900 a1bb27b1 pbrook
901 a1bb27b1 pbrook
        default:
902 a1bb27b1 pbrook
            break;
903 a1bb27b1 pbrook
        }
904 a1bb27b1 pbrook
        break;
905 a1bb27b1 pbrook
906 a1bb27b1 pbrook
    case 30:        /* CMD30:  SEND_WRITE_PROT */
907 a1bb27b1 pbrook
        switch (sd->state) {
908 a1bb27b1 pbrook
        case sd_transfer_state:
909 a1bb27b1 pbrook
            sd->state = sd_sendingdata_state;
910 a1bb27b1 pbrook
            *(uint32_t *) sd->data = sd_wpbits(sd, req.arg);
911 a1bb27b1 pbrook
            sd->data_start = req.arg;
912 a1bb27b1 pbrook
            sd->data_offset = 0;
913 a1bb27b1 pbrook
            return sd_r1b;
914 a1bb27b1 pbrook
915 a1bb27b1 pbrook
        default:
916 a1bb27b1 pbrook
            break;
917 a1bb27b1 pbrook
        }
918 a1bb27b1 pbrook
        break;
919 a1bb27b1 pbrook
920 a1bb27b1 pbrook
    /* Erase commands (Class 5) */
921 a1bb27b1 pbrook
    case 32:        /* CMD32:  ERASE_WR_BLK_START */
922 a1bb27b1 pbrook
        switch (sd->state) {
923 a1bb27b1 pbrook
        case sd_transfer_state:
924 a1bb27b1 pbrook
            sd->erase_start = req.arg;
925 a1bb27b1 pbrook
            return sd_r1;
926 a1bb27b1 pbrook
927 a1bb27b1 pbrook
        default:
928 a1bb27b1 pbrook
            break;
929 a1bb27b1 pbrook
        }
930 a1bb27b1 pbrook
        break;
931 a1bb27b1 pbrook
932 a1bb27b1 pbrook
    case 33:        /* CMD33:  ERASE_WR_BLK_END */
933 a1bb27b1 pbrook
        switch (sd->state) {
934 a1bb27b1 pbrook
        case sd_transfer_state:
935 a1bb27b1 pbrook
            sd->erase_end = req.arg;
936 a1bb27b1 pbrook
            return sd_r1;
937 a1bb27b1 pbrook
938 a1bb27b1 pbrook
        default:
939 a1bb27b1 pbrook
            break;
940 a1bb27b1 pbrook
        }
941 a1bb27b1 pbrook
        break;
942 a1bb27b1 pbrook
943 a1bb27b1 pbrook
    case 38:        /* CMD38:  ERASE */
944 a1bb27b1 pbrook
        switch (sd->state) {
945 a1bb27b1 pbrook
        case sd_transfer_state:
946 a1bb27b1 pbrook
            if (sd->csd[14] & 0x30) {
947 a1bb27b1 pbrook
                sd->card_status |= WP_VIOLATION;
948 a1bb27b1 pbrook
                return sd_r1b;
949 a1bb27b1 pbrook
            }
950 a1bb27b1 pbrook
951 a1bb27b1 pbrook
            sd->state = sd_programming_state;
952 a1bb27b1 pbrook
            sd_erase(sd);
953 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
954 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
955 a1bb27b1 pbrook
            return sd_r1b;
956 a1bb27b1 pbrook
957 a1bb27b1 pbrook
        default:
958 a1bb27b1 pbrook
            break;
959 a1bb27b1 pbrook
        }
960 a1bb27b1 pbrook
        break;
961 a1bb27b1 pbrook
962 a1bb27b1 pbrook
    /* Lock card commands (Class 7) */
963 a1bb27b1 pbrook
    case 42:        /* CMD42:  LOCK_UNLOCK */
964 a1bb27b1 pbrook
        switch (sd->state) {
965 a1bb27b1 pbrook
        case sd_transfer_state:
966 a1bb27b1 pbrook
            sd->state = sd_receivingdata_state;
967 a1bb27b1 pbrook
            sd->data_start = 0;
968 a1bb27b1 pbrook
            sd->data_offset = 0;
969 a1bb27b1 pbrook
            return sd_r1;
970 a1bb27b1 pbrook
971 a1bb27b1 pbrook
        default:
972 a1bb27b1 pbrook
            break;
973 a1bb27b1 pbrook
        }
974 a1bb27b1 pbrook
        break;
975 a1bb27b1 pbrook
976 a1bb27b1 pbrook
    /* Application specific commands (Class 8) */
977 a1bb27b1 pbrook
    case 55:        /* CMD55:  APP_CMD */
978 a1bb27b1 pbrook
        if (sd->rca != rca)
979 a1bb27b1 pbrook
            return sd_r0;
980 a1bb27b1 pbrook
981 a1bb27b1 pbrook
        sd->card_status |= APP_CMD;
982 a1bb27b1 pbrook
        return sd_r1;
983 a1bb27b1 pbrook
984 a1bb27b1 pbrook
    case 56:        /* CMD56:  GEN_CMD */
985 a1bb27b1 pbrook
        printf("SD: GEN_CMD 0x%08x\n", req.arg);
986 a1bb27b1 pbrook
987 a1bb27b1 pbrook
        switch (sd->state) {
988 a1bb27b1 pbrook
        case sd_transfer_state:
989 a1bb27b1 pbrook
            sd->data_offset = 0;
990 a1bb27b1 pbrook
            if (req.arg & 1)
991 a1bb27b1 pbrook
                sd->state = sd_sendingdata_state;
992 a1bb27b1 pbrook
            else
993 a1bb27b1 pbrook
                sd->state = sd_receivingdata_state;
994 a1bb27b1 pbrook
            return sd_r1;
995 a1bb27b1 pbrook
996 a1bb27b1 pbrook
        default:
997 a1bb27b1 pbrook
            break;
998 a1bb27b1 pbrook
        }
999 a1bb27b1 pbrook
        break;
1000 a1bb27b1 pbrook
1001 a1bb27b1 pbrook
    default:
1002 a1bb27b1 pbrook
        sd->card_status |= ILLEGAL_COMMAND;
1003 a1bb27b1 pbrook
1004 a1bb27b1 pbrook
        printf("SD: Unknown CMD%i\n", req.cmd);
1005 a1bb27b1 pbrook
        return sd_r0;
1006 a1bb27b1 pbrook
    }
1007 a1bb27b1 pbrook
1008 a1bb27b1 pbrook
    sd->card_status |= ILLEGAL_COMMAND;
1009 a1bb27b1 pbrook
    printf("SD: CMD%i in a wrong state\n", req.cmd);
1010 a1bb27b1 pbrook
    return sd_r0;
1011 a1bb27b1 pbrook
}
1012 a1bb27b1 pbrook
1013 a1bb27b1 pbrook
static sd_rsp_type_t sd_app_command(SDState *sd,
1014 a1bb27b1 pbrook
                                    struct sd_request_s req) {
1015 a1bb27b1 pbrook
    uint32_t rca;
1016 a1bb27b1 pbrook
1017 a1bb27b1 pbrook
    if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
1018 a1bb27b1 pbrook
        rca = req.arg >> 16;
1019 a1bb27b1 pbrook
1020 a1bb27b1 pbrook
    DPRINTF("ACMD%d 0x%08x\n", req.cmd, req.arg);
1021 a1bb27b1 pbrook
    switch (req.cmd) {
1022 a1bb27b1 pbrook
    case 6:        /* ACMD6:  SET_BUS_WIDTH */
1023 a1bb27b1 pbrook
        switch (sd->state) {
1024 a1bb27b1 pbrook
        case sd_transfer_state:
1025 a1bb27b1 pbrook
            sd->sd_status[0] &= 0x3f;
1026 a1bb27b1 pbrook
            sd->sd_status[0] |= (req.arg & 0x03) << 6;
1027 a1bb27b1 pbrook
            return sd_r1;
1028 a1bb27b1 pbrook
1029 a1bb27b1 pbrook
        default:
1030 a1bb27b1 pbrook
            break;
1031 a1bb27b1 pbrook
        }
1032 a1bb27b1 pbrook
        break;
1033 a1bb27b1 pbrook
1034 a1bb27b1 pbrook
    case 13:        /* ACMD13: SD_STATUS */
1035 a1bb27b1 pbrook
        switch (sd->state) {
1036 a1bb27b1 pbrook
        case sd_transfer_state:
1037 a1bb27b1 pbrook
            sd->data_start = 0;
1038 a1bb27b1 pbrook
            sd->data_offset = 0;
1039 a1bb27b1 pbrook
            return sd_r1;
1040 a1bb27b1 pbrook
1041 a1bb27b1 pbrook
        default:
1042 a1bb27b1 pbrook
            break;
1043 a1bb27b1 pbrook
        }
1044 a1bb27b1 pbrook
        break;
1045 a1bb27b1 pbrook
1046 a1bb27b1 pbrook
    case 22:        /* ACMD22: SEND_NUM_WR_BLOCKS */
1047 a1bb27b1 pbrook
        switch (sd->state) {
1048 a1bb27b1 pbrook
        case sd_transfer_state:
1049 a1bb27b1 pbrook
            *(uint32_t *) sd->data = sd->blk_written;
1050 a1bb27b1 pbrook
1051 a1bb27b1 pbrook
            sd->data_start = 0;
1052 a1bb27b1 pbrook
            sd->data_offset = 0;
1053 a1bb27b1 pbrook
            return sd_r1;
1054 a1bb27b1 pbrook
1055 a1bb27b1 pbrook
        default:
1056 a1bb27b1 pbrook
            break;
1057 a1bb27b1 pbrook
        }
1058 a1bb27b1 pbrook
        break;
1059 a1bb27b1 pbrook
1060 a1bb27b1 pbrook
    case 23:        /* ACMD23: SET_WR_BLK_ERASE_COUNT */
1061 a1bb27b1 pbrook
        switch (sd->state) {
1062 a1bb27b1 pbrook
        case sd_transfer_state:
1063 a1bb27b1 pbrook
            return sd_r1;
1064 a1bb27b1 pbrook
1065 a1bb27b1 pbrook
        default:
1066 a1bb27b1 pbrook
            break;
1067 a1bb27b1 pbrook
        }
1068 a1bb27b1 pbrook
        break;
1069 a1bb27b1 pbrook
1070 a1bb27b1 pbrook
    case 41:        /* ACMD41: SD_APP_OP_COND */
1071 a1bb27b1 pbrook
        switch (sd->state) {
1072 a1bb27b1 pbrook
        case sd_idle_state:
1073 a1bb27b1 pbrook
            /* We accept any voltage.  10000 V is nothing.  */
1074 a1bb27b1 pbrook
            if (req.arg)
1075 a1bb27b1 pbrook
                sd->state = sd_ready_state;
1076 a1bb27b1 pbrook
1077 a1bb27b1 pbrook
            return sd_r3;
1078 a1bb27b1 pbrook
1079 a1bb27b1 pbrook
        default:
1080 a1bb27b1 pbrook
            break;
1081 a1bb27b1 pbrook
        }
1082 a1bb27b1 pbrook
        break;
1083 a1bb27b1 pbrook
1084 a1bb27b1 pbrook
    case 42:        /* ACMD42: SET_CLR_CARD_DETECT */
1085 a1bb27b1 pbrook
        switch (sd->state) {
1086 a1bb27b1 pbrook
        case sd_transfer_state:
1087 a1bb27b1 pbrook
            /* Bringing in the 50KOhm pull-up resistor... Done.  */
1088 a1bb27b1 pbrook
            return sd_r1;
1089 a1bb27b1 pbrook
1090 a1bb27b1 pbrook
        default:
1091 a1bb27b1 pbrook
            break;
1092 a1bb27b1 pbrook
        }
1093 a1bb27b1 pbrook
        break;
1094 a1bb27b1 pbrook
1095 a1bb27b1 pbrook
    case 51:        /* ACMD51: SEND_SCR */
1096 a1bb27b1 pbrook
        switch (sd->state) {
1097 a1bb27b1 pbrook
        case sd_transfer_state:
1098 a1bb27b1 pbrook
            sd->state = sd_sendingdata_state;
1099 a1bb27b1 pbrook
            sd->data_start = 0;
1100 a1bb27b1 pbrook
            sd->data_offset = 0;
1101 a1bb27b1 pbrook
            return sd_r1;
1102 a1bb27b1 pbrook
1103 a1bb27b1 pbrook
        default:
1104 a1bb27b1 pbrook
            break;
1105 a1bb27b1 pbrook
        }
1106 a1bb27b1 pbrook
        break;
1107 a1bb27b1 pbrook
1108 a1bb27b1 pbrook
    default:
1109 a1bb27b1 pbrook
        /* Fall back to standard commands.  */
1110 a1bb27b1 pbrook
        sd->card_status &= ~APP_CMD;
1111 a1bb27b1 pbrook
        return sd_normal_command(sd, req);
1112 a1bb27b1 pbrook
    }
1113 a1bb27b1 pbrook
1114 a1bb27b1 pbrook
    printf("SD: ACMD%i in a wrong state\n", req.cmd);
1115 a1bb27b1 pbrook
    return sd_r0;
1116 a1bb27b1 pbrook
}
1117 a1bb27b1 pbrook
1118 a1bb27b1 pbrook
int sd_do_command(SDState *sd, struct sd_request_s *req,
1119 a1bb27b1 pbrook
                  uint8_t *response) {
1120 a1bb27b1 pbrook
    uint32_t last_status = sd->card_status;
1121 a1bb27b1 pbrook
    sd_rsp_type_t rtype;
1122 a1bb27b1 pbrook
    int rsplen;
1123 a1bb27b1 pbrook
1124 a1bb27b1 pbrook
    if (!bdrv_is_inserted(sd->bdrv)) {
1125 a1bb27b1 pbrook
        return 0;
1126 a1bb27b1 pbrook
    }
1127 a1bb27b1 pbrook
1128 a1bb27b1 pbrook
    if (sd_req_crc_validate(req)) {
1129 a1bb27b1 pbrook
        sd->card_status &= ~COM_CRC_ERROR;
1130 a1bb27b1 pbrook
        return 0;
1131 a1bb27b1 pbrook
    }
1132 a1bb27b1 pbrook
1133 a1bb27b1 pbrook
    sd->card_status &= ~CARD_STATUS_B;
1134 a1bb27b1 pbrook
    sd_set_status(sd);
1135 a1bb27b1 pbrook
1136 a1bb27b1 pbrook
    if (last_status & CARD_IS_LOCKED)
1137 a1bb27b1 pbrook
        if (((last_status & APP_CMD) &&
1138 a1bb27b1 pbrook
                                 req->cmd == 41) ||
1139 a1bb27b1 pbrook
                        (!(last_status & APP_CMD) &&
1140 a1bb27b1 pbrook
                         (sd_cmd_class[req->cmd] == 0 ||
1141 a1bb27b1 pbrook
                          sd_cmd_class[req->cmd] == 7 ||
1142 a1bb27b1 pbrook
                          req->cmd == 16 || req->cmd == 55))) {
1143 a1bb27b1 pbrook
            sd->card_status |= ILLEGAL_COMMAND;
1144 a1bb27b1 pbrook
            printf("SD: Card is locked\n");
1145 a1bb27b1 pbrook
            return 0;
1146 a1bb27b1 pbrook
        }
1147 a1bb27b1 pbrook
1148 724d3a8f balrog
    if (last_status & APP_CMD) {
1149 a1bb27b1 pbrook
        rtype = sd_app_command(sd, *req);
1150 724d3a8f balrog
        sd->card_status &= ~APP_CMD;
1151 724d3a8f balrog
    } else
1152 a1bb27b1 pbrook
        rtype = sd_normal_command(sd, *req);
1153 a1bb27b1 pbrook
1154 a1bb27b1 pbrook
    sd->current_cmd = req->cmd;
1155 a1bb27b1 pbrook
1156 a1bb27b1 pbrook
    switch (rtype) {
1157 a1bb27b1 pbrook
    case sd_r1:
1158 a1bb27b1 pbrook
    case sd_r1b:
1159 a1bb27b1 pbrook
        sd_response_r1_make(sd, response, last_status);
1160 a1bb27b1 pbrook
        rsplen = 4;
1161 a1bb27b1 pbrook
        break;
1162 a1bb27b1 pbrook
1163 a1bb27b1 pbrook
    case sd_r2_i:
1164 a1bb27b1 pbrook
        memcpy(response, sd->cid, sizeof(sd->cid));
1165 a1bb27b1 pbrook
        response[7] |= 1;
1166 a1bb27b1 pbrook
        rsplen = 16;
1167 a1bb27b1 pbrook
        break;
1168 a1bb27b1 pbrook
1169 a1bb27b1 pbrook
    case sd_r2_s:
1170 a1bb27b1 pbrook
        memcpy(response, sd->csd, sizeof(sd->csd));
1171 a1bb27b1 pbrook
        response[7] |= 1;
1172 a1bb27b1 pbrook
        rsplen = 16;
1173 a1bb27b1 pbrook
        break;
1174 a1bb27b1 pbrook
1175 a1bb27b1 pbrook
    case sd_r3:
1176 a1bb27b1 pbrook
        sd_response_r3_make(sd, response);
1177 a1bb27b1 pbrook
        rsplen = 4;
1178 a1bb27b1 pbrook
        break;
1179 a1bb27b1 pbrook
1180 a1bb27b1 pbrook
    case sd_r6:
1181 a1bb27b1 pbrook
        sd_response_r6_make(sd, response);
1182 a1bb27b1 pbrook
        rsplen = 4;
1183 a1bb27b1 pbrook
        break;
1184 a1bb27b1 pbrook
1185 a1bb27b1 pbrook
    case sd_r0:
1186 a1bb27b1 pbrook
    default:
1187 a1bb27b1 pbrook
        rsplen = 0;
1188 a1bb27b1 pbrook
        break;
1189 a1bb27b1 pbrook
    }
1190 a1bb27b1 pbrook
1191 a1bb27b1 pbrook
    if (sd->card_status & ILLEGAL_COMMAND)
1192 a1bb27b1 pbrook
        rsplen = 0;
1193 a1bb27b1 pbrook
1194 a1bb27b1 pbrook
#ifdef DEBUG_SD
1195 a1bb27b1 pbrook
    if (rsplen) {
1196 a1bb27b1 pbrook
        int i;
1197 a1bb27b1 pbrook
        DPRINTF("Response:");
1198 a1bb27b1 pbrook
        for (i = 0; i < rsplen; i++)
1199 a1bb27b1 pbrook
            printf(" %02x", response[i]);
1200 a1bb27b1 pbrook
        printf(" state %d\n", sd->state);
1201 a1bb27b1 pbrook
    } else {
1202 a1bb27b1 pbrook
        DPRINTF("No response %d\n", sd->state);
1203 a1bb27b1 pbrook
    }
1204 a1bb27b1 pbrook
#endif
1205 a1bb27b1 pbrook
1206 a1bb27b1 pbrook
    return rsplen;
1207 a1bb27b1 pbrook
}
1208 a1bb27b1 pbrook
1209 a1bb27b1 pbrook
/* No real need for 64 bit addresses here */
1210 a1bb27b1 pbrook
static void sd_blk_read(BlockDriverState *bdrv,
1211 a1bb27b1 pbrook
                void *data, uint32_t addr, uint32_t len)
1212 a1bb27b1 pbrook
{
1213 a1bb27b1 pbrook
    uint8_t buf[512];
1214 a1bb27b1 pbrook
    uint32_t end = addr + len;
1215 a1bb27b1 pbrook
1216 a1bb27b1 pbrook
    if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) == -1) {
1217 a1bb27b1 pbrook
        printf("sd_blk_read: read error on host side\n");
1218 a1bb27b1 pbrook
        return;
1219 a1bb27b1 pbrook
    }
1220 a1bb27b1 pbrook
1221 a1bb27b1 pbrook
    if (end > (addr & ~511) + 512) {
1222 a1bb27b1 pbrook
        memcpy(data, buf + (addr & 511), 512 - (addr & 511));
1223 a1bb27b1 pbrook
1224 a1bb27b1 pbrook
        if (bdrv_read(bdrv, end >> 9, buf, 1) == -1) {
1225 a1bb27b1 pbrook
            printf("sd_blk_read: read error on host side\n");
1226 a1bb27b1 pbrook
            return;
1227 a1bb27b1 pbrook
        }
1228 a1bb27b1 pbrook
        memcpy(data + 512 - (addr & 511), buf, end & 511);
1229 a1bb27b1 pbrook
    } else
1230 a1bb27b1 pbrook
        memcpy(data, buf + (addr & 511), len);
1231 a1bb27b1 pbrook
}
1232 a1bb27b1 pbrook
1233 a1bb27b1 pbrook
static void sd_blk_write(BlockDriverState *bdrv,
1234 a1bb27b1 pbrook
                void *data, uint32_t addr, uint32_t len)
1235 a1bb27b1 pbrook
{
1236 a1bb27b1 pbrook
    uint8_t buf[512];
1237 a1bb27b1 pbrook
    uint32_t end = addr + len;
1238 a1bb27b1 pbrook
1239 a1bb27b1 pbrook
    if ((addr & 511) || len < 512)
1240 a1bb27b1 pbrook
        if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) == -1) {
1241 a1bb27b1 pbrook
            printf("sd_blk_write: read error on host side\n");
1242 a1bb27b1 pbrook
            return;
1243 a1bb27b1 pbrook
        }
1244 a1bb27b1 pbrook
1245 a1bb27b1 pbrook
    if (end > (addr & ~511) + 512) {
1246 a1bb27b1 pbrook
        memcpy(buf + (addr & 511), data, 512 - (addr & 511));
1247 a1bb27b1 pbrook
        if (bdrv_write(bdrv, addr >> 9, buf, 1) == -1) {
1248 a1bb27b1 pbrook
            printf("sd_blk_write: write error on host side\n");
1249 a1bb27b1 pbrook
            return;
1250 a1bb27b1 pbrook
        }
1251 a1bb27b1 pbrook
1252 a1bb27b1 pbrook
        if (bdrv_read(bdrv, end >> 9, buf, 1) == -1) {
1253 a1bb27b1 pbrook
            printf("sd_blk_write: read error on host side\n");
1254 a1bb27b1 pbrook
            return;
1255 a1bb27b1 pbrook
        }
1256 a1bb27b1 pbrook
        memcpy(buf, data + 512 - (addr & 511), end & 511);
1257 a1bb27b1 pbrook
        if (bdrv_write(bdrv, end >> 9, buf, 1) == -1)
1258 a1bb27b1 pbrook
            printf("sd_blk_write: write error on host side\n");
1259 a1bb27b1 pbrook
    } else {
1260 a1bb27b1 pbrook
        memcpy(buf + (addr & 511), data, len);
1261 a1bb27b1 pbrook
        if (!bdrv || bdrv_write(bdrv, addr >> 9, buf, 1) == -1)
1262 a1bb27b1 pbrook
            printf("sd_blk_write: write error on host side\n");
1263 a1bb27b1 pbrook
    }
1264 a1bb27b1 pbrook
}
1265 a1bb27b1 pbrook
1266 a1bb27b1 pbrook
#define BLK_READ_BLOCK(a, len)        sd_blk_read(sd->bdrv, sd->data, a, len)
1267 a1bb27b1 pbrook
#define BLK_WRITE_BLOCK(a, len)        sd_blk_write(sd->bdrv, sd->data, a, len)
1268 a1bb27b1 pbrook
#define APP_READ_BLOCK(a, len)        memset(sd->data, 0xec, len)
1269 a1bb27b1 pbrook
#define APP_WRITE_BLOCK(a, len)
1270 a1bb27b1 pbrook
1271 a1bb27b1 pbrook
void sd_write_data(SDState *sd, uint8_t value)
1272 a1bb27b1 pbrook
{
1273 a1bb27b1 pbrook
    int i;
1274 a1bb27b1 pbrook
1275 a1bb27b1 pbrook
    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
1276 a1bb27b1 pbrook
        return;
1277 a1bb27b1 pbrook
1278 a1bb27b1 pbrook
    if (sd->state != sd_receivingdata_state) {
1279 a1bb27b1 pbrook
        printf("sd_write_data: not in Receiving-Data state\n");
1280 a1bb27b1 pbrook
        return;
1281 a1bb27b1 pbrook
    }
1282 a1bb27b1 pbrook
1283 a1bb27b1 pbrook
    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
1284 a1bb27b1 pbrook
        return;
1285 a1bb27b1 pbrook
1286 a1bb27b1 pbrook
    switch (sd->current_cmd) {
1287 a1bb27b1 pbrook
    case 24:        /* CMD24:  WRITE_SINGLE_BLOCK */
1288 a1bb27b1 pbrook
        sd->data[sd->data_offset ++] = value;
1289 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len) {
1290 a1bb27b1 pbrook
            /* TODO: Check CRC before committing */
1291 a1bb27b1 pbrook
            sd->state = sd_programming_state;
1292 a1bb27b1 pbrook
            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
1293 a1bb27b1 pbrook
            sd->blk_written ++;
1294 a1bb27b1 pbrook
            sd->csd[14] |= 0x40;
1295 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
1296 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1297 a1bb27b1 pbrook
        }
1298 a1bb27b1 pbrook
        break;
1299 a1bb27b1 pbrook
1300 a1bb27b1 pbrook
    case 25:        /* CMD25:  WRITE_MULTIPLE_BLOCK */
1301 a1bb27b1 pbrook
        sd->data[sd->data_offset ++] = value;
1302 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len) {
1303 a1bb27b1 pbrook
            /* TODO: Check CRC before committing */
1304 a1bb27b1 pbrook
            sd->state = sd_programming_state;
1305 a1bb27b1 pbrook
            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
1306 a1bb27b1 pbrook
            sd->blk_written ++;
1307 a1bb27b1 pbrook
            sd->data_start += sd->blk_len;
1308 a1bb27b1 pbrook
            sd->data_offset = 0;
1309 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size) {
1310 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
1311 a1bb27b1 pbrook
                break;
1312 a1bb27b1 pbrook
            }
1313 a1bb27b1 pbrook
            if (sd_wp_addr(sd, sd->data_start)) {
1314 a1bb27b1 pbrook
                sd->card_status |= WP_VIOLATION;
1315 a1bb27b1 pbrook
                break;
1316 a1bb27b1 pbrook
            }
1317 a1bb27b1 pbrook
            sd->csd[14] |= 0x40;
1318 a1bb27b1 pbrook
1319 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
1320 a1bb27b1 pbrook
            sd->state = sd_receivingdata_state;
1321 a1bb27b1 pbrook
        }
1322 a1bb27b1 pbrook
        break;
1323 a1bb27b1 pbrook
1324 a1bb27b1 pbrook
    case 26:        /* CMD26:  PROGRAM_CID */
1325 a1bb27b1 pbrook
        sd->data[sd->data_offset ++] = value;
1326 a1bb27b1 pbrook
        if (sd->data_offset >= sizeof(sd->cid)) {
1327 a1bb27b1 pbrook
            /* TODO: Check CRC before committing */
1328 a1bb27b1 pbrook
            sd->state = sd_programming_state;
1329 a1bb27b1 pbrook
            for (i = 0; i < sizeof(sd->cid); i ++)
1330 a1bb27b1 pbrook
                if ((sd->cid[i] | 0x00) != sd->data[i])
1331 a1bb27b1 pbrook
                    sd->card_status |= CID_CSD_OVERWRITE;
1332 a1bb27b1 pbrook
1333 a1bb27b1 pbrook
            if (!(sd->card_status & CID_CSD_OVERWRITE))
1334 a1bb27b1 pbrook
                for (i = 0; i < sizeof(sd->cid); i ++) {
1335 a1bb27b1 pbrook
                    sd->cid[i] |= 0x00;
1336 a1bb27b1 pbrook
                    sd->cid[i] &= sd->data[i];
1337 a1bb27b1 pbrook
                }
1338 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
1339 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1340 a1bb27b1 pbrook
        }
1341 a1bb27b1 pbrook
        break;
1342 a1bb27b1 pbrook
1343 a1bb27b1 pbrook
    case 27:        /* CMD27:  PROGRAM_CSD */
1344 a1bb27b1 pbrook
        sd->data[sd->data_offset ++] = value;
1345 a1bb27b1 pbrook
        if (sd->data_offset >= sizeof(sd->csd)) {
1346 a1bb27b1 pbrook
            /* TODO: Check CRC before committing */
1347 a1bb27b1 pbrook
            sd->state = sd_programming_state;
1348 a1bb27b1 pbrook
            for (i = 0; i < sizeof(sd->csd); i ++)
1349 a1bb27b1 pbrook
                if ((sd->csd[i] | sd_csd_rw_mask[i]) !=
1350 a1bb27b1 pbrook
                    (sd->data[i] | sd_csd_rw_mask[i]))
1351 a1bb27b1 pbrook
                    sd->card_status |= CID_CSD_OVERWRITE;
1352 a1bb27b1 pbrook
1353 a1bb27b1 pbrook
            /* Copy flag (OTP) & Permanent write protect */
1354 a1bb27b1 pbrook
            if (sd->csd[14] & ~sd->data[14] & 0x60)
1355 a1bb27b1 pbrook
                sd->card_status |= CID_CSD_OVERWRITE;
1356 a1bb27b1 pbrook
1357 a1bb27b1 pbrook
            if (!(sd->card_status & CID_CSD_OVERWRITE))
1358 a1bb27b1 pbrook
                for (i = 0; i < sizeof(sd->csd); i ++) {
1359 a1bb27b1 pbrook
                    sd->csd[i] |= sd_csd_rw_mask[i];
1360 a1bb27b1 pbrook
                    sd->csd[i] &= sd->data[i];
1361 a1bb27b1 pbrook
                }
1362 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
1363 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1364 a1bb27b1 pbrook
        }
1365 a1bb27b1 pbrook
        break;
1366 a1bb27b1 pbrook
1367 a1bb27b1 pbrook
    case 42:        /* CMD42:  LOCK_UNLOCK */
1368 a1bb27b1 pbrook
        sd->data[sd->data_offset ++] = value;
1369 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len) {
1370 a1bb27b1 pbrook
            /* TODO: Check CRC before committing */
1371 a1bb27b1 pbrook
            sd->state = sd_programming_state;
1372 a1bb27b1 pbrook
            sd_lock_command(sd);
1373 a1bb27b1 pbrook
            /* Bzzzzzzztt .... Operation complete.  */
1374 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1375 a1bb27b1 pbrook
        }
1376 a1bb27b1 pbrook
        break;
1377 a1bb27b1 pbrook
1378 a1bb27b1 pbrook
    case 56:        /* CMD56:  GEN_CMD */
1379 a1bb27b1 pbrook
        sd->data[sd->data_offset ++] = value;
1380 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len) {
1381 a1bb27b1 pbrook
            APP_WRITE_BLOCK(sd->data_start, sd->data_offset);
1382 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1383 a1bb27b1 pbrook
        }
1384 a1bb27b1 pbrook
        break;
1385 a1bb27b1 pbrook
1386 a1bb27b1 pbrook
    default:
1387 a1bb27b1 pbrook
        printf("sd_write_data: unknown command\n");
1388 a1bb27b1 pbrook
        break;
1389 a1bb27b1 pbrook
    }
1390 a1bb27b1 pbrook
}
1391 a1bb27b1 pbrook
1392 a1bb27b1 pbrook
uint8_t sd_read_data(SDState *sd)
1393 a1bb27b1 pbrook
{
1394 a1bb27b1 pbrook
    /* TODO: Append CRCs */
1395 a1bb27b1 pbrook
    uint8_t ret;
1396 a1bb27b1 pbrook
1397 a1bb27b1 pbrook
    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
1398 a1bb27b1 pbrook
        return 0x00;
1399 a1bb27b1 pbrook
1400 a1bb27b1 pbrook
    if (sd->state != sd_sendingdata_state) {
1401 a1bb27b1 pbrook
        printf("sd_read_data: not in Sending-Data state\n");
1402 a1bb27b1 pbrook
        return 0x00;
1403 a1bb27b1 pbrook
    }
1404 a1bb27b1 pbrook
1405 a1bb27b1 pbrook
    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
1406 a1bb27b1 pbrook
        return 0x00;
1407 a1bb27b1 pbrook
1408 a1bb27b1 pbrook
    switch (sd->current_cmd) {
1409 a1bb27b1 pbrook
    case 6:        /* CMD6:   SWITCH_FUNCTION */
1410 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1411 a1bb27b1 pbrook
1412 a1bb27b1 pbrook
        if (sd->data_offset >= 64)
1413 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1414 a1bb27b1 pbrook
        break;
1415 a1bb27b1 pbrook
1416 a1bb27b1 pbrook
    case 11:        /* CMD11:  READ_DAT_UNTIL_STOP */
1417 a1bb27b1 pbrook
        if (sd->data_offset == 0)
1418 a1bb27b1 pbrook
            BLK_READ_BLOCK(sd->data_start, sd->blk_len);
1419 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1420 a1bb27b1 pbrook
1421 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len) {
1422 a1bb27b1 pbrook
            sd->data_start += sd->blk_len;
1423 a1bb27b1 pbrook
            sd->data_offset = 0;
1424 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size) {
1425 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
1426 a1bb27b1 pbrook
                break;
1427 a1bb27b1 pbrook
            }
1428 a1bb27b1 pbrook
        }
1429 a1bb27b1 pbrook
        break;
1430 a1bb27b1 pbrook
1431 a1bb27b1 pbrook
    case 13:        /* ACMD13: SD_STATUS */
1432 a1bb27b1 pbrook
        ret = sd->sd_status[sd->data_offset ++];
1433 a1bb27b1 pbrook
1434 a1bb27b1 pbrook
        if (sd->data_offset >= sizeof(sd->sd_status))
1435 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1436 a1bb27b1 pbrook
        break;
1437 a1bb27b1 pbrook
1438 a1bb27b1 pbrook
    case 17:        /* CMD17:  READ_SINGLE_BLOCK */
1439 a1bb27b1 pbrook
        if (sd->data_offset == 0)
1440 a1bb27b1 pbrook
            BLK_READ_BLOCK(sd->data_start, sd->blk_len);
1441 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1442 a1bb27b1 pbrook
1443 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len)
1444 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1445 a1bb27b1 pbrook
        break;
1446 a1bb27b1 pbrook
1447 a1bb27b1 pbrook
    case 18:        /* CMD18:  READ_MULTIPLE_BLOCK */
1448 a1bb27b1 pbrook
        if (sd->data_offset == 0)
1449 a1bb27b1 pbrook
            BLK_READ_BLOCK(sd->data_start, sd->blk_len);
1450 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1451 a1bb27b1 pbrook
1452 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len) {
1453 a1bb27b1 pbrook
            sd->data_start += sd->blk_len;
1454 a1bb27b1 pbrook
            sd->data_offset = 0;
1455 a1bb27b1 pbrook
            if (sd->data_start + sd->blk_len > sd->size) {
1456 a1bb27b1 pbrook
                sd->card_status |= ADDRESS_ERROR;
1457 a1bb27b1 pbrook
                break;
1458 a1bb27b1 pbrook
            }
1459 a1bb27b1 pbrook
        }
1460 a1bb27b1 pbrook
        break;
1461 a1bb27b1 pbrook
1462 a1bb27b1 pbrook
    case 22:        /* ACMD22: SEND_NUM_WR_BLOCKS */
1463 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1464 a1bb27b1 pbrook
1465 a1bb27b1 pbrook
        if (sd->data_offset >= 4)
1466 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1467 a1bb27b1 pbrook
        break;
1468 a1bb27b1 pbrook
1469 a1bb27b1 pbrook
    case 30:        /* CMD30:  SEND_WRITE_PROT */
1470 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1471 a1bb27b1 pbrook
1472 a1bb27b1 pbrook
        if (sd->data_offset >= 4)
1473 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1474 a1bb27b1 pbrook
        break;
1475 a1bb27b1 pbrook
1476 a1bb27b1 pbrook
    case 51:        /* ACMD51: SEND_SCR */
1477 a1bb27b1 pbrook
        ret = sd->scr[sd->data_offset ++];
1478 a1bb27b1 pbrook
1479 a1bb27b1 pbrook
        if (sd->data_offset >= sizeof(sd->scr))
1480 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1481 a1bb27b1 pbrook
        break;
1482 a1bb27b1 pbrook
1483 a1bb27b1 pbrook
    case 56:        /* CMD56:  GEN_CMD */
1484 a1bb27b1 pbrook
        if (sd->data_offset == 0)
1485 a1bb27b1 pbrook
            APP_READ_BLOCK(sd->data_start, sd->blk_len);
1486 a1bb27b1 pbrook
        ret = sd->data[sd->data_offset ++];
1487 a1bb27b1 pbrook
1488 a1bb27b1 pbrook
        if (sd->data_offset >= sd->blk_len)
1489 a1bb27b1 pbrook
            sd->state = sd_transfer_state;
1490 a1bb27b1 pbrook
        break;
1491 a1bb27b1 pbrook
1492 a1bb27b1 pbrook
    default:
1493 a1bb27b1 pbrook
        printf("sd_read_data: unknown command\n");
1494 a1bb27b1 pbrook
        return 0x00;
1495 a1bb27b1 pbrook
    }
1496 a1bb27b1 pbrook
1497 a1bb27b1 pbrook
    return ret;
1498 a1bb27b1 pbrook
}
1499 a1bb27b1 pbrook
1500 a1bb27b1 pbrook
int sd_data_ready(SDState *sd)
1501 a1bb27b1 pbrook
{
1502 a1bb27b1 pbrook
    return sd->state == sd_sendingdata_state;
1503 a1bb27b1 pbrook
}