Changeset 7cfe5c0 in mainline for uspace/lib/block/block.c


Ignore:
Timestamp:
2012-08-20T19:16:24Z (12 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6b99156
Parents:
b9cb911 (diff), 01e397ac (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged with mainline 0.5.0 changes.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/block/block.c

    rb9cb911 r7cfe5c0  
    3737 */
    3838
    39 #include "libblock.h"
    4039#include "../../srv/vfs/vfs.h"
    4140#include <ipc/loc.h>
    42 #include <ipc/bd.h>
    4341#include <ipc/services.h>
    4442#include <errno.h>
     
    4745#include <as.h>
    4846#include <assert.h>
     47#include <bd.h>
    4948#include <fibril_synch.h>
    5049#include <adt/list.h>
     
    5655#include <sys/typefmt.h>
    5756#include <stacktrace.h>
     57#include "block.h"
    5858
    5959/** Lock protecting the device connection list */
     
    7878        service_id_t service_id;
    7979        async_sess_t *sess;
    80         fibril_mutex_t comm_area_lock;
    81         void *comm_area;
    82         size_t comm_size;
     80        bd_t *bd;
    8381        void *bb_buf;
    8482        aoff64_t bb_addr;
     
    8785} devcon_t;
    8886
    89 static int read_blocks(devcon_t *, aoff64_t, size_t);
    90 static int write_blocks(devcon_t *, aoff64_t, size_t);
    91 static int get_block_size(async_sess_t *, size_t *);
    92 static int get_num_blocks(async_sess_t *, aoff64_t *);
     87static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
     88static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
    9389static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9490
     
    110106
    111107static int devcon_add(service_id_t service_id, async_sess_t *sess,
    112     size_t bsize, void *comm_area, size_t comm_size)
     108    size_t bsize, bd_t *bd)
    113109{
    114110        devcon_t *devcon;
    115        
    116         if (comm_size < bsize)
    117                 return EINVAL;
    118111       
    119112        devcon = malloc(sizeof(devcon_t));
     
    124117        devcon->service_id = service_id;
    125118        devcon->sess = sess;
    126         fibril_mutex_initialize(&devcon->comm_area_lock);
    127         devcon->comm_area = comm_area;
    128         devcon->comm_size = comm_size;
     119        devcon->bd = bd;
    129120        devcon->bb_buf = NULL;
    130121        devcon->bb_addr = 0;
     
    156147    size_t comm_size)
    157148{
    158         void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    159             MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    160         if (!comm_area)
    161                 return ENOMEM;
    162        
     149        bd_t *bd;
     150
    163151        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    164152            IPC_FLAG_BLOCKING);
    165153        if (!sess) {
    166                 munmap(comm_area, comm_size);
    167154                return ENOENT;
    168155        }
    169156       
    170         async_exch_t *exch = async_exchange_begin(sess);
    171         int rc = async_share_out_start(exch, comm_area,
    172             AS_AREA_READ | AS_AREA_WRITE);
    173         async_exchange_end(exch);
    174        
     157        int rc = bd_open(sess, &bd);
    175158        if (rc != EOK) {
    176                 munmap(comm_area, comm_size);
    177159                async_hangup(sess);
    178160                return rc;
     
    180162       
    181163        size_t bsize;
    182         rc = get_block_size(sess, &bsize);
    183        
     164        rc = bd_get_block_size(bd, &bsize);
    184165        if (rc != EOK) {
    185                 munmap(comm_area, comm_size);
     166                bd_close(bd);
    186167                async_hangup(sess);
    187168                return rc;
    188169        }
    189170       
    190         rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
     171        rc = devcon_add(service_id, sess, bsize, bd);
    191172        if (rc != EOK) {
    192                 munmap(comm_area, comm_size);
     173                bd_close(bd);
    193174                async_hangup(sess);
    194175                return rc;
     
    211192                free(devcon->bb_buf);
    212193       
    213         munmap(devcon->comm_area, devcon->comm_size);
     194        bd_close(devcon->bd);
    214195        async_hangup(devcon->sess);
    215196       
     
    231212                return ENOMEM;
    232213
    233         fibril_mutex_lock(&devcon->comm_area_lock);
    234         rc = read_blocks(devcon, 0, 1);
     214        rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size);
    235215        if (rc != EOK) {
    236                 fibril_mutex_unlock(&devcon->comm_area_lock);
    237216                free(bb_buf);
    238217                return rc;
    239218        }
    240         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    241         fibril_mutex_unlock(&devcon->comm_area_lock);
    242219
    243220        devcon->bb_buf = bb_buf;
     
    342319                list_remove(&b->free_link);
    343320                if (b->dirty) {
    344                         memcpy(devcon->comm_area, b->data, b->size);
    345                         rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
     321                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster,
     322                            b->data, b->size);
    346323                        if (rc != EOK)
    347324                                return rc;
     
    476453                                list_append(&b->free_link, &cache->free_list);
    477454                                fibril_mutex_unlock(&cache->lock);
    478                                 fibril_mutex_lock(&devcon->comm_area_lock);
    479                                 memcpy(devcon->comm_area, b->data, b->size);
    480455                                rc = write_blocks(devcon, b->pba,
    481                                     cache->blocks_cluster);
    482                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     456                                    cache->blocks_cluster, b->data, b->size);
    483457                                if (rc != EOK) {
    484458                                        /*
     
    546520                         * the new contents from the device.
    547521                         */
    548                         fibril_mutex_lock(&devcon->comm_area_lock);
    549                         rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    550                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    551                         fibril_mutex_unlock(&devcon->comm_area_lock);
     522                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster,
     523                            b->data, cache->lblock_size);
    552524                        if (rc != EOK)
    553525                                b->toxic = true;
     
    607579        if (block->dirty && (block->refcnt == 1) &&
    608580            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    609                 fibril_mutex_lock(&devcon->comm_area_lock);
    610                 memcpy(devcon->comm_area, block->data, block->size);
    611                 rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    612                 fibril_mutex_unlock(&devcon->comm_area_lock);
     581                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
     582                    block->data, block->size);
    613583                block->dirty = false;
    614584        }
     
    675645 *
    676646 * @param service_id    Service ID of the block device.
     647 * @param buf           Buffer for holding one block
    677648 * @param bufpos        Pointer to the first unread valid offset within the
    678649 *                      communication buffer.
     
    686657 * @return              EOK on success or a negative return code on failure.
    687658 */
    688 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
    689     aoff64_t *pos, void *dst, size_t size)
     659int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,
     660    size_t *buflen, aoff64_t *pos, void *dst, size_t size)
    690661{
    691662        size_t offset = 0;
     
    698669        block_size = devcon->pblock_size;
    699670       
    700         fibril_mutex_lock(&devcon->comm_area_lock);
    701671        while (left > 0) {
    702672                size_t rd;
     
    712682                         * destination buffer.
    713683                         */
    714                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     684                        memcpy(dst + offset, buf + *bufpos, rd);
    715685                        offset += rd;
    716686                        *bufpos += rd;
     
    723693                        int rc;
    724694
    725                         rc = read_blocks(devcon, *pos / block_size, 1);
     695                        rc = read_blocks(devcon, *pos / block_size, 1, buf,
     696                            devcon->pblock_size);
    726697                        if (rc != EOK) {
    727                                 fibril_mutex_unlock(&devcon->comm_area_lock);
    728698                                return rc;
    729699                        }
     
    733703                }
    734704        }
    735         fibril_mutex_unlock(&devcon->comm_area_lock);
    736705       
    737706        return EOK;
     
    750719{
    751720        devcon_t *devcon;
    752         int rc;
    753721
    754722        devcon = devcon_search(service_id);
    755723        assert(devcon);
    756        
    757         fibril_mutex_lock(&devcon->comm_area_lock);
    758 
    759         rc = read_blocks(devcon, ba, cnt);
    760         if (rc == EOK)
    761                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    762 
    763         fibril_mutex_unlock(&devcon->comm_area_lock);
    764 
    765         return rc;
     724
     725        return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt);
    766726}
    767727
     
    779739{
    780740        devcon_t *devcon;
    781         int rc;
    782741
    783742        devcon = devcon_search(service_id);
    784743        assert(devcon);
    785        
    786         fibril_mutex_lock(&devcon->comm_area_lock);
    787 
    788         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    789         rc = write_blocks(devcon, ba, cnt);
    790 
    791         fibril_mutex_unlock(&devcon->comm_area_lock);
    792 
    793         return rc;
     744
     745        return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt);
    794746}
    795747
     
    807759        devcon = devcon_search(service_id);
    808760        assert(devcon);
    809        
    810         return get_block_size(devcon->sess, bsize);
     761
     762        return bd_get_block_size(devcon->bd, bsize);
    811763}
    812764
     
    823775        assert(devcon);
    824776       
    825         return get_num_blocks(devcon->sess, nblocks);
     777        return bd_get_num_blocks(devcon->bd, nblocks);
    826778}
    827779
     
    890842{
    891843        devcon_t *devcon = devcon_search(service_id);
    892         assert(devcon);
    893        
    894844        toc_block_t *toc = NULL;
    895        
    896         fibril_mutex_lock(&devcon->comm_area_lock);
    897        
    898         async_exch_t *exch = async_exchange_begin(devcon->sess);
    899         int rc = async_req_1_0(exch, BD_READ_TOC, session);
    900         async_exchange_end(exch);
    901        
    902         if (rc == EOK) {
    903                 toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    904                 if (toc != NULL) {
    905                         memset(toc, 0, sizeof(toc_block_t));
    906                         memcpy(toc, devcon->comm_area,
    907                             min(devcon->pblock_size, sizeof(toc_block_t)));
    908                 }
    909         }
    910        
    911        
    912         fibril_mutex_unlock(&devcon->comm_area_lock);
     845        int rc;
     846       
     847        assert(devcon);
     848       
     849        toc = (toc_block_t *) malloc(sizeof(toc_block_t));
     850        if (toc == NULL)
     851                return NULL;
     852       
     853        rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
     854        if (rc != EOK) {
     855                free(toc);
     856                return NULL;
     857        }
    913858       
    914859        return toc;
     
    924869 * @return              EOK on success or negative error code on failure.
    925870 */
    926 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    927 {
    928         assert(devcon);
    929        
    930         async_exch_t *exch = async_exchange_begin(devcon->sess);
    931         int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
    932             UPPER32(ba), cnt);
    933         async_exchange_end(exch);
    934        
     871static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf,
     872    size_t size)
     873{
     874        assert(devcon);
     875       
     876        int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size);
    935877        if (rc != EOK) {
    936878                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    954896 * @return              EOK on success or negative error code on failure.
    955897 */
    956 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    957 {
    958         assert(devcon);
    959        
    960         async_exch_t *exch = async_exchange_begin(devcon->sess);
    961         int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
    962             UPPER32(ba), cnt);
    963         async_exchange_end(exch);
    964        
     898static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data,
     899    size_t size)
     900{
     901        assert(devcon);
     902       
     903        int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size);
    965904        if (rc != EOK) {
    966905                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    974913}
    975914
    976 /** Get block size used by the device. */
    977 static int get_block_size(async_sess_t *sess, size_t *bsize)
    978 {
    979         sysarg_t bs;
    980        
    981         async_exch_t *exch = async_exchange_begin(sess);
    982         int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
    983         async_exchange_end(exch);
    984        
    985         if (rc == EOK)
    986                 *bsize = (size_t) bs;
    987        
    988         return rc;
    989 }
    990 
    991 /** Get total number of blocks on block device. */
    992 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
    993 {
    994         sysarg_t nb_l;
    995         sysarg_t nb_h;
    996        
    997         async_exch_t *exch = async_exchange_begin(sess);
    998         int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    999         async_exchange_end(exch);
    1000        
    1001         if (rc == EOK)
    1002                 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    1003        
    1004         return rc;
    1005 }
    1006 
    1007915/** Convert logical block address to physical block address. */
    1008916static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note: See TracChangeset for help on using the changeset viewer.