Ignore:
File:
1 edited

Legend:

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

    r4802dd7 r9d58539  
    4040#include "../../srv/vfs/vfs.h"
    4141#include <ipc/loc.h>
     42#include <ipc/bd.h>
    4243#include <ipc/services.h>
    4344#include <errno.h>
     
    4647#include <as.h>
    4748#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         bd_t *bd;
     82        fibril_mutex_t comm_area_lock;
     83        void *comm_area;
     84        size_t comm_size;
    8385        void *bb_buf;
    8486        aoff64_t bb_addr;
     
    8789} devcon_t;
    8890
    89 static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
    90 static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
     91static int read_blocks(devcon_t *, aoff64_t, size_t);
     92static int write_blocks(devcon_t *, aoff64_t, size_t);
     93static int get_block_size(async_sess_t *, size_t *);
     94static int get_num_blocks(async_sess_t *, aoff64_t *);
    9195static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9296
     
    108112
    109113static int devcon_add(service_id_t service_id, async_sess_t *sess,
    110     size_t bsize, bd_t *bd)
     114    size_t bsize, void *comm_area, size_t comm_size)
    111115{
    112116        devcon_t *devcon;
     117       
     118        if (comm_size < bsize)
     119                return EINVAL;
    113120       
    114121        devcon = malloc(sizeof(devcon_t));
     
    119126        devcon->service_id = service_id;
    120127        devcon->sess = sess;
    121         devcon->bd = bd;
     128        fibril_mutex_initialize(&devcon->comm_area_lock);
     129        devcon->comm_area = comm_area;
     130        devcon->comm_size = comm_size;
    122131        devcon->bb_buf = NULL;
    123132        devcon->bb_addr = 0;
     
    149158    size_t comm_size)
    150159{
    151         bd_t *bd;
    152 
     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       
    153165        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    154166            IPC_FLAG_BLOCKING);
    155167        if (!sess) {
     168                munmap(comm_area, comm_size);
    156169                return ENOENT;
    157170        }
    158171       
    159         int rc = bd_open(sess, &bd);
     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       
    160177        if (rc != EOK) {
     178                munmap(comm_area, comm_size);
    161179                async_hangup(sess);
    162180                return rc;
     
    164182       
    165183        size_t bsize;
    166         rc = bd_get_block_size(bd, &bsize);
     184        rc = get_block_size(sess, &bsize);
     185       
    167186        if (rc != EOK) {
    168                 bd_close(bd);
     187                munmap(comm_area, comm_size);
    169188                async_hangup(sess);
    170189                return rc;
    171190        }
    172191       
    173         rc = devcon_add(service_id, sess, bsize, bd);
     192        rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
    174193        if (rc != EOK) {
    175                 bd_close(bd);
     194                munmap(comm_area, comm_size);
    176195                async_hangup(sess);
    177196                return rc;
     
    194213                free(devcon->bb_buf);
    195214       
    196         bd_close(devcon->bd);
     215        munmap(devcon->comm_area, devcon->comm_size);
    197216        async_hangup(devcon->sess);
    198217       
     
    214233                return ENOMEM;
    215234
    216         rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size);
     235        fibril_mutex_lock(&devcon->comm_area_lock);
     236        rc = read_blocks(devcon, 0, 1);
    217237        if (rc != EOK) {
     238                fibril_mutex_unlock(&devcon->comm_area_lock);
    218239                free(bb_buf);
    219240                return rc;
    220241        }
     242        memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
     243        fibril_mutex_unlock(&devcon->comm_area_lock);
    221244
    222245        devcon->bb_buf = bb_buf;
     
    315338                list_remove(&b->free_link);
    316339                if (b->dirty) {
    317                         rc = write_blocks(devcon, b->pba, cache->blocks_cluster,
    318                             b->data, b->size);
     340                        memcpy(devcon->comm_area, b->data, b->size);
     341                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
    319342                        if (rc != EOK)
    320343                                return rc;
     
    458481                                list_append(&b->free_link, &cache->free_list);
    459482                                fibril_mutex_unlock(&cache->lock);
     483                                fibril_mutex_lock(&devcon->comm_area_lock);
     484                                memcpy(devcon->comm_area, b->data, b->size);
    460485                                rc = write_blocks(devcon, b->pba,
    461                                     cache->blocks_cluster, b->data, b->size);
     486                                    cache->blocks_cluster);
     487                                fibril_mutex_unlock(&devcon->comm_area_lock);
    462488                                if (rc != EOK) {
    463489                                        /*
     
    529555                         * the new contents from the device.
    530556                         */
    531                         rc = read_blocks(devcon, b->pba, cache->blocks_cluster,
    532                             b->data, cache->lblock_size);
     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);
    533561                        if (rc != EOK)
    534562                                b->toxic = true;
     
    588616        if (block->dirty && (block->refcnt == 1) &&
    589617            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    590                 rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
    591                     block->data, block->size);
     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);
    592622                block->dirty = false;
    593623        }
     
    658688 *
    659689 * @param service_id    Service ID of the block device.
    660  * @param buf           Buffer for holding one block
    661690 * @param bufpos        Pointer to the first unread valid offset within the
    662691 *                      communication buffer.
     
    670699 * @return              EOK on success or a negative return code on failure.
    671700 */
    672 int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,
    673     size_t *buflen, aoff64_t *pos, void *dst, size_t size)
     701int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
     702    aoff64_t *pos, void *dst, size_t size)
    674703{
    675704        size_t offset = 0;
     
    682711        block_size = devcon->pblock_size;
    683712       
     713        fibril_mutex_lock(&devcon->comm_area_lock);
    684714        while (left > 0) {
    685715                size_t rd;
     
    695725                         * destination buffer.
    696726                         */
    697                         memcpy(dst + offset, buf + *bufpos, rd);
     727                        memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
    698728                        offset += rd;
    699729                        *bufpos += rd;
     
    706736                        int rc;
    707737
    708                         rc = read_blocks(devcon, *pos / block_size, 1, buf,
    709                             devcon->pblock_size);
     738                        rc = read_blocks(devcon, *pos / block_size, 1);
    710739                        if (rc != EOK) {
     740                                fibril_mutex_unlock(&devcon->comm_area_lock);
    711741                                return rc;
    712742                        }
     
    716746                }
    717747        }
     748        fibril_mutex_unlock(&devcon->comm_area_lock);
    718749       
    719750        return EOK;
     
    732763{
    733764        devcon_t *devcon;
     765        int rc;
    734766
    735767        devcon = devcon_search(service_id);
    736768        assert(devcon);
    737 
    738         return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt);
     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;
    739779}
    740780
     
    752792{
    753793        devcon_t *devcon;
     794        int rc;
    754795
    755796        devcon = devcon_search(service_id);
    756797        assert(devcon);
    757 
    758         return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt);
     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;
    759807}
    760808
     
    772820        devcon = devcon_search(service_id);
    773821        assert(devcon);
    774 
    775         return bd_get_block_size(devcon->bd, bsize);
     822       
     823        return get_block_size(devcon->sess, bsize);
    776824}
    777825
     
    788836        assert(devcon);
    789837       
    790         return bd_get_num_blocks(devcon->bd, nblocks);
     838        return get_num_blocks(devcon->sess, nblocks);
    791839}
    792840
     
    839887        memcpy(data, buffer + offset, bytes);
    840888        free(buffer);
    841 
     889       
    842890        return EOK;
    843891}
     
    855903{
    856904        devcon_t *devcon = devcon_search(service_id);
     905        assert(devcon);
     906       
    857907        toc_block_t *toc = NULL;
    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         }
     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);
    871926       
    872927        return toc;
     
    882937 * @return              EOK on success or negative error code on failure.
    883938 */
    884 static 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);
     939static 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       
    890948        if (rc != EOK) {
    891949                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    909967 * @return              EOK on success or negative error code on failure.
    910968 */
    911 static 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);
     969static 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       
    917978        if (rc != EOK) {
    918979                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    926987}
    927988
     989/** Get block size used by the device. */
     990static 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. */
     1005static 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
    9281020/** Convert logical block address to physical block address. */
    9291021static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note: See TracChangeset for help on using the changeset viewer.