Ignore:
File:
1 edited

Legend:

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

    r79ae36dd rc7bbf029  
    22 * Copyright (c) 2008 Jakub Jermar
    33 * Copyright (c) 2008 Martin Decky
    4  * Copyright (c) 2011 Martin Sucha
    54 * All rights reserved.
    65 *
     
    6261static LIST_INITIALIZE(dcl_head);
    6362
    64 #define CACHE_BUCKETS_LOG2  10
    65 #define CACHE_BUCKETS       (1 << CACHE_BUCKETS_LOG2)
     63#define CACHE_BUCKETS_LOG2              10
     64#define CACHE_BUCKETS                   (1 << CACHE_BUCKETS_LOG2)
    6665
    6766typedef struct {
    6867        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. */
     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. */
    7372        hash_table_t block_hash;
    7473        link_t free_head;
     
    7978        link_t link;
    8079        devmap_handle_t devmap_handle;
    81         async_sess_t *sess;
     80        int dev_phone;
    8281        fibril_mutex_t comm_area_lock;
    8382        void *comm_area;
     
    8584        void *bb_buf;
    8685        aoff64_t bb_addr;
    87         size_t pblock_size;  /**< Physical block size. */
     86        size_t pblock_size;             /**< Physical block size. */
    8887        cache_t *cache;
    8988} devcon_t;
    9089
    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);
     90static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     91static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     92static int get_block_size(int dev_phone, size_t *bsize);
     93static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
     94static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
    9695
    9796static devcon_t *devcon_search(devmap_handle_t devmap_handle)
    9897{
    9998        link_t *cur;
    100        
     99
    101100        fibril_mutex_lock(&dcl_lock);
    102        
    103101        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    104102                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
     
    108106                }
    109107        }
    110        
    111108        fibril_mutex_unlock(&dcl_lock);
    112109        return NULL;
    113110}
    114111
    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)
     112static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
     113    void *comm_area, size_t comm_size)
    117114{
    118115        link_t *cur;
    119116        devcon_t *devcon;
    120        
     117
    121118        if (comm_size < bsize)
    122119                return EINVAL;
    123        
     120
    124121        devcon = malloc(sizeof(devcon_t));
    125122        if (!devcon)
     
    128125        link_initialize(&devcon->link);
    129126        devcon->devmap_handle = devmap_handle;
    130         devcon->sess = sess;
     127        devcon->dev_phone = dev_phone;
    131128        fibril_mutex_initialize(&devcon->comm_area_lock);
    132129        devcon->comm_area = comm_area;
     
    136133        devcon->pblock_size = bsize;
    137134        devcon->cache = NULL;
    138        
     135
    139136        fibril_mutex_lock(&dcl_lock);
    140137        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
     
    158155}
    159156
    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,
     157int 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,
    164165            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    165         if (!comm_area)
     166        if (!comm_area) {
    166167                return ENOMEM;
    167        
    168         async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
    169             IPC_FLAG_BLOCKING);
    170         if (!sess) {
     168        }
     169
     170        dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
     171        if (dev_phone < 0) {
    171172                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,
     173                return dev_phone;
     174        }
     175
     176        rc = async_share_out_start(dev_phone, comm_area,
    177177            AS_AREA_READ | AS_AREA_WRITE);
    178         async_exchange_end(exch);
    179        
     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);
    180191        if (rc != EOK) {
    181192                munmap(comm_area, comm_size);
    182                 async_hangup(sess);
     193                async_hangup(dev_phone);
    183194                return rc;
    184195        }
    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        
     196
    202197        return EOK;
    203198}
     
    210205        if (devcon->cache)
    211206                (void) block_cache_fini(devmap_handle);
    212        
     207
    213208        devcon_remove(devcon);
    214        
     209
    215210        if (devcon->bb_buf)
    216211                free(devcon->bb_buf);
    217        
     212
    218213        munmap(devcon->comm_area, devcon->comm_size);
    219         async_hangup(devcon->sess);
    220        
    221         free(devcon);
     214        async_hangup(devcon->dev_phone);
     215
     216        free(devcon);   
    222217}
    223218
     
    812807        assert(devcon);
    813808       
    814         return get_block_size(devcon->sess, bsize);
     809        return get_block_size(devcon->dev_phone, bsize);
    815810}
    816811
     
    824819int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
    825820{
    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;
     821        devcon_t *devcon;
     822
     823        devcon = devcon_search(devmap_handle);
     824        assert(devcon);
     825       
     826        return get_num_blocks(devcon->dev_phone, nblocks);
    882827}
    883828
     
    893838static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    894839{
    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),
     840        int rc;
     841
     842        assert(devcon);
     843        rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    899844            UPPER32(ba), cnt);
    900         async_exchange_end(exch);
    901        
    902845        if (rc != EOK) {
    903846                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    908851#endif
    909852        }
    910        
    911853        return rc;
    912854}
     
    923865static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    924866{
    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),
     867        int rc;
     868
     869        assert(devcon);
     870        rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    929871            UPPER32(ba), cnt);
    930         async_exchange_end(exch);
    931        
    932872        if (rc != EOK) {
    933873                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    937877#endif
    938878        }
    939        
    940879        return rc;
    941880}
    942881
    943882/** Get block size used by the device. */
    944 static int get_block_size(async_sess_t *sess, size_t *bsize)
     883static int get_block_size(int dev_phone, size_t *bsize)
    945884{
    946885        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        
     886        int rc;
     887
     888        rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
    952889        if (rc == EOK)
    953890                *bsize = (size_t) bs;
    954        
     891
    955892        return rc;
    956893}
    957894
    958895/** 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)
     896static 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) {
    969903                *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    970        
     904        }
     905
    971906        return rc;
    972907}
Note: See TracChangeset for help on using the changeset viewer.