Changeset 9814d2dd in rtems


Ignore:
Timestamp:
Dec 23, 2008, 8:31:47 AM (10 years ago)
Author:
Thomas Doerfler <Thomas.Doerfler@…>
Branches:
4.10, 4.11, master
Children:
85c429b
Parents:
c51f900b
Message:

spi-sd-card.c, spi-sd-card.h: removed high-level driver IF, added generic block I/O functions

Location:
c/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/ChangeLog

    rc51f900b r9814d2dd  
     12008-11-23      Sebastian Huber <sebastian.huber@embedded-brains.de>
     2
     3        * libchip/i2c/spi-sd-card.h, libchip/i2c/spi-sd-card.c: Removed high
     4        level LibI2C interface.  Added generic block IO functions.
     5
    162008-12-22      Ralf Corsépius <ralf.corsepius@rtems.org>
    27
  • c/src/libchip/i2c/spi-sd-card.c

    rc51f900b r9814d2dd  
    298298static inline int sd_card_query( sd_card_driver_entry *e, uint8_t *in, int n)
    299299{
    300         return rtems_libi2c_read_bytes( e->minor, in, n);
     300        return rtems_libi2c_read_bytes( e->bus, in, n);
    301301}
    302302
     
    347347        SD_CARD_COMMAND_SET_COMMAND( e->command, command);
    348348        SD_CARD_COMMAND_SET_ARGUMENT( e->command, argument);
    349         rv = rtems_libi2c_ioctl( e->minor, RTEMS_LIBI2C_IOCTL_READ_WRITE, &rw);
     349        rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_READ_WRITE, &rw);
    350350        RTEMS_CHECK_RV( rv, "Write command and read response");
    351351
     
    389389
    390390        SD_CARD_COMMAND_SET_COMMAND( e->command, SD_CARD_CMD_STOP_TRANSMISSION);
    391         rv = rtems_libi2c_write_bytes( e->minor, e->command, SD_CARD_COMMAND_SIZE);
     391        rv = rtems_libi2c_write_bytes( e->bus, e->command, SD_CARD_COMMAND_SIZE);
    392392        RTEMS_CHECK_RV( rv, "Write stop transfer token");
    393393
     
    405405
    406406        /* Send stop token */
    407         rv = rtems_libi2c_write_bytes( e->minor, stop_transfer, 3);
     407        rv = rtems_libi2c_write_bytes( e->bus, stop_transfer, 3);
    408408        RTEMS_CHECK_RV( rv, "Write stop transfer token");
    409409
     
    435435        SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
    436436
    437         while (1) {
     437        while (true) {
    438438                RTEMS_DEBUG_PRINT( "Search from %u to %u\n", r, response_size - 1);
    439439
     
    505505
    506506        /* Write data start token */
    507         rv = rtems_libi2c_write_bytes( e->minor, &start_token, 1);
     507        rv = rtems_libi2c_write_bytes( e->bus, &start_token, 1);
    508508        RTEMS_CHECK_RV( rv, "Write data start token");
    509509
    510510        /* Write data */
    511         o = rtems_libi2c_write_bytes( e->minor, out, n);
     511        o = rtems_libi2c_write_bytes( e->bus, out, n);
    512512        RTEMS_CHECK_RV( o, "Write data");
    513513
    514514        /* Write CRC 16 */
    515         rv = rtems_libi2c_write_bytes( e->minor, crc16, 2);
     515        rv = rtems_libi2c_write_bytes( e->bus, crc16, 2);
    516516        RTEMS_CHECK_RV( rv, "Write CRC 16");
    517517
     
    535535        int rv = 0;
    536536
    537         sc = rtems_libi2c_send_start( e->minor);
     537        sc = rtems_libi2c_send_start( e->bus);
    538538        RTEMS_CHECK_SC( sc, "Send start");
    539539
    540         rv = rtems_libi2c_ioctl( e->minor, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
     540        rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
    541541        RTEMS_CHECK_RV_SC( rv, "Set transfer mode");
    542542
    543         sc = rtems_libi2c_send_addr( e->minor, 1);
     543        sc = rtems_libi2c_send_addr( e->bus, 1);
    544544        RTEMS_CHECK_SC( sc, "Send address");
    545545
     
    551551        rtems_status_code sc = RTEMS_SUCCESSFUL;
    552552
    553         sc = rtems_libi2c_send_stop( e->minor);
     553        sc = rtems_libi2c_send_stop( e->bus);
    554554        RTEMS_CHECK_SC( sc, "Send stop");
    555555
    556556        return RTEMS_SUCCESSFUL;
    557557}
    558 /** @} */
    559 
    560 /**
    561  * @name Disk Driver Functions
    562  * @{
    563  */
    564 
    565 static int sd_card_disk_block_read( sd_card_driver_entry *e, rtems_blkdev_request *r)
     558
     559static rtems_status_code sd_card_init( sd_card_driver_entry *e)
    566560{
    567561        rtems_status_code sc = RTEMS_SUCCESSFUL;
    568562        int rv = 0;
    569         uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
    570         uint32_t i = 0;
    571 
    572         RTEMS_DEBUG_PRINT( "start = %u, bufnum = %u\n", r->start, r->bufnum);
    573 
    574 #ifdef DEBUG
    575         /* Check request */
    576   if (r->bufs[0].block >= e->block_number) {
    577                 RTEMS_SYSLOG_ERROR( "Start block number out of range");
    578                 return -RTEMS_INTERNAL_ERROR;
    579         } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
    580                 RTEMS_SYSLOG_ERROR( "Block count out of range");
    581                 return -RTEMS_INTERNAL_ERROR;
    582         }
    583 #endif /* DEBUG */
    584 
    585         /* Start */
    586         sc = sd_card_start( e);
    587         RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_read_cleanup, "Start");
    588 
    589         if (r->bufnum == 1) {
    590 #ifdef DEBUG
    591                 /* Check buffer */
    592                 if (r->bufs [0].length != e->block_size) {
    593                         RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_cleanup, "Buffer and disk block size are not equal");
    594                 }
    595                 RTEMS_DEBUG_PRINT( "[%02u]: buffer = 0x%08x, size = %u\n", 0, r->bufs [0].buffer, r->bufs [0].length);
    596 #endif /* DEBUG */
    597 
    598                 /* Single block read */
    599                 rv = sd_card_send_command( e, SD_CARD_CMD_READ_SINGLE_BLOCK, start_address);
    600                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Send: SD_CARD_CMD_READ_SINGLE_BLOCK");
    601                 rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
    602                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Read: SD_CARD_CMD_READ_SINGLE_BLOCK");
    603         } else {
    604                 /* Start multiple block read */
    605                 rv = sd_card_send_command( e, SD_CARD_CMD_READ_MULTIPLE_BLOCK, start_address);
    606                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Send: SD_CARD_CMD_READ_MULTIPLE_BLOCK");
    607 
    608                 /* Multiple block read */
    609                 for (i = 0; i < r->bufnum; ++i) {
    610 #ifdef DEBUG
    611                         /* Check buffer */
    612                         if (r->bufs [i].length != e->block_size) {
    613                                 RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_stop_cleanup, "Buffer and disk block size are not equal");
    614                         }
    615                         RTEMS_DEBUG_PRINT( "[%02u]: buffer = 0x%08x, size = %u\n", i, r->bufs [i].buffer, r->bufs [i].length);
    616 #endif /* DEBUG */
    617 
    618                         rv = sd_card_read( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
    619                         RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Read block");
    620                 }
    621 
    622                 /* Stop multiple block read */
    623                 rv = sd_card_stop_multiple_block_read( e);
    624                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Stop multiple block read");
    625         }
    626 
    627         /* Stop */
    628         sc = sd_card_stop( e);
    629         RTEMS_CHECK_SC_RV( sc, "Stop");
    630 
    631         /* Done */
    632         r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
    633 
    634         return 0;
    635 
    636 sd_card_disk_block_read_stop_cleanup:
    637 
    638         /* Stop multiple block read */
    639         sd_card_stop_multiple_block_read( e);
    640 
    641 sd_card_disk_block_read_cleanup:
    642 
    643         /* Stop */
    644         sd_card_stop( e);
    645 
    646         /* Done */
    647         r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
    648 
    649         return rv;
    650 }
    651 
    652 static int sd_card_disk_block_write( sd_card_driver_entry *e, rtems_blkdev_request *r)
    653 {
    654         rtems_status_code sc = RTEMS_SUCCESSFUL;
    655         int rv = 0;
    656         uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
    657         uint32_t i = 0;
    658 
    659         RTEMS_DEBUG_PRINT( "start = %u, count = %u, bufnum = %u\n", r->start, r->count, r->bufnum);
    660 
    661 #ifdef DEBUG
    662         /* Check request */
    663   if (r->bufs[0].block >= e->block_number) {
    664                 RTEMS_SYSLOG_ERROR( "Start block number out of range");
    665                 return -RTEMS_INTERNAL_ERROR;
    666         } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
    667                 RTEMS_SYSLOG_ERROR( "Block count out of range");
    668                 return -RTEMS_INTERNAL_ERROR;
    669         }
    670 #endif /* DEBUG */
    671 
    672         /* Start */
    673         sc = sd_card_start( e);
    674         RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_write_cleanup, "Start");
    675 
    676         if (r->bufnum == 1) {
    677 #ifdef DEBUG
    678                 /* Check buffer */
    679                 if (r->bufs [0].length != e->block_size) {
    680                         RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_cleanup, "Buffer and disk block size are not equal");
    681                 }
    682                 RTEMS_DEBUG_PRINT( "[%02u]: buffer = 0x%08x, size = %u\n", 0, r->bufs [0].buffer, r->bufs [0].length);
    683 #endif /* DEBUG */
    684 
    685                 /* Single block write */
    686                 rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_BLOCK, start_address);
    687                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Send: SD_CARD_CMD_WRITE_BLOCK");
    688                 rv = sd_card_write( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
    689                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Write: SD_CARD_CMD_WRITE_BLOCK");
    690         } else {
    691                 /* Start multiple block write */
    692                 rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_MULTIPLE_BLOCK, start_address);
    693                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Send: SD_CARD_CMD_WRITE_MULTIPLE_BLOCK");
    694 
    695                 /* Multiple block write */
    696                 for (i = 0; i < r->bufnum; ++i) {
    697 #ifdef DEBUG
    698                         /* Check buffer */
    699                         if (r->bufs [i].length != e->block_size) {
    700                                 RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_stop_cleanup, "Buffer and disk block size are not equal");
    701                         }
    702                         RTEMS_DEBUG_PRINT( "[%02u]: buffer = 0x%08x, size = %u\n", i, r->bufs [i].buffer, r->bufs [i].length);
    703 #endif /* DEBUG */
    704 
    705                         rv = sd_card_write( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
    706                         RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Write block");
    707                 }
    708 
    709                 /* Stop multiple block write */
    710                 rv = sd_card_stop_multiple_block_write( e);
    711                 RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Stop multiple block write");
    712         }
    713 
    714         /* Get card status */
    715         rv = sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
    716         RTEMS_CHECK_RV( rv, "Send: SD_CARD_CMD_SEND_STATUS");
    717 
    718         /* Stop */
    719         sc = sd_card_stop( e);
    720         RTEMS_CHECK_SC_RV( sc, "Stop");
    721 
    722         /* Done */
    723         r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
    724 
    725         return 0;
    726 
    727 sd_card_disk_block_write_stop_cleanup:
    728 
    729         /* Stop multiple block write */
    730         sd_card_stop_multiple_block_write( e);
    731 
    732 sd_card_disk_block_write_cleanup:
    733 
    734         /* Get card status */
    735         rv = sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
    736         RTEMS_CHECK_RV( rv, "Send: SD_CARD_CMD_SEND_STATUS");
    737 
    738         /* Stop */
    739         sd_card_stop( e);
    740 
    741         /* Done */
    742         r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
    743 
    744         return rv;
    745 }
    746 
    747 static int sd_card_disk_ioctl( dev_t dev, uint32_t req, void *arg)
    748 {
    749         RTEMS_DEBUG_PRINT( "dev = %u, req = %u, arg = 0x08%x\n", dev, req, arg);
    750         if (req == RTEMS_BLKIO_REQUEST) {
    751                 rtems_device_minor_number minor = rtems_filesystem_dev_minor_t( dev);
    752                 sd_card_driver_entry *e = &sd_card_driver_table [minor];
    753                 rtems_blkdev_request *r = (rtems_blkdev_request *) arg;
    754                 switch (r->req) {
    755                         case RTEMS_BLKDEV_REQ_READ:
    756                                 return sd_card_disk_block_read( e, r);
    757                         case RTEMS_BLKDEV_REQ_WRITE:
    758                                 return sd_card_disk_block_write( e, r);
    759                         case RTEMS_BLKDEV_CAPABILITIES:
    760                                 *((uint32_t*) arg)  = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
    761                                 return 0;
    762                         default:
    763                                 errno = EBADRQC;
    764                                 return -1;
    765                 }
    766         } else {
    767                 errno = EBADRQC;
    768                 return -1;
    769         }
    770 }
    771 
    772 static rtems_status_code sd_card_disk_init( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    773 {
    774         /* Do nothing */
    775 
    776         return RTEMS_SUCCESSFUL;
    777 }
    778 
    779 /** @} */
    780 
    781 static const rtems_driver_address_table sd_card_disk_ops = {
    782         .initialization_entry = sd_card_disk_init,
    783         .open_entry = NULL,
    784         .close_entry = NULL,
    785         .read_entry = NULL,
    786         .write_entry = NULL,
    787         .control_entry = NULL
    788 };
    789 
    790 static rtems_device_major_number sd_card_disk_major = 0;
    791 
    792 static int sd_card_driver_first = 1;
    793 
    794 /**
    795  * @name LibI2C Driver Functions
    796  * @{
    797  */
    798 
    799 static inline int sd_card_driver_get_entry( rtems_device_minor_number minor, sd_card_driver_entry **e)
    800 {
    801         return rtems_libi2c_ioctl( minor, RTEMS_LIBI2C_IOCTL_GET_DRV_T, e);
    802 }
    803 
    804 static rtems_status_code sd_card_driver_init( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
    805 {
    806         rtems_status_code sc = RTEMS_SUCCESSFUL;
    807         int rv = 0;
    808         sd_card_driver_entry *e = NULL;
    809563        uint8_t block [SD_CARD_BLOCK_SIZE_DEFAULT];
    810564        uint32_t transfer_speed = 0;
    811565        uint32_t read_block_size = 0;
    812566        uint32_t write_block_size = 0;
    813         dev_t dev = 0;
    814 
    815         /* Get driver entry */
    816         rv = sd_card_driver_get_entry( minor, &e);
    817         RTEMS_CHECK_RV_SC( rv, "Get driver entry");
    818567
    819568        /* Start */
     
    821570        RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Start");
    822571
    823         /* Save minor number for disk operations */
    824         e->minor = minor;
    825 
    826         /* Register disk driver */
    827         if (sd_card_driver_first) {
    828                 sd_card_driver_first = 0;
    829                 sc = rtems_io_register_driver( 0, &sd_card_disk_ops, &sd_card_disk_major);
    830                 RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Register disk IO driver");
    831         }
    832 
    833572        /* Wait until card is not busy */
    834573        rv = sd_card_wait( e);
     
    837576        /* Send idle tokens for at least 74 clock cycles with active chip select */
    838577        memset( block, SD_CARD_IDLE_TOKEN, SD_CARD_BLOCK_SIZE_DEFAULT);
    839         rv = rtems_libi2c_write_bytes( e->minor, block, SD_CARD_BLOCK_SIZE_DEFAULT);
     578        rv = rtems_libi2c_write_bytes( e->bus, block, SD_CARD_BLOCK_SIZE_DEFAULT);
    840579        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Active chip select delay");
    841580
     
    845584
    846585        /* Start with inactive chip select */
    847         sc = rtems_libi2c_send_start( e->minor);
     586        sc = rtems_libi2c_send_start( e->bus);
    848587        RTEMS_CHECK_SC( sc, "Send start");
    849588
    850589        /* Set transfer mode */
    851         rv = rtems_libi2c_ioctl( e->minor, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
     590        rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
    852591        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Set transfer mode");
    853592
     
    857596
    858597        /* Activate chip select */
    859         sc = rtems_libi2c_send_addr( e->minor, 1);
     598        sc = rtems_libi2c_send_addr( e->bus, 1);
    860599        RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Send address");
    861600
     
    874613
    875614        /* Initialize card */
    876         while (1) {
     615        while (true) {
    877616                rv = sd_card_send_command( e, SD_CARD_CMD_APP_CMD, 0);
    878617                RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_APP_CMD");
     
    948687        RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SET_BLOCKLEN");
    949688
    950         /* Create disk device */
    951         dev = rtems_filesystem_make_dev_t( sd_card_disk_major, (rtems_device_minor_number) e->table_index);
    952         sc = rtems_disk_io_initialize();
    953         RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Initialize RTEMS disk IO");
    954         sc = rtems_disk_create_phys( dev, (int) e->block_size, (int) e->block_number, sd_card_disk_ioctl, e->disk_device_name);
    955         RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Create disk device");
    956 
    957689        /* Stop */
    958690        sc = sd_card_stop( e);
     
    968700        return sc;
    969701}
    970 
    971 static rtems_status_code sd_card_driver_read( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     702/** @} */
     703
     704/**
     705 * @name Disk Driver Functions
     706 * @{
     707 */
     708
     709static int sd_card_disk_block_read( sd_card_driver_entry *e, rtems_blkdev_request *r)
    972710{
    973711        rtems_status_code sc = RTEMS_SUCCESSFUL;
    974712        int rv = 0;
    975         rtems_libio_rw_args_t *rw = (rtems_libio_rw_args_t *) arg;
    976         sd_card_driver_entry *e = NULL;
    977         uint32_t block_size_mask = 0;
    978         uint32_t block_count = 0;
    979         uint32_t start_block = 0;
     713        uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
    980714        uint32_t i = 0;
    981715
    982         /* Clear moved bytes counter */
    983         rw->bytes_moved = 0;
    984 
    985         /* Get driver entry */
    986         rv = sd_card_driver_get_entry( minor, &e);
    987         RTEMS_CHECK_RV_SC( rv, "Get driver entry");
     716#ifdef DEBUG
     717        /* Check request */
     718        if (r->bufs[0].block >= e->block_number) {
     719                RTEMS_SYSLOG_ERROR( "Start block number out of range");
     720                return -RTEMS_INTERNAL_ERROR;
     721        } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
     722                RTEMS_SYSLOG_ERROR( "Block count out of range");
     723                return -RTEMS_INTERNAL_ERROR;
     724        }
     725#endif /* DEBUG */
    988726
    989727        /* Start */
    990728        sc = sd_card_start( e);
    991         RTEMS_CLEANUP_SC( sc, sd_card_driver_read_cleanup, "Start");
    992 
    993         /* Check arguments */
    994         block_size_mask = e->block_size - 1;
    995         block_count = (uint32_t) rw->count >> e->block_size_shift;
    996         start_block = (uint32_t) rw->offset >> e->block_size_shift;
    997         if (rw->offset & block_size_mask) {
    998                 RTEMS_DO_CLEANUP_SC( RTEMS_INVALID_ADDRESS, sc, sd_card_driver_read_cleanup, "Invalid offset");
    999         } else if ((rw->count & block_size_mask) || (start_block >= e->block_number) || (block_count > e->block_number - start_block)) {
    1000                 RTEMS_DO_CLEANUP_SC( RTEMS_INVALID_NUMBER, sc, sd_card_driver_read_cleanup, "Invalid count or out of range");
    1001         }
    1002 
    1003         if (block_count == 0) {
    1004                 /* Do nothing */
    1005         } else if (block_count == 1) {
     729        RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_read_cleanup, "Start");
     730
     731        if (r->bufnum == 1) {
     732#ifdef DEBUG
     733                /* Check buffer */
     734                if (r->bufs [0].length != e->block_size) {
     735                        RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_cleanup, "Buffer and disk block size are not equal");
     736                }
     737                RTEMS_DEBUG_PRINT( "[01:01]: buffer = 0x%08x, size = %u\n", r->bufs [0].buffer, r->bufs [0].length);
     738#endif /* DEBUG */
     739
    1006740                /* Single block read */
    1007                 rv = sd_card_send_command( e, SD_CARD_CMD_READ_SINGLE_BLOCK, (uint32_t) rw->offset);
    1008                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_read_cleanup, "Send: SD_CARD_CMD_READ_SINGLE_BLOCK");
    1009                 rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, (uint8_t *) rw->buffer, (int) e->block_size);
    1010                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_read_cleanup, "Read: SD_CARD_CMD_READ_SINGLE_BLOCK");
    1011 
    1012                 /* Set moved bytes counter */
    1013                 rw->bytes_moved = (uint32_t) rv;
     741                rv = sd_card_send_command( e, SD_CARD_CMD_READ_SINGLE_BLOCK, start_address);
     742                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Send: SD_CARD_CMD_READ_SINGLE_BLOCK");
     743                rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
     744                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Read: SD_CARD_CMD_READ_SINGLE_BLOCK");
    1014745        } else {
    1015746                /* Start multiple block read */
    1016                 rv = sd_card_send_command( e, SD_CARD_CMD_READ_MULTIPLE_BLOCK, (uint32_t) rw->offset);
    1017                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_read_stop_cleanup, "Send: SD_CARD_CMD_READ_MULTIPLE_BLOCK");
     747                rv = sd_card_send_command( e, SD_CARD_CMD_READ_MULTIPLE_BLOCK, start_address);
     748                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Send: SD_CARD_CMD_READ_MULTIPLE_BLOCK");
    1018749
    1019750                /* Multiple block read */
    1020                 for (i = 0; i < block_count; ++i) {
    1021                         rv = sd_card_read( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ, (uint8_t *) rw->buffer + (i << e->block_size_shift), (int) e->block_size);
    1022                         RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_read_stop_cleanup, "Read block");
    1023 
    1024                         /* Update moved bytes counter */
    1025                         rw->bytes_moved += (uint32_t) rv;
     751                for (i = 0; i < r->bufnum; ++i) {
     752#ifdef DEBUG
     753                        /* Check buffer */
     754                        if (r->bufs [i].length != e->block_size) {
     755                                RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_stop_cleanup, "Buffer and disk block size are not equal");
     756                        }
     757                        RTEMS_DEBUG_PRINT( "[%02u:%02u]: buffer = 0x%08x, size = %u\n", i + 1, r->bufnum, r->bufs [i].buffer, r->bufs [i].length);
     758#endif /* DEBUG */
     759
     760                        rv = sd_card_read( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
     761                        RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Read block");
    1026762                }
    1027763
    1028764                /* Stop multiple block read */
    1029765                rv = sd_card_stop_multiple_block_read( e);
    1030                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_read_cleanup, "Stop multiple block read");
     766                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Stop multiple block read");
    1031767        }
    1032768
    1033769        /* Stop */
    1034770        sc = sd_card_stop( e);
    1035         RTEMS_CHECK_SC( sc, "Stop");
    1036 
    1037         return RTEMS_SUCCESSFUL;
    1038 
    1039 sd_card_driver_read_stop_cleanup:
     771        RTEMS_CHECK_SC_RV( sc, "Stop");
     772
     773        /* Done */
     774        r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
     775
     776        return 0;
     777
     778sd_card_disk_block_read_stop_cleanup:
    1040779
    1041780        /* Stop multiple block read */
    1042781        sd_card_stop_multiple_block_read( e);
    1043782
    1044 sd_card_driver_read_cleanup:
     783sd_card_disk_block_read_cleanup:
    1045784
    1046785        /* Stop */
    1047786        sd_card_stop( e);
    1048787
    1049         return sc;
    1050 }
    1051 
    1052 static rtems_status_code sd_card_driver_write( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     788        /* Done */
     789        r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
     790
     791        return rv;
     792}
     793
     794static int sd_card_disk_block_write( sd_card_driver_entry *e, rtems_blkdev_request *r)
    1053795{
    1054796        rtems_status_code sc = RTEMS_SUCCESSFUL;
    1055797        int rv = 0;
    1056         rtems_libio_rw_args_t *rw = (rtems_libio_rw_args_t *) arg;
    1057         sd_card_driver_entry *e = NULL;
    1058         uint32_t block_size_mask = 0;
    1059         uint32_t block_count = 0;
    1060         uint32_t start_block = 0;
     798        uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
    1061799        uint32_t i = 0;
    1062800
    1063         /* Clear moved bytes counter */
    1064         rw->bytes_moved = 0;
    1065 
    1066         /* Get driver entry */
    1067         rv = sd_card_driver_get_entry( minor, &e);
    1068         RTEMS_CHECK_RV_SC( rv, "Get driver entry");
     801#ifdef DEBUG
     802        /* Check request */
     803        if (r->bufs[0].block >= e->block_number) {
     804                RTEMS_SYSLOG_ERROR( "Start block number out of range");
     805                return -RTEMS_INTERNAL_ERROR;
     806        } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
     807                RTEMS_SYSLOG_ERROR( "Block count out of range");
     808                return -RTEMS_INTERNAL_ERROR;
     809        }
     810#endif /* DEBUG */
    1069811
    1070812        /* Start */
    1071813        sc = sd_card_start( e);
    1072         RTEMS_CLEANUP_SC( sc, sd_card_driver_write_cleanup, "Start");
    1073 
    1074         /* Check arguments */
    1075         block_size_mask = e->block_size - 1;
    1076         block_count = (uint32_t) rw->count >> e->block_size_shift;
    1077         start_block = (uint32_t) rw->offset >> e->block_size_shift;
    1078         if (rw->offset & block_size_mask) {
    1079                 RTEMS_DO_CLEANUP_SC( RTEMS_INVALID_ADDRESS, sc, sd_card_driver_write_cleanup, "Invalid offset");
    1080         } else if ((rw->count & block_size_mask) || (start_block >= e->block_number) || (block_count > e->block_number - start_block)) {
    1081                 RTEMS_DO_CLEANUP_SC( RTEMS_INVALID_NUMBER, sc, sd_card_driver_write_cleanup, "Invalid count or out of range");
    1082         }
    1083 
    1084         if (block_count == 0) {
    1085                 /* Do nothing */
    1086         } else if (block_count == 1) {
     814        RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_write_cleanup, "Start");
     815
     816        if (r->bufnum == 1) {
     817#ifdef DEBUG
     818                /* Check buffer */
     819                if (r->bufs [0].length != e->block_size) {
     820                        RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_cleanup, "Buffer and disk block size are not equal");
     821                }
     822                RTEMS_DEBUG_PRINT( "[01:01]: buffer = 0x%08x, size = %u\n", r->bufs [0].buffer, r->bufs [0].length);
     823#endif /* DEBUG */
     824
    1087825                /* Single block write */
    1088                 rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_BLOCK, (uint32_t) rw->offset);
    1089                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_write_cleanup, "Send: SD_CARD_CMD_WRITE_BLOCK");
    1090                 rv = sd_card_write( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE, (uint8_t *) rw->buffer, (int) e->block_size);
    1091                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_write_cleanup, "Write: SD_CARD_CMD_WRITE_BLOCK");
    1092 
    1093                 /* Set moved bytes counter */
    1094                 rw->bytes_moved = (uint32_t) rv;
     826                rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_BLOCK, start_address);
     827                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Send: SD_CARD_CMD_WRITE_BLOCK");
     828                rv = sd_card_write( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
     829                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Write: SD_CARD_CMD_WRITE_BLOCK");
    1095830        } else {
    1096831                /* Start multiple block write */
    1097                 rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_MULTIPLE_BLOCK, (uint32_t) rw->offset);
    1098                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_write_stop_cleanup, "Send: SD_CARD_CMD_WRITE_MULTIPLE_BLOCK");
     832                rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_MULTIPLE_BLOCK, start_address);
     833                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Send: SD_CARD_CMD_WRITE_MULTIPLE_BLOCK");
    1099834
    1100835                /* Multiple block write */
    1101                 for (i = 0; i < block_count; ++i) {
    1102                         rv = sd_card_write( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE, (uint8_t *) rw->buffer + (i << e->block_size_shift), (int) e->block_size);
    1103                         RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_write_stop_cleanup, "Write: SD_CARD_CMD_WRITE_MULTIPLE_BLOCK");
    1104 
    1105                         /* Update moved bytes counter */
    1106                         rw->bytes_moved += (uint32_t) rv;
     836                for (i = 0; i < r->bufnum; ++i) {
     837#ifdef DEBUG
     838                        /* Check buffer */
     839                        if (r->bufs [i].length != e->block_size) {
     840                                RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_stop_cleanup, "Buffer and disk block size are not equal");
     841                        }
     842                        RTEMS_DEBUG_PRINT( "[%02u:%02u]: buffer = 0x%08x, size = %u\n", i + 1, r->bufnum, r->bufs [i].buffer, r->bufs [i].length);
     843#endif /* DEBUG */
     844
     845                        rv = sd_card_write( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
     846                        RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Write block");
    1107847                }
    1108848
    1109849                /* Stop multiple block write */
    1110850                rv = sd_card_stop_multiple_block_write( e);
    1111                 RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_write_cleanup, "Stop multiple block write");
     851                RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Stop multiple block write");
    1112852        }
    1113853
     
    1118858        /* Stop */
    1119859        sc = sd_card_stop( e);
    1120         RTEMS_CHECK_SC( sc, "Stop");
    1121 
    1122         return RTEMS_SUCCESSFUL;
    1123 
    1124 sd_card_driver_write_stop_cleanup:
     860        RTEMS_CHECK_SC_RV( sc, "Stop");
     861
     862        /* Done */
     863        r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
     864
     865        return 0;
     866
     867sd_card_disk_block_write_stop_cleanup:
    1125868
    1126869        /* Stop multiple block write */
    1127870        sd_card_stop_multiple_block_write( e);
    1128871
    1129 sd_card_driver_write_cleanup:
     872sd_card_disk_block_write_cleanup:
    1130873
    1131874        /* Get card status */
     
    1136879        sd_card_stop( e);
    1137880
    1138         return sc;
    1139 }
    1140 
    1141 /** @} */
    1142 
    1143 const rtems_driver_address_table sd_card_driver_ops = {
    1144         .initialization_entry = sd_card_driver_init,
    1145         .open_entry = NULL,
    1146         .close_entry = NULL,
    1147         .read_entry = sd_card_driver_read,
    1148         .write_entry = sd_card_driver_write,
    1149         .control_entry = NULL
     881        /* Done */
     882        r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
     883
     884        return rv;
     885}
     886
     887static int sd_card_disk_ioctl( dev_t dev, uint32_t req, void *arg)
     888{
     889        RTEMS_DEBUG_PRINT( "dev = %u, req = %u, arg = 0x08%x\n", dev, req, arg);
     890        if (req == RTEMS_BLKIO_REQUEST) {
     891                rtems_device_minor_number minor = rtems_filesystem_dev_minor_t( dev);
     892                sd_card_driver_entry *e = &sd_card_driver_table [minor];
     893                rtems_blkdev_request *r = (rtems_blkdev_request *) arg;
     894                switch (r->req) {
     895                        case RTEMS_BLKDEV_REQ_READ:
     896                                return sd_card_disk_block_read( e, r);
     897                        case RTEMS_BLKDEV_REQ_WRITE:
     898                                return sd_card_disk_block_write( e, r);
     899                        case RTEMS_BLKDEV_CAPABILITIES:
     900                                *((uint32_t*) arg)  = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
     901                                return 0;
     902                        default:
     903                                errno = EBADRQC;
     904                                return -1;
     905                }
     906        } else {
     907                errno = EBADRQC;
     908                return -1;
     909        }
     910}
     911
     912static rtems_status_code sd_card_disk_init( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
     913{
     914        rtems_status_code sc = RTEMS_SUCCESSFUL;
     915        sd_card_driver_entry *e = NULL;
     916        dev_t dev = 0;
     917
     918        /* Initialize disk IO */
     919        sc = rtems_disk_io_initialize();
     920        RTEMS_CHECK_SC( sc, "Initialize RTEMS disk IO");
     921
     922        for (minor = 0; minor < sd_card_driver_table_size; ++minor) {
     923                e = &sd_card_driver_table [minor];
     924
     925                /* Initialize SD Card */
     926                sc = sd_card_init( e);
     927                RTEMS_CHECK_SC( sc, "Initialize SD Card");
     928
     929                /* Create disk device */
     930                dev = rtems_filesystem_make_dev_t( major, minor);
     931                sc = rtems_disk_create_phys( dev, (int) e->block_size, (int) e->block_number, sd_card_disk_ioctl, e->device_name);
     932                RTEMS_CHECK_SC( sc, "Create disk device");
     933        }
     934
     935        return RTEMS_SUCCESSFUL;
     936}
     937
     938/** @} */
     939
     940static const rtems_driver_address_table sd_card_disk_ops = {
     941        .initialization_entry = sd_card_disk_init,
     942        .open_entry = rtems_blkdev_generic_open,
     943        .close_entry = rtems_blkdev_generic_close,
     944        .read_entry = rtems_blkdev_generic_read,
     945        .write_entry = rtems_blkdev_generic_write,
     946        .control_entry = rtems_blkdev_generic_ioctl
    1150947};
     948
     949rtems_status_code sd_card_register( void)
     950{
     951        rtems_status_code sc = RTEMS_SUCCESSFUL;
     952        rtems_device_major_number major = 0;
     953
     954        sc = rtems_io_register_driver( 0, &sd_card_disk_ops, &major);
     955        RTEMS_CHECK_SC( sc, "Register disk SD Card driver");
     956
     957        return RTEMS_SUCCESSFUL;
     958}
  • c/src/libchip/i2c/spi-sd-card.h

    rc51f900b r9814d2dd  
    5656
    5757typedef struct {
    58         rtems_libi2c_drv_t driver;
    59         int table_index;
    60         rtems_device_minor_number minor;
    6158        const char *device_name;
    62         const char *disk_device_name;
     59        int bus;
    6360        rtems_libi2c_tfr_mode_t transfer_mode;
    6461        uint8_t command [SD_CARD_COMMAND_SIZE];
     
    7471} sd_card_driver_entry;
    7572
    76 extern const rtems_driver_address_table sd_card_driver_ops;
     73extern sd_card_driver_entry sd_card_driver_table [];
    7774
    78 extern sd_card_driver_entry sd_card_driver_table [];
     75extern size_t sd_card_driver_table_size;
     76
     77rtems_status_code sd_card_register( void);
    7978
    8079#ifdef __cplusplus
Note: See TracChangeset for help on using the changeset viewer.