File indexing completed on 2025-05-11 08:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <stdio.h>
0035 #include <string.h>
0036 #include <errno.h>
0037 #include <inttypes.h>
0038
0039 #include <rtems.h>
0040 #include <rtems/libi2c.h>
0041 #include <rtems/libio.h>
0042 #include <rtems/blkdev.h>
0043
0044 #include <libchip/spi-sd-card.h>
0045
0046 #include <rtems/status-checks.h>
0047
0048
0049
0050
0051
0052
0053 static inline uint16_t sd_card_get_uint16( const uint8_t *s)
0054 {
0055 return (uint16_t) ((s [0] << 8) | s [1]);
0056 }
0057
0058 static inline uint32_t sd_card_get_uint32( const uint8_t *s)
0059 {
0060 return ((uint32_t) s [0] << 24) | ((uint32_t) s [1] << 16) | ((uint32_t) s [2] << 8) | (uint32_t) s [3];
0061 }
0062
0063 static inline void sd_card_put_uint16( uint16_t v, uint8_t *s)
0064 {
0065 *s++ = (uint8_t) (v >> 8);
0066 *s = (uint8_t) (v);
0067 }
0068
0069 static inline void sd_card_put_uint32( uint32_t v, uint8_t *s)
0070 {
0071 *s++ = (uint8_t) (v >> 24);
0072 *s++ = (uint8_t) (v >> 16);
0073 *s++ = (uint8_t) (v >> 8);
0074 *s = (uint8_t) (v);
0075 }
0076
0077
0078
0079 #define SD_CARD_BUSY_TOKEN 0
0080
0081 #define SD_CARD_BLOCK_SIZE_DEFAULT 512
0082
0083 #define SD_CARD_COMMAND_RESPONSE_START 7
0084
0085
0086
0087
0088
0089
0090 #define SD_CARD_CMD_GO_IDLE_STATE 0
0091 #define SD_CARD_CMD_SEND_OP_COND 1
0092 #define SD_CARD_CMD_SEND_IF_COND 8
0093 #define SD_CARD_CMD_SEND_CSD 9
0094 #define SD_CARD_CMD_SEND_CID 10
0095 #define SD_CARD_CMD_STOP_TRANSMISSION 12
0096 #define SD_CARD_CMD_SEND_STATUS 13
0097 #define SD_CARD_CMD_SET_BLOCKLEN 16
0098 #define SD_CARD_CMD_READ_SINGLE_BLOCK 17
0099 #define SD_CARD_CMD_READ_MULTIPLE_BLOCK 18
0100 #define SD_CARD_CMD_SET_BLOCK_COUNT 23
0101 #define SD_CARD_CMD_WRITE_BLOCK 24
0102 #define SD_CARD_CMD_WRITE_MULTIPLE_BLOCK 25
0103 #define SD_CARD_CMD_PROGRAM_CSD 27
0104 #define SD_CARD_CMD_SET_WRITE_PROT 28
0105 #define SD_CARD_CMD_CLR_WRITE_PROT 29
0106 #define SD_CARD_CMD_SEND_WRITE_PROT 30
0107 #define SD_CARD_CMD_TAG_SECTOR_START 32
0108 #define SD_CARD_CMD_TAG_SECTOR_END 33
0109 #define SD_CARD_CMD_UNTAG_SECTOR 34
0110 #define SD_CARD_CMD_TAG_ERASE_GROUP_START 35
0111 #define SD_CARD_CMD_TAG_ERASE_GROUP_END 36
0112 #define SD_CARD_CMD_UNTAG_ERASE_GROUP 37
0113 #define SD_CARD_CMD_ERASE 38
0114 #define SD_CARD_CMD_LOCK_UNLOCK 42
0115 #define SD_CARD_CMD_APP_CMD 55
0116 #define SD_CARD_CMD_GEN_CND 56
0117 #define SD_CARD_CMD_READ_OCR 58
0118 #define SD_CARD_CMD_CRC_ON_OFF 59
0119
0120
0121
0122
0123
0124
0125
0126
0127 #define SD_CARD_ACMD_SD_SEND_OP_COND 41
0128
0129
0130
0131
0132
0133
0134
0135
0136 #define SD_CARD_FLAG_HCS 0x40000000U
0137
0138 #define SD_CARD_FLAG_VHS_2_7_TO_3_3 0x00000100U
0139
0140 #define SD_CARD_FLAG_CHECK_PATTERN 0x000000aaU
0141
0142
0143
0144
0145
0146
0147
0148
0149 #define SD_CARD_COMMAND_SET_COMMAND( c, cmd) (c) [1] = (uint8_t) (0x40 + ((cmd) & 0x3f))
0150
0151 #define SD_CARD_COMMAND_SET_ARGUMENT( c, arg) sd_card_put_uint32( (arg), &((c) [2]))
0152
0153 #define SD_CARD_COMMAND_SET_CRC7( c, crc7) ((c) [6] = ((crc7) << 1) | 1U)
0154
0155 #define SD_CARD_COMMAND_GET_CRC7( c) ((c) [6] >> 1)
0156
0157
0158
0159
0160
0161
0162
0163
0164 #define SD_CARD_IS_RESPONSE( r) (((r) & 0x80) == 0)
0165
0166 #define SD_CARD_IS_ERRORLESS_RESPONSE( r) (((r) & 0x7e) == 0)
0167
0168 #define SD_CARD_IS_NOT_IDLE_RESPONSE( r) (((r) & 0x81) == 0)
0169
0170 #define SD_CARD_IS_DATA_ERROR( r) (((r) & 0xe0) == 0)
0171
0172 #define SD_CARD_IS_DATA_REJECTED( r) (((r) & 0x1f) != 0x05)
0173
0174
0175
0176
0177
0178
0179
0180
0181 #define SD_CARD_CID_SIZE 16
0182
0183 #define SD_CARD_CID_GET_MID( cid) ((cid) [0])
0184 #define SD_CARD_CID_GET_OID( cid) sd_card_get_uint16( cid + 1)
0185 #define SD_CARD_CID_GET_PNM( cid, i) ((char) (cid) [3 + (i)])
0186 #define SD_CARD_CID_GET_PRV( cid) ((cid) [9])
0187 #define SD_CARD_CID_GET_PSN( cid) sd_card_get_uint32( cid + 10)
0188 #define SD_CARD_CID_GET_MDT( cid) ((cid) [14])
0189 #define SD_CARD_CID_GET_CRC7( cid) ((cid) [15] >> 1)
0190
0191
0192
0193
0194
0195
0196
0197
0198 #define SD_CARD_CSD_SIZE 16
0199
0200 #define SD_CARD_CSD_GET_CSD_STRUCTURE( csd) ((csd) [0] >> 6)
0201 #define SD_CARD_CSD_GET_SPEC_VERS( csd) (((csd) [0] >> 2) & 0xf)
0202 #define SD_CARD_CSD_GET_TAAC( csd) ((csd) [1])
0203 #define SD_CARD_CSD_GET_NSAC( csd) ((uint32_t) (csd) [2])
0204 #define SD_CARD_CSD_GET_TRAN_SPEED( csd) ((csd) [3])
0205 #define SD_CARD_CSD_GET_C_SIZE( csd) ((((uint32_t) (csd) [6] & 0x3) << 10) + (((uint32_t) (csd) [7]) << 2) + ((((uint32_t) (csd) [8]) >> 6) & 0x3))
0206 #define SD_CARD_CSD_GET_C_SIZE_MULT( csd) ((((csd) [9] & 0x3) << 1) + (((csd) [10] >> 7) & 0x1))
0207 #define SD_CARD_CSD_GET_READ_BLK_LEN( csd) ((uint32_t) (csd) [5] & 0xf)
0208 #define SD_CARD_CSD_GET_WRITE_BLK_LEN( csd) ((((uint32_t) (csd) [12] & 0x3) << 2) + ((((uint32_t) (csd) [13]) >> 6) & 0x3))
0209 #define SD_CARD_CSD_1_GET_C_SIZE( csd) ((((uint32_t) (csd) [7] & 0x3f) << 16) + (((uint32_t) (csd) [8]) << 8) + (uint32_t) (csd) [9])
0210
0211
0212
0213 #define SD_CARD_INVALIDATE_RESPONSE_INDEX( e) e->response_index = SD_CARD_COMMAND_SIZE
0214
0215
0216
0217
0218
0219
0220 #define SD_CARD_START_BLOCK_SINGLE_BLOCK_READ 0xfe
0221 #define SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ 0xfe
0222 #define SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE 0xfe
0223 #define SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE 0xfc
0224 #define SD_CARD_STOP_TRANSFER_MULTIPLE_BLOCK_WRITE 0xfd
0225
0226
0227
0228
0229
0230
0231
0232
0233 static inline uint32_t sd_card_block_number( const uint8_t *csd)
0234 {
0235 uint32_t size = SD_CARD_CSD_GET_C_SIZE( csd);
0236 uint32_t mult = 1U << (SD_CARD_CSD_GET_C_SIZE_MULT( csd) + 2);
0237 return (size + 1) * mult;
0238 }
0239
0240 static inline uint32_t sd_card_capacity( const uint8_t *csd)
0241 {
0242 uint32_t block_size = 1U << SD_CARD_CSD_GET_READ_BLK_LEN( csd);
0243 return sd_card_block_number( csd) * block_size;
0244 }
0245
0246 static inline uint32_t sd_card_transfer_speed( const uint8_t *csd)
0247 {
0248 uint32_t s = SD_CARD_CSD_GET_TRAN_SPEED( csd);
0249 uint32_t e = s & 0x7;
0250 uint32_t m = s >> 3;
0251 switch (e) {
0252 case 0: s = 10000; break;
0253 case 1: s = 100000; break;
0254 case 2: s = 1000000; break;
0255 case 3: s = 10000000; break;
0256 default: s = 0; break;
0257 }
0258 switch (m) {
0259 case 1: s *= 10; break;
0260 case 2: s *= 12; break;
0261 case 3: s *= 13; break;
0262 case 4: s *= 15; break;
0263 case 5: s *= 20; break;
0264 case 6: s *= 25; break;
0265 case 7: s *= 30; break;
0266 case 8: s *= 35; break;
0267 case 9: s *= 40; break;
0268 case 10: s *= 45; break;
0269 case 11: s *= 50; break;
0270 case 12: s *= 55; break;
0271 case 13: s *= 60; break;
0272 case 14: s *= 70; break;
0273 case 15: s *= 80; break;
0274 default: s *= 0; break;
0275 }
0276 return s;
0277 }
0278
0279 static inline uint32_t sd_card_access_time( const uint8_t *csd)
0280 {
0281 uint32_t ac = SD_CARD_CSD_GET_TAAC( csd);
0282 uint32_t e = ac & 0x7;
0283 uint32_t m = ac >> 3;
0284 switch (e) {
0285 case 0: ac = 1; break;
0286 case 1: ac = 10; break;
0287 case 2: ac = 100; break;
0288 case 3: ac = 1000; break;
0289 case 4: ac = 10000; break;
0290 case 5: ac = 100000; break;
0291 case 6: ac = 1000000; break;
0292 case 7: ac = 10000000; break;
0293 default: ac = 0; break;
0294 }
0295 switch (m) {
0296 case 1: ac *= 10; break;
0297 case 2: ac *= 12; break;
0298 case 3: ac *= 13; break;
0299 case 4: ac *= 15; break;
0300 case 5: ac *= 20; break;
0301 case 6: ac *= 25; break;
0302 case 7: ac *= 30; break;
0303 case 8: ac *= 35; break;
0304 case 9: ac *= 40; break;
0305 case 10: ac *= 45; break;
0306 case 11: ac *= 50; break;
0307 case 12: ac *= 55; break;
0308 case 13: ac *= 60; break;
0309 case 14: ac *= 70; break;
0310 case 15: ac *= 80; break;
0311 default: ac *= 0; break;
0312 }
0313 return ac / 10;
0314 }
0315
0316 static inline uint32_t sd_card_max_access_time( const uint8_t *csd, uint32_t transfer_speed)
0317 {
0318 uint64_t ac = sd_card_access_time( csd);
0319 uint32_t ac_100ms = transfer_speed / 80;
0320 uint32_t n = SD_CARD_CSD_GET_NSAC( csd) * 100;
0321
0322
0323 ac = ac * transfer_speed / 80000000;
0324 ac = ac + 100*n;
0325 if ((uint32_t)ac > ac_100ms)
0326 return ac_100ms;
0327 else
0328 return (uint32_t)ac;
0329 }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 static uint8_t sd_card_compute_crc7 (uint8_t *data, size_t len)
0342 {
0343 uint8_t e, f, crc;
0344 size_t i;
0345
0346 crc = 0;
0347 for (i = 0; i < len; i++) {
0348 e = crc ^ data[i];
0349 f = e ^ (e >> 4) ^ (e >> 7);
0350 crc = (f << 1) ^ (f << 4);
0351 }
0352 return crc >> 1;
0353 }
0354
0355 static uint16_t sd_card_compute_crc16 (uint8_t *data, size_t len)
0356 {
0357 uint8_t s, t;
0358 uint16_t crc;
0359 size_t i;
0360
0361 crc = 0;
0362 for (i = 0; i < len; i++) {
0363 s = data[i] ^ (crc >> 8);
0364 t = s ^ (s >> 4);
0365 crc = (crc << 8) ^ t ^ (t << 5) ^ (t << 12);
0366 }
0367 return crc;
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377 static inline int sd_card_query( sd_card_driver_entry *e, uint8_t *in, int n)
0378 {
0379 return rtems_libi2c_read_bytes( e->bus, in, n);
0380 }
0381
0382 static int sd_card_wait( sd_card_driver_entry *e)
0383 {
0384 int rv = 0;
0385 int r = 0;
0386 int n = 2;
0387
0388
0389
0390 int retries = e->n_ac_max * 25 / 10;
0391
0392
0393
0394 int wait_time_bytes = (retries + 149) / 150;
0395 while (e->busy) {
0396
0397 rv = sd_card_query( e, e->response, n);
0398 RTEMS_CHECK_RV( rv, "Busy");
0399
0400
0401 for (r = 0; r < n; ++r) {
0402 if (e->response [r] != SD_CARD_BUSY_TOKEN) {
0403 e->busy = false;
0404 return 0;
0405 }
0406 }
0407 retries -= n;
0408 if (retries <= 0) {
0409 return -RTEMS_TIMEOUT;
0410 }
0411
0412 if (e->schedule_if_busy) {
0413 uint64_t wait_time_us = wait_time_bytes;
0414 wait_time_us *= 8000000;
0415 wait_time_us /= e->transfer_mode.baudrate;
0416 rtems_task_wake_after( RTEMS_MICROSECONDS_TO_TICKS(wait_time_us));
0417 retries -= wait_time_bytes;
0418 wait_time_bytes = wait_time_bytes * 15 / 10;
0419 } else {
0420 n = SD_CARD_COMMAND_SIZE;
0421 }
0422 }
0423 return 0;
0424 }
0425
0426 static int sd_card_send_command( sd_card_driver_entry *e, uint32_t command, uint32_t argument)
0427 {
0428 int rv = 0;
0429 rtems_libi2c_read_write_t rw = {
0430 .rd_buf = e->response,
0431 .wr_buf = e->command,
0432 .byte_cnt = SD_CARD_COMMAND_SIZE
0433 };
0434 int r = 0;
0435 uint8_t crc7;
0436
0437 SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
0438
0439
0440 rv = sd_card_wait( e);
0441 RTEMS_CHECK_RV( rv, "Wait");
0442
0443
0444 SD_CARD_COMMAND_SET_COMMAND( e->command, command);
0445 SD_CARD_COMMAND_SET_ARGUMENT( e->command, argument);
0446 crc7 = sd_card_compute_crc7( e->command + 1, 5);
0447 SD_CARD_COMMAND_SET_CRC7( e->command, crc7);
0448 rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_READ_WRITE, &rw);
0449 RTEMS_CHECK_RV( rv, "Write command and read response");
0450
0451
0452 for (r = SD_CARD_COMMAND_RESPONSE_START; r < SD_CARD_COMMAND_SIZE; ++r) {
0453 RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, e->response [r]);
0454 e->response_index = r;
0455 if (SD_CARD_IS_RESPONSE( e->response [r])) {
0456 if (SD_CARD_IS_ERRORLESS_RESPONSE( e->response [r])) {
0457 return 0;
0458 } else {
0459 RTEMS_SYSLOG_ERROR( "Command error [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
0460 goto sd_card_send_command_error;
0461 }
0462 } else if (e->response [r] != SD_CARD_IDLE_TOKEN) {
0463 RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
0464 goto sd_card_send_command_error;
0465 }
0466 }
0467
0468 RTEMS_SYSLOG_ERROR( "Timeout\n");
0469
0470 sd_card_send_command_error:
0471
0472 RTEMS_SYSLOG_ERROR( "Response:");
0473 for (r = 0; r < SD_CARD_COMMAND_SIZE; ++r) {
0474 if (e->response_index == r) {
0475 RTEMS_SYSLOG_PRINT( " %02" PRIx8 ":[%02" PRIx8 "]", e->command [r], e->response [r]);
0476 } else {
0477 RTEMS_SYSLOG_PRINT( " %02" PRIx8 ":%02" PRIx8 "", e->command [r], e->response [r]);
0478 }
0479 }
0480 RTEMS_SYSLOG_PRINT( "\n");
0481
0482 return -RTEMS_IO_ERROR;
0483 }
0484
0485 static int sd_card_send_register_command( sd_card_driver_entry *e, uint32_t command, uint32_t argument, uint32_t *reg)
0486 {
0487 int rv = 0;
0488 uint8_t crc7;
0489
0490 rv = sd_card_send_command( e, command, argument);
0491 RTEMS_CHECK_RV( rv, "Send command");
0492
0493 if (e->response_index + 5 > SD_CARD_COMMAND_SIZE) {
0494
0495
0496
0497
0498 RTEMS_SYSLOG_ERROR( "Unexpected response position\n");
0499 return -RTEMS_IO_ERROR;
0500 }
0501
0502 crc7 = sd_card_compute_crc7( e->response + e->response_index, 5);
0503 if (crc7 != SD_CARD_COMMAND_GET_CRC7( e->response + e->response_index) &&
0504 SD_CARD_COMMAND_GET_CRC7( e->response + e->response_index) != 0x7f) {
0505 RTEMS_SYSLOG_ERROR( "CRC check failed on register command\n");
0506 return -RTEMS_IO_ERROR;
0507 }
0508
0509 *reg = sd_card_get_uint32( e->response + e->response_index + 1);
0510
0511 return 0;
0512 }
0513
0514 static int sd_card_stop_multiple_block_read( sd_card_driver_entry *e)
0515 {
0516 int rv = 0;
0517 uint8_t crc7;
0518
0519 SD_CARD_COMMAND_SET_COMMAND( e->command, SD_CARD_CMD_STOP_TRANSMISSION);
0520 SD_CARD_COMMAND_SET_ARGUMENT( e->command, 0);
0521
0522 crc7 = 0x30;
0523 SD_CARD_COMMAND_SET_CRC7( e->command, crc7);
0524 rv = rtems_libi2c_write_bytes( e->bus, e->command, SD_CARD_COMMAND_SIZE);
0525 RTEMS_CHECK_RV( rv, "Write stop transfer token");
0526
0527 return 0;
0528 }
0529
0530 static int sd_card_stop_multiple_block_write( sd_card_driver_entry *e)
0531 {
0532 int rv = 0;
0533 uint8_t stop_transfer [3] = { SD_CARD_IDLE_TOKEN, SD_CARD_STOP_TRANSFER_MULTIPLE_BLOCK_WRITE, SD_CARD_IDLE_TOKEN };
0534
0535
0536 rv = sd_card_wait( e);
0537 RTEMS_CHECK_RV( rv, "Wait");
0538
0539
0540 rv = rtems_libi2c_write_bytes( e->bus, stop_transfer, 3);
0541 RTEMS_CHECK_RV( rv, "Write stop transfer token");
0542
0543
0544 e->busy = true;
0545
0546 return 0;
0547 }
0548
0549 static int sd_card_read( sd_card_driver_entry *e, uint8_t start_token, uint8_t *in, int n)
0550 {
0551 int rv = 0;
0552
0553
0554 int r = e->response_index + 1;
0555
0556
0557 int response_size = SD_CARD_COMMAND_SIZE;
0558
0559
0560 uint8_t *response = e->response;
0561
0562
0563 int i = 0;
0564
0565
0566 uint16_t crc16;
0567
0568
0569 int retries = e->n_ac_max;
0570
0571 SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
0572
0573 while (true) {
0574 RTEMS_DEBUG_PRINT( "Search from %u to %u\n", r, response_size - 1);
0575
0576
0577 retries -= (response_size - r);
0578 while (r < response_size) {
0579 RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, response [r]);
0580 if (response [r] == start_token) {
0581
0582 ++r;
0583 goto sd_card_read_start;
0584 } else if (SD_CARD_IS_DATA_ERROR( response [r])) {
0585 RTEMS_SYSLOG_ERROR( "Data error token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
0586 return -RTEMS_IO_ERROR;
0587 } else if (response [r] != SD_CARD_IDLE_TOKEN) {
0588 RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
0589 return -RTEMS_IO_ERROR;
0590 }
0591 ++r;
0592 }
0593
0594 if (retries <= 0) {
0595 RTEMS_SYSLOG_ERROR( "Timeout\n");
0596 return -RTEMS_IO_ERROR;
0597 }
0598
0599 if (e->schedule_if_busy)
0600 rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
0601
0602
0603
0604
0605
0606 response = in;
0607 response_size = 50;
0608 if (response_size > n)
0609 response_size = n;
0610 rv = sd_card_query( e, response, response_size);
0611 RTEMS_CHECK_RV( rv, "Query data start token");
0612
0613
0614 r = 0;
0615 }
0616
0617 sd_card_read_start:
0618
0619
0620 while (r < response_size && i < n) {
0621 in [i++] = response [r++];
0622 }
0623
0624
0625 if (i < n) {
0626 rv = sd_card_query( e, &in [i], n - i);
0627 RTEMS_CHECK_RV( rv, "Read data");
0628 i += rv;
0629 }
0630
0631
0632 rv = sd_card_query( e, e->response, 3);
0633 RTEMS_CHECK_RV( rv, "Read CRC 16");
0634
0635 crc16 = sd_card_compute_crc16 (in, n);
0636 if ((e->response[0] != ((crc16 >> 8) & 0xff)) ||
0637 (e->response[1] != (crc16 & 0xff))) {
0638 RTEMS_SYSLOG_ERROR( "CRC check failed on read\n");
0639 return -RTEMS_IO_ERROR;
0640 }
0641
0642 return i;
0643 }
0644
0645 static int sd_card_write( sd_card_driver_entry *e, uint8_t start_token, uint8_t *out, int n)
0646 {
0647 int rv = 0;
0648 uint8_t crc16_bytes [2] = { 0, 0 };
0649 uint16_t crc16;
0650
0651
0652 int o = 0;
0653
0654
0655 rv = sd_card_wait( e);
0656 RTEMS_CHECK_RV( rv, "Wait");
0657
0658
0659 rv = rtems_libi2c_write_bytes( e->bus, &start_token, 1);
0660 RTEMS_CHECK_RV( rv, "Write data start token");
0661
0662
0663 o = rtems_libi2c_write_bytes( e->bus, out, n);
0664 RTEMS_CHECK_RV( o, "Write data");
0665
0666
0667 crc16 = sd_card_compute_crc16(out, n);
0668 crc16_bytes[0] = (crc16>>8) & 0xff;
0669 crc16_bytes[1] = (crc16) & 0xff;
0670 rv = rtems_libi2c_write_bytes( e->bus, crc16_bytes, 2);
0671 RTEMS_CHECK_RV( rv, "Write CRC 16");
0672
0673
0674 rv = sd_card_query( e, e->response, 2);
0675 RTEMS_CHECK_RV( rv, "Read data response");
0676 if (SD_CARD_IS_DATA_REJECTED( e->response [0])) {
0677 RTEMS_SYSLOG_ERROR( "Data rejected: 0x%02" PRIx8 "\n", e->response [0]);
0678 return -RTEMS_IO_ERROR;
0679 }
0680
0681
0682 e->busy = true;
0683
0684 return o;
0685 }
0686
0687 static inline rtems_status_code sd_card_start( sd_card_driver_entry *e)
0688 {
0689 rtems_status_code sc = RTEMS_SUCCESSFUL;
0690 int rv = 0;
0691
0692 sc = rtems_libi2c_send_start( e->bus);
0693 RTEMS_CHECK_SC( sc, "Send start");
0694
0695 rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
0696 RTEMS_CHECK_RV_SC( rv, "Set transfer mode");
0697
0698 sc = rtems_libi2c_send_addr( e->bus, 1);
0699 RTEMS_CHECK_SC( sc, "Send address");
0700
0701 return RTEMS_SUCCESSFUL;
0702 }
0703
0704 static inline rtems_status_code sd_card_stop( sd_card_driver_entry *e)
0705 {
0706 rtems_status_code sc = RTEMS_SUCCESSFUL;
0707
0708 sc = rtems_libi2c_send_stop( e->bus);
0709 RTEMS_CHECK_SC( sc, "Send stop");
0710
0711 return RTEMS_SUCCESSFUL;
0712 }
0713
0714 static rtems_status_code sd_card_init( sd_card_driver_entry *e)
0715 {
0716 rtems_status_code sc = RTEMS_SUCCESSFUL;
0717 int rv = 0;
0718 uint8_t block [SD_CARD_BLOCK_SIZE_DEFAULT];
0719 uint32_t transfer_speed = 0;
0720 uint32_t read_block_size = 0;
0721 uint32_t write_block_size = 0;
0722 uint8_t csd_structure = 0;
0723 uint64_t capacity = 0;
0724 uint8_t crc7;
0725
0726
0727 bool assume_sd = true;
0728
0729
0730
0731
0732
0733 bool high_capacity = true;
0734
0735 bool do_cmd58 = true;
0736 uint32_t cmd_arg = 0;
0737 uint32_t if_cond_test = SD_CARD_FLAG_VHS_2_7_TO_3_3 | SD_CARD_FLAG_CHECK_PATTERN;
0738 uint32_t if_cond_reg = if_cond_test;
0739
0740
0741 sc = sd_card_start( e);
0742 RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Start");
0743
0744
0745 rv = sd_card_wait( e);
0746 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Wait");
0747
0748
0749 memset( block, SD_CARD_IDLE_TOKEN, SD_CARD_BLOCK_SIZE_DEFAULT);
0750 rv = rtems_libi2c_write_bytes( e->bus, block, SD_CARD_BLOCK_SIZE_DEFAULT);
0751 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Active chip select delay");
0752
0753
0754 sc = sd_card_stop( e);
0755 RTEMS_CHECK_SC( sc, "Stop");
0756
0757
0758 sc = rtems_libi2c_send_start( e->bus);
0759 RTEMS_CHECK_SC( sc, "Send start");
0760
0761
0762 rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
0763 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Set transfer mode");
0764
0765
0766 rv = sd_card_query( e, e->response, SD_CARD_COMMAND_SIZE);
0767 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Inactive chip select delay");
0768
0769
0770 sc = rtems_libi2c_send_addr( e->bus, 1);
0771 RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Send address");
0772
0773
0774 sd_card_stop_multiple_block_write( e);
0775
0776
0777 sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
0778
0779
0780 sd_card_stop_multiple_block_read( e);
0781
0782
0783 rv = sd_card_send_command( e, SD_CARD_CMD_GO_IDLE_STATE, 0);
0784 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_GO_IDLE_STATE");
0785
0786
0787
0788
0789
0790
0791
0792
0793 rv = sd_card_send_register_command( e, SD_CARD_CMD_SEND_IF_COND, if_cond_reg, &if_cond_reg);
0794
0795
0796
0797
0798
0799
0800
0801 if (rv < 0) {
0802
0803 cmd_arg = 0;
0804 } else {
0805 cmd_arg = SD_CARD_FLAG_HCS;
0806 }
0807
0808
0809 sd_card_send_command( e, SD_CARD_CMD_CRC_ON_OFF, 1);
0810
0811
0812 while (true) {
0813 if (assume_sd) {
0814
0815 rv = sd_card_send_command( e, SD_CARD_CMD_APP_CMD, 0);
0816 if (rv < 0) {
0817 RTEMS_SYSLOG( "CMD55 failed. Assume MMC and try CMD1\n");
0818 assume_sd = false;
0819 continue;
0820 }
0821
0822
0823
0824
0825
0826 rv = sd_card_send_command( e, SD_CARD_ACMD_SD_SEND_OP_COND, cmd_arg);
0827 if (rv < 0) {
0828
0829
0830
0831
0832 RTEMS_SYSLOG( "ACMD41 failed. Assume MMC and do CMD58 (once) then CMD1\n");
0833 assume_sd = false;
0834 cmd_arg = SD_CARD_FLAG_HCS;
0835 do_cmd58 = true;
0836 continue;
0837 } else {
0838
0839
0840
0841
0842
0843 if (if_cond_reg != if_cond_test) {
0844 RTEMS_CLEANUP_RV_SC( -1, sc, sd_card_driver_init_cleanup, "Bad voltage for SD");
0845 }
0846 }
0847 } else {
0848
0849
0850
0851
0852
0853
0854
0855
0856 if (do_cmd58) {
0857 rv = sd_card_send_command( e, SD_CARD_CMD_READ_OCR, cmd_arg);
0858 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for MMC");
0859
0860
0861 do_cmd58 = false;
0862 }
0863
0864
0865 rv = sd_card_send_command( e, SD_CARD_CMD_SEND_OP_COND, 0);
0866 if (rv < 0) {
0867 if (cmd_arg != 0) {
0868
0869
0870
0871
0872
0873 cmd_arg = 0;
0874 do_cmd58 = true;
0875 high_capacity = false;
0876 continue;
0877 }
0878
0879 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed to initialize MMC");
0880 }
0881 }
0882
0883
0884
0885
0886
0887
0888
0889 if (SD_CARD_IS_NOT_IDLE_RESPONSE( e->response [e->response_index])) {
0890 break;
0891 }
0892
0893
0894 rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
0895 }
0896
0897
0898 if (assume_sd) {
0899 if (cmd_arg == 0) {
0900
0901 high_capacity = 0;
0902 } else {
0903 uint32_t reg = 0;
0904
0905
0906
0907
0908
0909
0910
0911 rv = sd_card_send_register_command( e, SD_CARD_CMD_READ_OCR, 0, ®);
0912 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for SD 2.x");
0913
0914
0915 high_capacity = (reg & SD_CARD_FLAG_HCS) != 0;
0916 }
0917 } else {
0918
0919
0920
0921
0922 if (high_capacity) {
0923 uint32_t reg = 0;
0924
0925
0926
0927
0928
0929 rv = sd_card_send_register_command( e, SD_CARD_CMD_READ_OCR, cmd_arg, ®);
0930 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for MMC 4.2");
0931
0932
0933 high_capacity = (reg & SD_CARD_FLAG_HCS) != 0;
0934 }
0935 }
0936
0937
0938 if (e->verbose) {
0939 rv = sd_card_send_command( e, SD_CARD_CMD_SEND_CID, 0);
0940 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SEND_CID");
0941 rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, block, SD_CARD_CID_SIZE);
0942 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Read: SD_CARD_CMD_SEND_CID");
0943 RTEMS_SYSLOG( "*** Card Identification ***\n");
0944 RTEMS_SYSLOG( "Manufacturer ID : %" PRIu8 "\n", SD_CARD_CID_GET_MID( block));
0945 RTEMS_SYSLOG( "OEM/Application ID : %" PRIu16 "\n", SD_CARD_CID_GET_OID( block));
0946 RTEMS_SYSLOG(
0947 "Product name : %c%c%c%c%c%c\n",
0948 SD_CARD_CID_GET_PNM( block, 0),
0949 SD_CARD_CID_GET_PNM( block, 1),
0950 SD_CARD_CID_GET_PNM( block, 2),
0951 SD_CARD_CID_GET_PNM( block, 3),
0952 SD_CARD_CID_GET_PNM( block, 4),
0953 SD_CARD_CID_GET_PNM( block, 5)
0954 );
0955 RTEMS_SYSLOG( "Product revision : %" PRIu8 "\n", SD_CARD_CID_GET_PRV( block));
0956 RTEMS_SYSLOG( "Product serial number : %" PRIu32 "\n", SD_CARD_CID_GET_PSN( block));
0957 RTEMS_SYSLOG( "Manufacturing date : %" PRIu8 "\n", SD_CARD_CID_GET_MDT( block));
0958 RTEMS_SYSLOG( "7-bit CRC checksum : %" PRIu8 "\n", SD_CARD_CID_GET_CRC7( block));
0959 crc7 = sd_card_compute_crc7( block, 15);
0960 if (crc7 != SD_CARD_CID_GET_CRC7( block))
0961 RTEMS_SYSLOG( " Failed! (computed %02" PRIx8 ")\n", crc7);
0962 }
0963
0964
0965
0966
0967 rv = sd_card_send_command( e, SD_CARD_CMD_SEND_CSD, 0);
0968 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SEND_CSD");
0969 rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, block, SD_CARD_CSD_SIZE);
0970 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Read: SD_CARD_CMD_SEND_CSD");
0971
0972 crc7 = sd_card_compute_crc7( block, 15);
0973 if (crc7 != SD_CARD_CID_GET_CRC7( block)) {
0974 RTEMS_SYSLOG( "SD_CARD_CMD_SEND_CSD CRC failed\n");
0975 sc = RTEMS_IO_ERROR;
0976 goto sd_card_driver_init_cleanup;
0977 }
0978
0979
0980 csd_structure = SD_CARD_CSD_GET_CSD_STRUCTURE( block);
0981
0982
0983 transfer_speed = sd_card_transfer_speed( block);
0984 e->transfer_mode.baudrate = transfer_speed;
0985 e->n_ac_max = sd_card_max_access_time( block, transfer_speed);
0986
0987
0988 if (csd_structure == 0 || !assume_sd) {
0989
0990
0991 read_block_size = 1U << SD_CARD_CSD_GET_READ_BLK_LEN( block);
0992 e->block_size_shift = SD_CARD_CSD_GET_WRITE_BLK_LEN( block);
0993 write_block_size = 1U << e->block_size_shift;
0994 if (read_block_size < write_block_size) {
0995 RTEMS_SYSLOG_ERROR( "Read block size smaller than write block size\n");
0996 return -RTEMS_IO_ERROR;
0997 }
0998 e->block_size = write_block_size;
0999 e->block_number = sd_card_block_number( block);
1000 capacity = sd_card_capacity( block);
1001 } else if (csd_structure == 1) {
1002 uint32_t c_size = SD_CARD_CSD_1_GET_C_SIZE( block);
1003
1004
1005 e->block_size_shift = 9;
1006 e->block_size = 512;
1007
1008 e->block_number = (c_size + 1) * 1024;
1009 capacity = (c_size + 1) * 512 * 1024;
1010 read_block_size = 512;
1011 write_block_size = 512;
1012
1013
1014 e->n_ac_max = transfer_speed / 80;
1015 } else {
1016 RTEMS_DO_CLEANUP_SC( RTEMS_IO_ERROR, sc, sd_card_driver_init_cleanup, "Unexpected CSD Structure number");
1017 }
1018
1019
1020 if (e->verbose) {
1021 RTEMS_SYSLOG( "*** Card Specific Data ***\n");
1022 RTEMS_SYSLOG( "CSD structure : %" PRIu8 "\n", SD_CARD_CSD_GET_CSD_STRUCTURE( block));
1023 RTEMS_SYSLOG( "Spec version : %" PRIu8 "\n", SD_CARD_CSD_GET_SPEC_VERS( block));
1024 RTEMS_SYSLOG( "Access time [ns] : %" PRIu32 "\n", sd_card_access_time( block));
1025 RTEMS_SYSLOG( "Access time [N] : %" PRIu32 "\n", SD_CARD_CSD_GET_NSAC( block)*100);
1026 RTEMS_SYSLOG( "Max access time [N] : %" PRIu32 "\n", e->n_ac_max);
1027 RTEMS_SYSLOG( "Max read block size [B] : %" PRIu32 "\n", read_block_size);
1028 RTEMS_SYSLOG( "Max write block size [B] : %" PRIu32 "\n", write_block_size);
1029 RTEMS_SYSLOG( "Block size [B] : %" PRIu32 "\n", e->block_size);
1030 RTEMS_SYSLOG( "Block number : %" PRIu32 "\n", e->block_number);
1031 RTEMS_SYSLOG( "Capacity [B] : %" PRIu64 "\n", capacity);
1032 RTEMS_SYSLOG( "Max transfer speed [b/s] : %" PRIu32 "\n", transfer_speed);
1033 }
1034
1035 if (high_capacity) {
1036
1037 e->block_size_shift = 0;
1038 } else if (e->block_size_shift == 10) {
1039
1040
1041
1042
1043
1044
1045 e->block_size_shift = 9;
1046 e->block_size = 512;
1047 e->block_number *= 2;
1048 }
1049
1050
1051 rv = sd_card_send_command( e, SD_CARD_CMD_SET_BLOCKLEN, e->block_size);
1052 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SET_BLOCKLEN");
1053
1054
1055 sc = sd_card_stop( e);
1056 RTEMS_CHECK_SC( sc, "Stop");
1057
1058 return RTEMS_SUCCESSFUL;
1059
1060 sd_card_driver_init_cleanup:
1061
1062
1063 sd_card_stop( e);
1064
1065 return sc;
1066 }
1067
1068
1069
1070
1071
1072
1073
1074 static int sd_card_disk_block_read( sd_card_driver_entry *e, rtems_blkdev_request *r)
1075 {
1076 rtems_status_code sc = RTEMS_SUCCESSFUL;
1077 int rv = 0;
1078 uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
1079 uint32_t i = 0;
1080
1081 #ifdef DEBUG
1082
1083 if (r->bufs[0].block >= e->block_number) {
1084 RTEMS_SYSLOG_ERROR( "Start block number out of range");
1085 return -RTEMS_INTERNAL_ERROR;
1086 } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
1087 RTEMS_SYSLOG_ERROR( "Block count out of range");
1088 return -RTEMS_INTERNAL_ERROR;
1089 }
1090 #endif
1091
1092
1093 sc = sd_card_start( e);
1094 RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_read_cleanup, "Start");
1095
1096 if (r->bufnum == 1) {
1097 #ifdef DEBUG
1098
1099 if (r->bufs [0].length != e->block_size) {
1100 RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_cleanup, "Buffer and disk block size are not equal");
1101 }
1102 RTEMS_DEBUG_PRINT( "[01:01]: buffer = 0x%08x, size = %u\n", r->bufs [0].buffer, r->bufs [0].length);
1103 #endif
1104
1105
1106 rv = sd_card_send_command( e, SD_CARD_CMD_READ_SINGLE_BLOCK, start_address);
1107 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Send: SD_CARD_CMD_READ_SINGLE_BLOCK");
1108 rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
1109 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Read: SD_CARD_CMD_READ_SINGLE_BLOCK");
1110 } else {
1111
1112 rv = sd_card_send_command( e, SD_CARD_CMD_READ_MULTIPLE_BLOCK, start_address);
1113 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Send: SD_CARD_CMD_READ_MULTIPLE_BLOCK");
1114
1115
1116 for (i = 0; i < r->bufnum; ++i) {
1117 #ifdef DEBUG
1118
1119 if (r->bufs [i].length != e->block_size) {
1120 RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_stop_cleanup, "Buffer and disk block size are not equal");
1121 }
1122 RTEMS_DEBUG_PRINT( "[%02u:%02u]: buffer = 0x%08x, size = %u\n", i + 1, r->bufnum, r->bufs [i].buffer, r->bufs [i].length);
1123 #endif
1124
1125 rv = sd_card_read( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
1126 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Read block");
1127 }
1128
1129
1130 rv = sd_card_stop_multiple_block_read( e);
1131 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Stop multiple block read");
1132 }
1133
1134
1135 sc = sd_card_stop( e);
1136 RTEMS_CHECK_SC_RV( sc, "Stop");
1137
1138
1139 rtems_blkdev_request_done( r, RTEMS_SUCCESSFUL);
1140
1141 return 0;
1142
1143 sd_card_disk_block_read_stop_cleanup:
1144
1145
1146 sd_card_stop_multiple_block_read( e);
1147
1148 sd_card_disk_block_read_cleanup:
1149
1150
1151 sd_card_stop( e);
1152
1153
1154 rtems_blkdev_request_done( r, RTEMS_IO_ERROR);
1155
1156 return 0;
1157 }
1158
1159 static int sd_card_disk_block_write( sd_card_driver_entry *e, rtems_blkdev_request *r)
1160 {
1161 rtems_status_code sc = RTEMS_SUCCESSFUL;
1162 int rv = 0;
1163 uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
1164 uint32_t i = 0;
1165
1166 #ifdef DEBUG
1167
1168 if (r->bufs[0].block >= e->block_number) {
1169 RTEMS_SYSLOG_ERROR( "Start block number out of range");
1170 return -RTEMS_INTERNAL_ERROR;
1171 } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
1172 RTEMS_SYSLOG_ERROR( "Block count out of range");
1173 return -RTEMS_INTERNAL_ERROR;
1174 }
1175 #endif
1176
1177
1178 sc = sd_card_start( e);
1179 RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_write_cleanup, "Start");
1180
1181 if (r->bufnum == 1) {
1182 #ifdef DEBUG
1183
1184 if (r->bufs [0].length != e->block_size) {
1185 RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_cleanup, "Buffer and disk block size are not equal");
1186 }
1187 RTEMS_DEBUG_PRINT( "[01:01]: buffer = 0x%08x, size = %u\n", r->bufs [0].buffer, r->bufs [0].length);
1188 #endif
1189
1190
1191 rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_BLOCK, start_address);
1192 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Send: SD_CARD_CMD_WRITE_BLOCK");
1193 rv = sd_card_write( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
1194 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Write: SD_CARD_CMD_WRITE_BLOCK");
1195 } else {
1196
1197 rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_MULTIPLE_BLOCK, start_address);
1198 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Send: SD_CARD_CMD_WRITE_MULTIPLE_BLOCK");
1199
1200
1201 for (i = 0; i < r->bufnum; ++i) {
1202 #ifdef DEBUG
1203
1204 if (r->bufs [i].length != e->block_size) {
1205 RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_stop_cleanup, "Buffer and disk block size are not equal");
1206 }
1207 RTEMS_DEBUG_PRINT( "[%02u:%02u]: buffer = 0x%08x, size = %u\n", i + 1, r->bufnum, r->bufs [i].buffer, r->bufs [i].length);
1208 #endif
1209
1210 rv = sd_card_write( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
1211 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Write block");
1212 }
1213
1214
1215 rv = sd_card_stop_multiple_block_write( e);
1216 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Stop multiple block write");
1217 }
1218
1219
1220 rv = sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
1221 RTEMS_CHECK_RV( rv, "Send: SD_CARD_CMD_SEND_STATUS");
1222
1223
1224 sc = sd_card_stop( e);
1225 RTEMS_CHECK_SC_RV( sc, "Stop");
1226
1227
1228 rtems_blkdev_request_done( r, RTEMS_SUCCESSFUL);
1229
1230 return 0;
1231
1232 sd_card_disk_block_write_stop_cleanup:
1233
1234
1235 sd_card_stop_multiple_block_write( e);
1236
1237 sd_card_disk_block_write_cleanup:
1238
1239
1240 rv = sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
1241 RTEMS_CHECK_RV( rv, "Send: SD_CARD_CMD_SEND_STATUS");
1242
1243
1244 sd_card_stop( e);
1245
1246
1247 rtems_blkdev_request_done( r, RTEMS_IO_ERROR);
1248
1249 return 0;
1250 }
1251
1252 static int sd_card_disk_ioctl( rtems_disk_device *dd, uint32_t req, void *arg)
1253 {
1254 RTEMS_DEBUG_PRINT( "sd_card_disk_ioctl req = 0x%08x, arg = %p\n", (unsigned)req, arg);
1255 if (req == RTEMS_BLKIO_REQUEST) {
1256 sd_card_driver_entry *e = rtems_disk_get_driver_data( dd);
1257 rtems_blkdev_request *r = (rtems_blkdev_request *) arg;
1258 int (*f)( sd_card_driver_entry *, rtems_blkdev_request *);
1259 uint32_t retries = e->retries;
1260 int result;
1261
1262 switch (r->req) {
1263 case RTEMS_BLKDEV_REQ_READ:
1264 f = sd_card_disk_block_read;
1265 break;
1266 case RTEMS_BLKDEV_REQ_WRITE:
1267 f = sd_card_disk_block_write;
1268 break;
1269 default:
1270 errno = EINVAL;
1271 return -1;
1272 }
1273 do {
1274 result = f( e, r);
1275 } while (retries-- > 0 && result != 0);
1276 return result;
1277
1278 } else if (req == RTEMS_BLKIO_CAPABILITIES) {
1279 *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
1280 return 0;
1281 } else {
1282 return rtems_blkdev_ioctl( dd, req, arg );
1283 }
1284 }
1285
1286 rtems_status_code sd_card_register( void)
1287 {
1288 size_t i;
1289
1290 for (i = 0; i < sd_card_driver_table_size; ++i) {
1291 sd_card_driver_entry *e = &sd_card_driver_table [i];
1292 uint32_t retries = e->retries;
1293 rtems_status_code sc;
1294
1295
1296 do {
1297 sc = sd_card_init( e);
1298 } while (retries-- > 0 && sc != RTEMS_SUCCESSFUL);
1299 RTEMS_CHECK_SC( sc, "Initialize SD Card");
1300
1301
1302 sc = rtems_blkdev_create( e->device_name, e->block_size, e->block_number, sd_card_disk_ioctl, NULL);
1303 RTEMS_CHECK_SC( sc, "Create disk device");
1304 }
1305
1306 return RTEMS_SUCCESSFUL;
1307 }