Ignore:
File:
1 edited

Legend:

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

    r9d58539 r4802dd7  
    4040#include "../../srv/vfs/vfs.h"
    4141#include <ipc/loc.h>
    42 #include <ipc/bd.h>
    4342#include <ipc/services.h>
    4443#include <errno.h>
     
    4746#include <as.h>
    4847#include <assert.h>
     48#include <bd.h>
    4949#include <fibril_synch.h>
    5050#include <adt/list.h>
     
    8080        service_id_t service_id;
    8181        async_sess_t *sess;
    82         fibril_mutex_t comm_area_lock;
    83         void *comm_area;
    84         size_t comm_size;
     82        bd_t *bd;
    8583        void *bb_buf;
    8684        aoff64_t bb_addr;
     
    8987} devcon_t;
    9088
    91 static int read_blocks(devcon_t *, aoff64_t, size_t);
    92 static int write_blocks(devcon_t *, aoff64_t, size_t);
    93 static int get_block_size(async_sess_t *, size_t *);
    94 static int get_num_blocks(async_sess_t *, aoff64_t *);
     89static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
     90static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
    9591static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9692
     
    112108
    113109static int devcon_add(service_id_t service_id, async_sess_t *sess,
    114     size_t bsize, void *comm_area, size_t comm_size)
     110    size_t bsize, bd_t *bd)
    115111{
    116112        devcon_t *devcon;
    117        
    118         if (comm_size < bsize)
    119                 return EINVAL;
    120113       
    121114        devcon = malloc(sizeof(devcon_t));
     
    126119        devcon->service_id = service_id;
    127120        devcon->sess = sess;
    128         fibril_mutex_initialize(&devcon->comm_area_lock);
    129         devcon->comm_area = comm_area;
    130         devcon->comm_size = comm_size;
     121        devcon->bd = bd;
    131122        devcon->bb_buf = NULL;
    132123        devcon->bb_addr = 0;
     
    158149    size_t comm_size)
    159150{
    160         void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    161             MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    162         if (!comm_area)
    163                 return ENOMEM;
    164        
     151        bd_t *bd;
     152
    165153        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    166154            IPC_FLAG_BLOCKING);
    167155        if (!sess) {
    168                 munmap(comm_area, comm_size);
    169156                return ENOENT;
    170157        }
    171158       
    172         async_exch_t *exch = async_exchange_begin(sess);
    173         int rc = async_share_out_start(exch, comm_area,
    174             AS_AREA_READ | AS_AREA_WRITE);
    175         async_exchange_end(exch);
    176        
     159        int rc = bd_open(sess, &bd);
    177160        if (rc != EOK) {
    178                 munmap(comm_area, comm_size);
    179161                async_hangup(sess);
    180162                return rc;
     
    182164       
    183165        size_t bsize;
    184         rc = get_block_size(sess, &bsize);
    185        
     166        rc = bd_get_block_size(bd, &bsize);
    186167        if (rc != EOK) {
    187                 munmap(comm_area, comm_size);
     168                bd_close(bd);
    188169                async_hangup(sess);
    189170                return rc;
    190171        }
    191172       
    192         rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
     173        rc = devcon_add(service_id, sess, bsize, bd);
    193174        if (rc != EOK) {
    194                 munmap(comm_area, comm_size);
     175                bd_close(bd);
    195176                async_hangup(sess);
    196177                return rc;
     
    213194                free(devcon->bb_buf);
    214195       
    215         munmap(devcon->comm_area, devcon->comm_size);
     196        bd_close(devcon->bd);
    216197        async_hangup(devcon->sess);
    217198       
     
    233214                return ENOMEM;
    234215
    235         fibril_mutex_lock(&devcon->comm_area_lock);
    236         rc = read_blocks(devcon, 0, 1);
     216        rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size);
    237217        if (rc != EOK) {
    238                 fibril_mutex_unlock(&devcon->comm_area_lock);
    239218                free(bb_buf);
    240219                return rc;
    241220        }
    242         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    243         fibril_mutex_unlock(&devcon->comm_area_lock);
    244221
    245222        devcon->bb_buf = bb_buf;
     
    338315                list_remove(&b->free_link);
    339316                if (b->dirty) {
    340                         memcpy(devcon->comm_area, b->data, b->size);
    341                         rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
     317                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster,
     318                            b->data, b->size);
    342319                        if (rc != EOK)
    343320                                return rc;
     
    481458                                list_append(&b->free_link, &cache->free_list);
    482459                                fibril_mutex_unlock(&cache->lock);
    483                                 fibril_mutex_lock(&devcon->comm_area_lock);
    484                                 memcpy(devcon->comm_area, b->data, b->size);
    485460                                rc = write_blocks(devcon, b->pba,
    486                                     cache->blocks_cluster);
    487                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     461                                    cache->blocks_cluster, b->data, b->size);
    488462                                if (rc != EOK) {
    489463                                        /*
     
    555529                         * the new contents from the device.
    556530                         */
    557                         fibril_mutex_lock(&devcon->comm_area_lock);
    558                         rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    559                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    560                         fibril_mutex_unlock(&devcon->comm_area_lock);
     531                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster,
     532                            b->data, cache->lblock_size);
    561533                        if (rc != EOK)
    562534                                b->toxic = true;
     
    616588        if (block->dirty && (block->refcnt == 1) &&
    617589            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    618                 fibril_mutex_lock(&devcon->comm_area_lock);
    619                 memcpy(devcon->comm_area, block->data, block->size);
    620                 rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    621                 fibril_mutex_unlock(&devcon->comm_area_lock);
     590                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
     591                    block->data, block->size);
    622592                block->dirty = false;
    623593        }
     
    688658 *
    689659 * @param service_id    Service ID of the block device.
     660 * @param buf           Buffer for holding one block
    690661 * @param bufpos        Pointer to the first unread valid offset within the
    691662 *                      communication buffer.
     
    699670 * @return              EOK on success or a negative return code on failure.
    700671 */
    701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
    702     aoff64_t *pos, void *dst, size_t size)
     672int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,
     673    size_t *buflen, aoff64_t *pos, void *dst, size_t size)
    703674{
    704675        size_t offset = 0;
     
    711682        block_size = devcon->pblock_size;
    712683       
    713         fibril_mutex_lock(&devcon->comm_area_lock);
    714684        while (left > 0) {
    715685                size_t rd;
     
    725695                         * destination buffer.
    726696                         */
    727                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     697                        memcpy(dst + offset, buf + *bufpos, rd);
    728698                        offset += rd;
    729699                        *bufpos += rd;
     
    736706                        int rc;
    737707
    738                         rc = read_blocks(devcon, *pos / block_size, 1);
     708                        rc = read_blocks(devcon, *pos / block_size, 1, buf,
     709                            devcon->pblock_size);
    739710                        if (rc != EOK) {
    740                                 fibril_mutex_unlock(&devcon->comm_area_lock);
    741711                                return rc;
    742712                        }
     
    746716                }
    747717        }
    748         fibril_mutex_unlock(&devcon->comm_area_lock);
    749718       
    750719        return EOK;
     
    763732{
    764733        devcon_t *devcon;
    765         int rc;
    766734
    767735        devcon = devcon_search(service_id);
    768736        assert(devcon);
    769        
    770         fibril_mutex_lock(&devcon->comm_area_lock);
    771 
    772         rc = read_blocks(devcon, ba, cnt);
    773         if (rc == EOK)
    774                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    775 
    776         fibril_mutex_unlock(&devcon->comm_area_lock);
    777 
    778         return rc;
     737
     738        return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt);
    779739}
    780740
     
    792752{
    793753        devcon_t *devcon;
    794         int rc;
    795754
    796755        devcon = devcon_search(service_id);
    797756        assert(devcon);
    798        
    799         fibril_mutex_lock(&devcon->comm_area_lock);
    800 
    801         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    802         rc = write_blocks(devcon, ba, cnt);
    803 
    804         fibril_mutex_unlock(&devcon->comm_area_lock);
    805 
    806         return rc;
     757
     758        return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt);
    807759}
    808760
     
    820772        devcon = devcon_search(service_id);
    821773        assert(devcon);
    822        
    823         return get_block_size(devcon->sess, bsize);
     774
     775        return bd_get_block_size(devcon->bd, bsize);
    824776}
    825777
     
    836788        assert(devcon);
    837789       
    838         return get_num_blocks(devcon->sess, nblocks);
     790        return bd_get_num_blocks(devcon->bd, nblocks);
    839791}
    840792
     
    887839        memcpy(data, buffer + offset, bytes);
    888840        free(buffer);
    889        
     841
    890842        return EOK;
    891843}
     
    903855{
    904856        devcon_t *devcon = devcon_search(service_id);
    905         assert(devcon);
    906        
    907857        toc_block_t *toc = NULL;
    908        
    909         fibril_mutex_lock(&devcon->comm_area_lock);
    910        
    911         async_exch_t *exch = async_exchange_begin(devcon->sess);
    912         int rc = async_req_1_0(exch, BD_READ_TOC, session);
    913         async_exchange_end(exch);
    914        
    915         if (rc == EOK) {
    916                 toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    917                 if (toc != NULL) {
    918                         memset(toc, 0, sizeof(toc_block_t));
    919                         memcpy(toc, devcon->comm_area,
    920                             min(devcon->pblock_size, sizeof(toc_block_t)));
    921                 }
    922         }
    923        
    924        
    925         fibril_mutex_unlock(&devcon->comm_area_lock);
     858        int rc;
     859       
     860        assert(devcon);
     861       
     862        toc = (toc_block_t *) malloc(sizeof(toc_block_t));
     863        if (toc == NULL)
     864                return NULL;
     865       
     866        rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
     867        if (rc != EOK) {
     868                free(toc);
     869                return NULL;
     870        }
    926871       
    927872        return toc;
     
    937882 * @return              EOK on success or negative error code on failure.
    938883 */
    939 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    940 {
    941         assert(devcon);
    942        
    943         async_exch_t *exch = async_exchange_begin(devcon->sess);
    944         int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
    945             UPPER32(ba), cnt);
    946         async_exchange_end(exch);
    947        
     884static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf,
     885    size_t size)
     886{
     887        assert(devcon);
     888       
     889        int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size);
    948890        if (rc != EOK) {
    949891                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    967909 * @return              EOK on success or negative error code on failure.
    968910 */
    969 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    970 {
    971         assert(devcon);
    972        
    973         async_exch_t *exch = async_exchange_begin(devcon->sess);
    974         int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
    975             UPPER32(ba), cnt);
    976         async_exchange_end(exch);
    977        
     911static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data,
     912    size_t size)
     913{
     914        assert(devcon);
     915       
     916        int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size);
    978917        if (rc != EOK) {
    979918                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    987926}
    988927
    989 /** Get block size used by the device. */
    990 static int get_block_size(async_sess_t *sess, size_t *bsize)
    991 {
    992         sysarg_t bs;
    993        
    994         async_exch_t *exch = async_exchange_begin(sess);
    995         int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
    996         async_exchange_end(exch);
    997        
    998         if (rc == EOK)
    999                 *bsize = (size_t) bs;
    1000        
    1001         return rc;
    1002 }
    1003 
    1004 /** Get total number of blocks on block device. */
    1005 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
    1006 {
    1007         sysarg_t nb_l;
    1008         sysarg_t nb_h;
    1009        
    1010         async_exch_t *exch = async_exchange_begin(sess);
    1011         int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    1012         async_exchange_end(exch);
    1013        
    1014         if (rc == EOK)
    1015                 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    1016        
    1017         return rc;
    1018 }
    1019 
    1020928/** Convert logical block address to physical block address. */
    1021929static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note: See TracChangeset for help on using the changeset viewer.