Ignore:
File:
1 edited

Legend:

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

    r5716e9a r79ae36dd  
    22 * Copyright (c) 2008 Jakub Jermar
    33 * Copyright (c) 2008 Martin Decky
     4 * Copyright (c) 2011 Martin Sucha
    45 * All rights reserved.
    56 *
     
    5152#include <macros.h>
    5253#include <mem.h>
     54#include <malloc.h>
     55#include <stdio.h>
    5356#include <sys/typefmt.h>
    5457#include <stacktrace.h>
     
    5962static LIST_INITIALIZE(dcl_head);
    6063
    61 #define CACHE_BUCKETS_LOG2              10
    62 #define CACHE_BUCKETS                   (1 << CACHE_BUCKETS_LOG2)
     64#define CACHE_BUCKETS_LOG2  10
     65#define CACHE_BUCKETS       (1 << CACHE_BUCKETS_LOG2)
    6366
    6467typedef struct {
    6568        fibril_mutex_t lock;
    66         size_t lblock_size;             /**< Logical block size. */
    67         unsigned blocks_cluster;        /**< Physical blocks per block_t */
    68         unsigned block_count;           /**< Total number of blocks. */
    69         unsigned blocks_cached;         /**< Number of cached blocks. */
     69        size_t lblock_size;       /**< Logical block size. */
     70        unsigned blocks_cluster;  /**< Physical blocks per block_t */
     71        unsigned block_count;     /**< Total number of blocks. */
     72        unsigned blocks_cached;   /**< Number of cached blocks. */
    7073        hash_table_t block_hash;
    7174        link_t free_head;
     
    7679        link_t link;
    7780        devmap_handle_t devmap_handle;
    78         int dev_phone;
     81        async_sess_t *sess;
    7982        fibril_mutex_t comm_area_lock;
    8083        void *comm_area;
     
    8285        void *bb_buf;
    8386        aoff64_t bb_addr;
    84         size_t pblock_size;             /**< Physical block size. */
     87        size_t pblock_size;  /**< Physical block size. */
    8588        cache_t *cache;
    8689} devcon_t;
    8790
    88 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
    89 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
    90 static int get_block_size(int dev_phone, size_t *bsize);
    91 static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
    92 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
     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 *);
     95static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9396
    9497static devcon_t *devcon_search(devmap_handle_t devmap_handle)
    9598{
    9699        link_t *cur;
    97 
     100       
    98101        fibril_mutex_lock(&dcl_lock);
     102       
    99103        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    100104                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
     
    104108                }
    105109        }
     110       
    106111        fibril_mutex_unlock(&dcl_lock);
    107112        return NULL;
    108113}
    109114
    110 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
    111     void *comm_area, size_t comm_size)
     115static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess,
     116    size_t bsize, void *comm_area, size_t comm_size)
    112117{
    113118        link_t *cur;
    114119        devcon_t *devcon;
    115 
     120       
    116121        if (comm_size < bsize)
    117122                return EINVAL;
    118 
     123       
    119124        devcon = malloc(sizeof(devcon_t));
    120125        if (!devcon)
     
    123128        link_initialize(&devcon->link);
    124129        devcon->devmap_handle = devmap_handle;
    125         devcon->dev_phone = dev_phone;
     130        devcon->sess = sess;
    126131        fibril_mutex_initialize(&devcon->comm_area_lock);
    127132        devcon->comm_area = comm_area;
     
    131136        devcon->pblock_size = bsize;
    132137        devcon->cache = NULL;
    133 
     138       
    134139        fibril_mutex_lock(&dcl_lock);
    135140        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
     
    153158}
    154159
    155 int block_init(devmap_handle_t devmap_handle, size_t comm_size)
    156 {
    157         int rc;
    158         int dev_phone;
    159         void *comm_area;
    160         size_t bsize;
    161 
    162         comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
     160int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle,
     161    size_t comm_size)
     162{
     163        void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    163164            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    164         if (!comm_area) {
     165        if (!comm_area)
    165166                return ENOMEM;
    166         }
    167 
    168         dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
    169         if (dev_phone < 0) {
     167       
     168        async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
     169            IPC_FLAG_BLOCKING);
     170        if (!sess) {
    170171                munmap(comm_area, comm_size);
    171                 return dev_phone;
    172         }
    173 
    174         rc = async_share_out_start(dev_phone, comm_area,
     172                return ENOENT;
     173        }
     174       
     175        async_exch_t *exch = async_exchange_begin(sess);
     176        int rc = async_share_out_start(exch, comm_area,
    175177            AS_AREA_READ | AS_AREA_WRITE);
    176         if (rc != EOK) {
    177                 munmap(comm_area, comm_size);
    178                 async_hangup(dev_phone);
    179                 return rc;
    180         }
    181 
    182         if (get_block_size(dev_phone, &bsize) != EOK) {
    183                 munmap(comm_area, comm_size);
    184                 async_hangup(dev_phone);
    185                 return rc;
    186         }
    187        
    188         rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size);
     178        async_exchange_end(exch);
     179       
    189180        if (rc != EOK) {
    190181                munmap(comm_area, comm_size);
    191                 async_hangup(dev_phone);
     182                async_hangup(sess);
    192183                return rc;
    193184        }
    194 
     185       
     186        size_t bsize;
     187        rc = get_block_size(sess, &bsize);
     188       
     189        if (rc != EOK) {
     190                munmap(comm_area, comm_size);
     191                async_hangup(sess);
     192                return rc;
     193        }
     194       
     195        rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size);
     196        if (rc != EOK) {
     197                munmap(comm_area, comm_size);
     198                async_hangup(sess);
     199                return rc;
     200        }
     201       
    195202        return EOK;
    196203}
     
    203210        if (devcon->cache)
    204211                (void) block_cache_fini(devmap_handle);
    205 
     212       
    206213        devcon_remove(devcon);
    207 
     214       
    208215        if (devcon->bb_buf)
    209216                free(devcon->bb_buf);
    210 
     217       
    211218        munmap(devcon->comm_area, devcon->comm_size);
    212         async_hangup(devcon->dev_phone);
    213 
    214         free(devcon);   
     219        async_hangup(devcon->sess);
     220       
     221        free(devcon);
    215222}
    216223
     
    805812        assert(devcon);
    806813       
    807         return get_block_size(devcon->dev_phone, bsize);
     814        return get_block_size(devcon->sess, bsize);
    808815}
    809816
     
    817824int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
    818825{
    819         devcon_t *devcon;
    820 
    821         devcon = devcon_search(devmap_handle);
    822         assert(devcon);
    823        
    824         return get_num_blocks(devcon->dev_phone, nblocks);
     826        devcon_t *devcon = devcon_search(devmap_handle);
     827        assert(devcon);
     828       
     829        return get_num_blocks(devcon->sess, nblocks);
     830}
     831
     832/** Read bytes directly from the device (bypass cache)
     833 *
     834 * @param devmap_handle Device handle of the block device.
     835 * @param abs_offset    Absolute offset in bytes where to start reading
     836 * @param bytes                 Number of bytes to read
     837 * @param data                  Buffer that receives the data
     838 *
     839 * @return              EOK on success or negative error code on failure.
     840 */
     841int block_read_bytes_direct(devmap_handle_t devmap_handle, aoff64_t abs_offset,
     842    size_t bytes, void *data)
     843{
     844        int rc;
     845        size_t phys_block_size;
     846        size_t buf_size;
     847        void *buffer;
     848        aoff64_t first_block;
     849        aoff64_t last_block;
     850        size_t blocks;
     851        size_t offset;
     852       
     853        rc = block_get_bsize(devmap_handle, &phys_block_size);
     854        if (rc != EOK) {
     855                return rc;
     856        }
     857       
     858        /* calculate data position and required space */
     859        first_block = abs_offset / phys_block_size;
     860        offset = abs_offset % phys_block_size;
     861        last_block = (abs_offset + bytes - 1) / phys_block_size;
     862        blocks = last_block - first_block + 1;
     863        buf_size = blocks * phys_block_size;
     864       
     865        /* read the data into memory */
     866        buffer = malloc(buf_size);
     867        if (buffer == NULL) {
     868                return ENOMEM;
     869        }
     870       
     871        rc = block_read_direct(devmap_handle, first_block, blocks, buffer);
     872        if (rc != EOK) {
     873                free(buffer);
     874                return rc;
     875        }
     876       
     877        /* copy the data from the buffer */
     878        memcpy(data, buffer + offset, bytes);
     879        free(buffer);
     880       
     881        return EOK;
    825882}
    826883
     
    836893static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    837894{
    838         int rc;
    839 
    840         assert(devcon);
    841         rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
     895        assert(devcon);
     896       
     897        async_exch_t *exch = async_exchange_begin(devcon->sess);
     898        int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
    842899            UPPER32(ba), cnt);
     900        async_exchange_end(exch);
     901       
    843902        if (rc != EOK) {
    844903                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    849908#endif
    850909        }
     910       
    851911        return rc;
    852912}
     
    863923static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    864924{
    865         int rc;
    866 
    867         assert(devcon);
    868         rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
     925        assert(devcon);
     926       
     927        async_exch_t *exch = async_exchange_begin(devcon->sess);
     928        int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
    869929            UPPER32(ba), cnt);
     930        async_exchange_end(exch);
     931       
    870932        if (rc != EOK) {
    871933                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    875937#endif
    876938        }
     939       
    877940        return rc;
    878941}
    879942
    880943/** Get block size used by the device. */
    881 static int get_block_size(int dev_phone, size_t *bsize)
     944static int get_block_size(async_sess_t *sess, size_t *bsize)
    882945{
    883946        sysarg_t bs;
    884         int rc;
    885 
    886         rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
     947       
     948        async_exch_t *exch = async_exchange_begin(sess);
     949        int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
     950        async_exchange_end(exch);
     951       
    887952        if (rc == EOK)
    888953                *bsize = (size_t) bs;
    889 
     954       
    890955        return rc;
    891956}
    892957
    893958/** Get total number of blocks on block device. */
    894 static int get_num_blocks(int dev_phone, aoff64_t *nblocks)
    895 {
    896         sysarg_t nb_l, nb_h;
    897         int rc;
    898 
    899         rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    900         if (rc == EOK) {
     959static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
     960{
     961        sysarg_t nb_l;
     962        sysarg_t nb_h;
     963       
     964        async_exch_t *exch = async_exchange_begin(sess);
     965        int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
     966        async_exchange_end(exch);
     967       
     968        if (rc == EOK)
    901969                *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    902         }
    903 
     970       
    904971        return rc;
    905972}
Note: See TracChangeset for help on using the changeset viewer.