diff options
author | Jack Halpin <jack.halpin@gmail.com> | 2009-11-23 04:22:11 +0000 |
---|---|---|
committer | Jack Halpin <jack.halpin@gmail.com> | 2009-11-23 04:22:11 +0000 |
commit | fab80009bcaa97294fffef92a031c159d75d4142 (patch) | |
tree | f3acbb297b63cde9852f0f82f6b020699c8763db /firmware/target/arm | |
parent | e5c2d941711a76fcfd0011c55ce1187468167506 (diff) | |
download | rockbox-fab80009bcaa97294fffef92a031c159d75d4142.tar.gz rockbox-fab80009bcaa97294fffef92a031c159d75d4142.zip |
AMS Sansa: Handle responses to SD Commands so that response crc checking is accounted for. Adjust sd error codes appropriately.
The crc check on responses to sd commands was being bypassed due to a SD_APP_OP_COND special case. Now a short response is returned
even if the crc check fails so we can check the busy bit. The send_cmd() function still returns a false value but it loads the response
variable with the cmd response.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23718 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index 05cbd327d5..0255b914db 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c | |||
@@ -211,26 +211,28 @@ static bool send_cmd(const int drive, const int cmd, const int arg, | |||
211 | 211 | ||
212 | status = MCI_STATUS(drive); | 212 | status = MCI_STATUS(drive); |
213 | 213 | ||
214 | if(flags & MCI_RESP) | 214 | /* Handle command responses */ |
215 | if(flags & MCI_RESP) /* CMD expects response */ | ||
215 | { | 216 | { |
216 | if(status & MCI_CMD_TIMEOUT) | 217 | response[0] = MCI_RESP0(drive); /* Always prepare short response */ |
218 | |||
219 | if(status & (MCI_CMD_TIMEOUT | MCI_CMD_CRC_FAIL)) /* failed response */ | ||
217 | return false; | 220 | return false; |
218 | else if(status & (MCI_CMD_CRC_FAIL /* FIXME? */ | MCI_CMD_RESP_END)) | 221 | |
219 | { /* resp received */ | 222 | if(status & MCI_CMD_RESP_END) /*Response passed CRC check */ |
223 | { | ||
220 | if(flags & MCI_LONG_RESP) | 224 | if(flags & MCI_LONG_RESP) |
221 | { | 225 | { /* replace short response with long response */ |
222 | /* store the response in reverse words order */ | 226 | /* store the response in reverse words order */ |
223 | response[0] = MCI_RESP3(drive); | 227 | response[0] = MCI_RESP3(drive); |
224 | response[1] = MCI_RESP2(drive); | 228 | response[1] = MCI_RESP2(drive); |
225 | response[2] = MCI_RESP1(drive); | 229 | response[2] = MCI_RESP1(drive); |
226 | response[3] = MCI_RESP0(drive); | 230 | response[3] = MCI_RESP0(drive); |
227 | } | 231 | } |
228 | else | ||
229 | response[0] = MCI_RESP0(drive); | ||
230 | return true; | 232 | return true; |
231 | } | 233 | } |
232 | } | 234 | } |
233 | else if(status & MCI_CMD_SENT) | 235 | else if(status & MCI_CMD_SENT) /* CMD sent, no response required */ |
234 | return true; | 236 | return true; |
235 | 237 | ||
236 | return false; | 238 | return false; |
@@ -268,29 +270,23 @@ static int sd_init_card(const int drive) | |||
268 | init_timeout = current_tick + HZ; | 270 | init_timeout = current_tick + HZ; |
269 | 271 | ||
270 | do { | 272 | do { |
271 | /* timeout */ | 273 | /* this timeout is the only valid error for this loop*/ |
272 | if(TIME_AFTER(current_tick, init_timeout)) | 274 | if(TIME_AFTER(current_tick, init_timeout)) |
273 | return -2; | 275 | return -2; |
274 | 276 | ||
275 | /* app_cmd */ | 277 | /* app_cmd */ |
276 | if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) ) | 278 | send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response); |
277 | { | ||
278 | return -3; | ||
279 | } | ||
280 | 279 | ||
281 | /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ | 280 | /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ |
282 | if(!send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), | 281 | send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), |
283 | MCI_RESP|MCI_ARG, &card_info[drive].ocr)) | 282 | MCI_RESP|MCI_ARG, &card_info[drive].ocr); |
284 | { | ||
285 | return -4; | ||
286 | } | ||
287 | 283 | ||
288 | } while(!(card_info[drive].ocr & (1<<31))); | 284 | } while(!(card_info[drive].ocr & (1<<31))); |
289 | 285 | ||
290 | /* CMD2 send CID */ | 286 | /* CMD2 send CID */ |
291 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, | 287 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, |
292 | temp_reg)) | 288 | temp_reg)) |
293 | return -5; | 289 | return -3; |
294 | 290 | ||
295 | for(i=0; i<4; i++) | 291 | for(i=0; i<4; i++) |
296 | card_info[drive].cid[3-i] = temp_reg[i]; | 292 | card_info[drive].cid[3-i] = temp_reg[i]; |
@@ -298,7 +294,7 @@ static int sd_init_card(const int drive) | |||
298 | /* CMD3 send RCA */ | 294 | /* CMD3 send RCA */ |
299 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, | 295 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, |
300 | &card_info[drive].rca)) | 296 | &card_info[drive].rca)) |
301 | return -6; | 297 | return -4; |
302 | 298 | ||
303 | 299 | ||
304 | /* End of Card Identification Mode ************************************/ | 300 | /* End of Card Identification Mode ************************************/ |
@@ -314,26 +310,26 @@ static int sd_init_card(const int drive) | |||
314 | { | 310 | { |
315 | /* CMD7 w/rca: Select card to put it in TRAN state */ | 311 | /* CMD7 w/rca: Select card to put it in TRAN state */ |
316 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) | 312 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) |
317 | return -7; | 313 | return -5; |
318 | 314 | ||
319 | if(sd_wait_for_state(drive, SD_TRAN)) | 315 | if(sd_wait_for_state(drive, SD_TRAN)) |
320 | return -8; | 316 | return -6; |
321 | /* CMD6 */ | 317 | /* CMD6 */ |
322 | if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL)) | 318 | if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL)) |
323 | return -9; | 319 | return -7; |
324 | mci_delay(); | 320 | mci_delay(); |
325 | 321 | ||
326 | /* go back to STBY state so we can read csd */ | 322 | /* go back to STBY state so we can read csd */ |
327 | /* CMD7 w/rca=0: Deselect card to put it in STBY state */ | 323 | /* CMD7 w/rca=0: Deselect card to put it in STBY state */ |
328 | if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_ARG, NULL)) | 324 | if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_ARG, NULL)) |
329 | return -10; | 325 | return -8; |
330 | } | 326 | } |
331 | #endif /* HAVE_MULTIDRIVE */ | 327 | #endif /* HAVE_MULTIDRIVE */ |
332 | 328 | ||
333 | /* CMD9 send CSD */ | 329 | /* CMD9 send CSD */ |
334 | if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, | 330 | if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, |
335 | MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) | 331 | MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) |
336 | return -11; | 332 | return -9; |
337 | 333 | ||
338 | for(i=0; i<4; i++) | 334 | for(i=0; i<4; i++) |
339 | card_info[drive].csd[3-i] = temp_reg[i]; | 335 | card_info[drive].csd[3-i] = temp_reg[i]; |
@@ -342,10 +338,10 @@ static int sd_init_card(const int drive) | |||
342 | 338 | ||
343 | /* CMD7 w/rca: Select card to put it in TRAN state */ | 339 | /* CMD7 w/rca: Select card to put it in TRAN state */ |
344 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) | 340 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) |
345 | return -12; | 341 | return -10; |
346 | 342 | ||
347 | /* | 343 | /* |
348 | * enable bank switching | 344 | * enable bank switching |
349 | * without issuing this command, we only have access to 1/4 of the blocks | 345 | * without issuing this command, we only have access to 1/4 of the blocks |
350 | * of the first bank (0x1E9E00 blocks, which is the size reported in the | 346 | * of the first bank (0x1E9E00 blocks, which is the size reported in the |
351 | * CSD register) | 347 | * CSD register) |
@@ -354,7 +350,7 @@ static int sd_init_card(const int drive) | |||
354 | { | 350 | { |
355 | const int ret = sd_select_bank(-1); | 351 | const int ret = sd_select_bank(-1); |
356 | if(ret < 0) | 352 | if(ret < 0) |
357 | return ret - 13; | 353 | return ret - 11; |
358 | } | 354 | } |
359 | 355 | ||
360 | card_info[drive].initialized = 1; | 356 | card_info[drive].initialized = 1; |