Ignore:
File:
1 edited

Legend:

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

    rc7bbf029 r79ae36dd  
    22 * Copyright (c) 2008 Jakub Jermar
    33 * Copyright (c) 2008 Martin Decky
     4 * Copyright (c) 2011 Martin Sucha
    45 * All rights reserved.
    56 *
     
    6162static LIST_INITIALIZE(dcl_head);
    6263
    63 #define CACHE_BUCKETS_LOG2              10
    64 #define CACHE_BUCKETS                   (1 << CACHE_BUCKETS_LOG2)
     64#define CACHE_BUCKETS_LOG2  10
     65#define CACHE_BUCKETS       (1 << CACHE_BUCKETS_LOG2)
    6566
    6667typedef struct {
    6768        fibril_mutex_t lock;
    68         size_t lblock_size;             /**< Logical block size. */
    69         unsigned blocks_cluster;        /**< Physical blocks per block_t */
    70         unsigned block_count;           /**< Total number of blocks. */
    71         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. */
    7273        hash_table_t block_hash;
    7374        link_t free_head;
     
    7879        link_t link;
    7980        devmap_handle_t devmap_handle;
    80         int dev_phone;
     81        async_sess_t *sess;
    8182        fibril_mutex_t comm_area_lock;
    8283        void *comm_area;
     
    8485        void *bb_buf;
    8586        aoff64_t bb_addr;
    86         size_t pblock_size;             /**< Physical block size. */
     87        size_t pblock_size;  /**< Physical block size. */
    8788        cache_t *cache;
    8889} devcon_t;
    8990
    90 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
    91 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
    92 static int get_block_size(int dev_phone, size_t *bsize);
    93 static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
    94 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);
    9596
    9697static devcon_t *devcon_search(devmap_handle_t devmap_handle)
    9798{
    9899        link_t *cur;
    99 
     100       
    100101        fibril_mutex_lock(&dcl_lock);
     102       
    101103        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    102104                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
     
    106108                }
    107109        }
     110       
    108111        fibril_mutex_unlock(&dcl_lock);
    109112        return NULL;
    110113}
    111114
    112 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
    113     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)
    114117{
    115118        link_t *cur;
    116119        devcon_t *devcon;
    117 
     120       
    118121        if (comm_size < bsize)
    119122                return EINVAL;
    120 
     123       
    121124        devcon = malloc(sizeof(devcon_t));
    122125        if (!devcon)
     
    125128        link_initialize(&devcon->link);
    126129        devcon->devmap_handle = devmap_handle;
    127         devcon->dev_phone = dev_phone;
     130        devcon->sess = sess;
    128131        fibril_mutex_initialize(&devcon->comm_area_lock);
    129132        devcon->comm_area = comm_area;
     
    133136        devcon->pblock_size = bsize;
    134137        devcon->cache = NULL;
    135 
     138       
    136139        fibril_mutex_lock(&dcl_lock);
    137140        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
     
    155158}
    156159
    157 int block_init(devmap_handle_t devmap_handle, size_t comm_size)
    158 {
    159         int rc;
    160         int dev_phone;
    161         void *comm_area;
    162         size_t bsize;
    163 
    164         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,
    165164            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    166         if (!comm_area) {
     165        if (!comm_area)
    167166                return ENOMEM;
    168         }
    169 
    170         dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
    171         if (dev_phone < 0) {
     167       
     168        async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
     169            IPC_FLAG_BLOCKING);
     170        if (!sess) {
    172171                munmap(comm_area, comm_size);
    173                 return dev_phone;
    174         }
    175 
    176         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,
    177177            AS_AREA_READ | AS_AREA_WRITE);
    178         if (rc != EOK) {
    179                 munmap(comm_area, comm_size);
    180                 async_hangup(dev_phone);
    181                 return rc;
    182         }
    183 
    184         if (get_block_size(dev_phone, &bsize) != EOK) {
    185                 munmap(comm_area, comm_size);
    186                 async_hangup(dev_phone);
    187                 return rc;
    188         }
    189        
    190         rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size);
     178        async_exchange_end(exch);
     179       
    191180        if (rc != EOK) {
    192181                munmap(comm_area, comm_size);
    193                 async_hangup(dev_phone);
     182                async_hangup(sess);
    194183                return rc;
    195184        }
    196 
     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       
    197202        return EOK;
    198203}
     
    205210        if (devcon->cache)
    206211                (void) block_cache_fini(devmap_handle);
    207 
     212       
    208213        devcon_remove(devcon);
    209 
     214       
    210215        if (devcon->bb_buf)
    211216                free(devcon->bb_buf);
    212 
     217       
    213218        munmap(devcon->comm_area, devcon->comm_size);
    214         async_hangup(devcon->dev_phone);
    215 
    216         free(devcon);   
     219        async_hangup(devcon->sess);
     220       
     221        free(devcon);
    217222}
    218223
     
    807812        assert(devcon);
    808813       
    809         return get_block_size(devcon->dev_phone, bsize);
     814        return get_block_size(devcon->sess, bsize);
    810815}
    811816
     
    819824int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
    820825{
    821         devcon_t *devcon;
    822 
    823         devcon = devcon_search(devmap_handle);
    824         assert(devcon);
    825        
    826         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;
    827882}
    828883
     
    838893static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    839894{
    840         int rc;
    841 
    842         assert(devcon);
    843         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),
    844899            UPPER32(ba), cnt);
     900        async_exchange_end(exch);
     901       
    845902        if (rc != EOK) {
    846903                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    851908#endif
    852909        }
     910       
    853911        return rc;
    854912}
     
    865923static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    866924{
    867         int rc;
    868 
    869         assert(devcon);
    870         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),
    871929            UPPER32(ba), cnt);
     930        async_exchange_end(exch);
     931       
    872932        if (rc != EOK) {
    873933                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    877937#endif
    878938        }
     939       
    879940        return rc;
    880941}
    881942
    882943/** Get block size used by the device. */
    883 static int get_block_size(int dev_phone, size_t *bsize)
     944static int get_block_size(async_sess_t *sess, size_t *bsize)
    884945{
    885946        sysarg_t bs;
    886         int rc;
    887 
    888         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       
    889952        if (rc == EOK)
    890953                *bsize = (size_t) bs;
    891 
     954       
    892955        return rc;
    893956}
    894957
    895958/** Get total number of blocks on block device. */
    896 static int get_num_blocks(int dev_phone, aoff64_t *nblocks)
    897 {
    898         sysarg_t nb_l, nb_h;
    899         int rc;
    900 
    901         rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    902         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)
    903969                *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    904         }
    905 
     970       
    906971        return rc;
    907972}
Note: See TracChangeset for help on using the changeset viewer.