Ignore:
File:
1 edited

Legend:

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

    r79ae36dd r5716e9a  
    22 * Copyright (c) 2008 Jakub Jermar
    33 * Copyright (c) 2008 Martin Decky
    4  * Copyright (c) 2011 Martin Sucha
    54 * All rights reserved.
    65 *
     
    5251#include <macros.h>
    5352#include <mem.h>
    54 #include <malloc.h>
    55 #include <stdio.h>
    5653#include <sys/typefmt.h>
    5754#include <stacktrace.h>
     
    6259static LIST_INITIALIZE(dcl_head);
    6360
    64 #define CACHE_BUCKETS_LOG2  10
    65 #define CACHE_BUCKETS       (1 << CACHE_BUCKETS_LOG2)
     61#define CACHE_BUCKETS_LOG2              10
     62#define CACHE_BUCKETS                   (1 << CACHE_BUCKETS_LOG2)
    6663
    6764typedef struct {
    6865        fibril_mutex_t lock;
    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. */
     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. */
    7370        hash_table_t block_hash;
    7471        link_t free_head;
     
    7976        link_t link;
    8077        devmap_handle_t devmap_handle;
    81         async_sess_t *sess;
     78        int dev_phone;
    8279        fibril_mutex_t comm_area_lock;
    8380        void *comm_area;
     
    8582        void *bb_buf;
    8683        aoff64_t bb_addr;
    87         size_t pblock_size;  /**< Physical block size. */
     84        size_t pblock_size;             /**< Physical block size. */
    8885        cache_t *cache;
    8986} devcon_t;
    9087
    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 *);
    95 static aoff64_t ba_ltop(devcon_t *, aoff64_t);
     88static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     89static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     90static int get_block_size(int dev_phone, size_t *bsize);
     91static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
     92static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
    9693
    9794static devcon_t *devcon_search(devmap_handle_t devmap_handle)
    9895{
    9996        link_t *cur;
    100        
     97
    10198        fibril_mutex_lock(&dcl_lock);
    102        
    10399        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    104100                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
     
    108104                }
    109105        }
    110        
    111106        fibril_mutex_unlock(&dcl_lock);
    112107        return NULL;
    113108}
    114109
    115 static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess,
    116     size_t bsize, void *comm_area, size_t comm_size)
     110static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
     111    void *comm_area, size_t comm_size)
    117112{
    118113        link_t *cur;
    119114        devcon_t *devcon;
    120        
     115
    121116        if (comm_size < bsize)
    122117                return EINVAL;
    123        
     118
    124119        devcon = malloc(sizeof(devcon_t));
    125120        if (!devcon)
     
    128123        link_initialize(&devcon->link);
    129124        devcon->devmap_handle = devmap_handle;
    130         devcon->sess = sess;
     125        devcon->dev_phone = dev_phone;
    131126        fibril_mutex_initialize(&devcon->comm_area_lock);
    132127        devcon->comm_area = comm_area;
     
    136131        devcon->pblock_size = bsize;
    137132        devcon->cache = NULL;
    138        
     133
    139134        fibril_mutex_lock(&dcl_lock);
    140135        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
     
    158153}
    159154
    160 int 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,
     155int 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,
    164163            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    165         if (!comm_area)
     164        if (!comm_area) {
    166165                return ENOMEM;
    167        
    168         async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
    169             IPC_FLAG_BLOCKING);
    170         if (!sess) {
     166        }
     167
     168        dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
     169        if (dev_phone < 0) {
    171170                munmap(comm_area, comm_size);
    172                 return ENOENT;
    173         }
    174        
    175         async_exch_t *exch = async_exchange_begin(sess);
    176         int rc = async_share_out_start(exch, comm_area,
     171                return dev_phone;
     172        }
     173
     174        rc = async_share_out_start(dev_phone, comm_area,
    177175            AS_AREA_READ | AS_AREA_WRITE);
    178         async_exchange_end(exch);
    179        
     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);
    180189        if (rc != EOK) {
    181190                munmap(comm_area, comm_size);
    182                 async_hangup(sess);
     191                async_hangup(dev_phone);
    183192                return rc;
    184193        }
    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        
     194
    202195        return EOK;
    203196}
     
    210203        if (devcon->cache)
    211204                (void) block_cache_fini(devmap_handle);
    212        
     205
    213206        devcon_remove(devcon);
    214        
     207
    215208        if (devcon->bb_buf)
    216209                free(devcon->bb_buf);
    217        
     210
    218211        munmap(devcon->comm_area, devcon->comm_size);
    219         async_hangup(devcon->sess);
    220        
    221         free(devcon);
     212        async_hangup(devcon->dev_phone);
     213
     214        free(devcon);   
    222215}
    223216
     
    812805        assert(devcon);
    813806       
    814         return get_block_size(devcon->sess, bsize);
     807        return get_block_size(devcon->dev_phone, bsize);
    815808}
    816809
     
    824817int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
    825818{
    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  */
    841 int 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;
     819        devcon_t *devcon;
     820
     821        devcon = devcon_search(devmap_handle);
     822        assert(devcon);
     823       
     824        return get_num_blocks(devcon->dev_phone, nblocks);
    882825}
    883826
     
    893836static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    894837{
    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),
     838        int rc;
     839
     840        assert(devcon);
     841        rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    899842            UPPER32(ba), cnt);
    900         async_exchange_end(exch);
    901        
    902843        if (rc != EOK) {
    903844                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    908849#endif
    909850        }
    910        
    911851        return rc;
    912852}
     
    923863static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    924864{
    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),
     865        int rc;
     866
     867        assert(devcon);
     868        rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    929869            UPPER32(ba), cnt);
    930         async_exchange_end(exch);
    931        
    932870        if (rc != EOK) {
    933871                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    937875#endif
    938876        }
    939        
    940877        return rc;
    941878}
    942879
    943880/** Get block size used by the device. */
    944 static int get_block_size(async_sess_t *sess, size_t *bsize)
     881static int get_block_size(int dev_phone, size_t *bsize)
    945882{
    946883        sysarg_t 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        
     884        int rc;
     885
     886        rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
    952887        if (rc == EOK)
    953888                *bsize = (size_t) bs;
    954        
     889
    955890        return rc;
    956891}
    957892
    958893/** Get total number of blocks on block device. */
    959 static 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)
     894static 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) {
    969901                *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    970        
     902        }
     903
    971904        return rc;
    972905}
Note: See TracChangeset for help on using the changeset viewer.