Ignore:
File:
1 edited

Legend:

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

    rb72efe8 rc4aa9cf  
    6060static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
    6161/** Device connection list head. */
    62 static LIST_INITIALIZE(dcl);
    63 
    64 #define CACHE_BUCKETS_LOG2  10
    65 #define CACHE_BUCKETS       (1 << CACHE_BUCKETS_LOG2)
     62static LIST_INITIALIZE(dcl_head);
     63
     64#define CACHE_BUCKETS_LOG2              10
     65#define CACHE_BUCKETS                   (1 << CACHE_BUCKETS_LOG2)
    6666
    6767typedef struct {
    6868        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. */
     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. */
    7373        hash_table_t block_hash;
    74         list_t free_list;
     74        link_t free_head;
    7575        enum cache_mode mode;
    7676} cache_t;
     
    7979        link_t link;
    8080        devmap_handle_t devmap_handle;
    81         async_sess_t *sess;
     81        int dev_phone;
    8282        fibril_mutex_t comm_area_lock;
    8383        void *comm_area;
     
    8585        void *bb_buf;
    8686        aoff64_t bb_addr;
    87         size_t pblock_size;  /**< Physical block size. */
     87        size_t pblock_size;             /**< Physical block size. */
    8888        cache_t *cache;
    8989} devcon_t;
    9090
    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);
     91static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     92static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     93static int get_block_size(int dev_phone, size_t *bsize);
     94static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
     95static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
    9696
    9797static devcon_t *devcon_search(devmap_handle_t devmap_handle)
    9898{
     99        link_t *cur;
     100
    99101        fibril_mutex_lock(&dcl_lock);
    100        
    101         list_foreach(dcl, cur) {
     102        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    102103                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
    103104                if (devcon->devmap_handle == devmap_handle) {
     
    106107                }
    107108        }
    108        
    109109        fibril_mutex_unlock(&dcl_lock);
    110110        return NULL;
    111111}
    112112
    113 static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess,
    114     size_t bsize, void *comm_area, size_t comm_size)
    115 {
     113static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
     114    void *comm_area, size_t comm_size)
     115{
     116        link_t *cur;
    116117        devcon_t *devcon;
    117        
     118
    118119        if (comm_size < bsize)
    119120                return EINVAL;
    120        
     121
    121122        devcon = malloc(sizeof(devcon_t));
    122123        if (!devcon)
     
    125126        link_initialize(&devcon->link);
    126127        devcon->devmap_handle = devmap_handle;
    127         devcon->sess = sess;
     128        devcon->dev_phone = dev_phone;
    128129        fibril_mutex_initialize(&devcon->comm_area_lock);
    129130        devcon->comm_area = comm_area;
     
    133134        devcon->pblock_size = bsize;
    134135        devcon->cache = NULL;
    135        
     136
    136137        fibril_mutex_lock(&dcl_lock);
    137         list_foreach(dcl, cur) {
     138        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    138139                devcon_t *d = list_get_instance(cur, devcon_t, link);
    139140                if (d->devmap_handle == devmap_handle) {
     
    143144                }
    144145        }
    145         list_append(&devcon->link, &dcl);
     146        list_append(&devcon->link, &dcl_head);
    146147        fibril_mutex_unlock(&dcl_lock);
    147148        return EOK;
     
    155156}
    156157
    157 int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle,
    158     size_t comm_size)
    159 {
    160         void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
     158int block_init(devmap_handle_t devmap_handle, size_t comm_size)
     159{
     160        int rc;
     161        int dev_phone;
     162        void *comm_area;
     163        size_t bsize;
     164
     165        comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    161166            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    162         if (!comm_area)
     167        if (!comm_area) {
    163168                return ENOMEM;
    164        
    165         async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
    166             IPC_FLAG_BLOCKING);
    167         if (!sess) {
     169        }
     170
     171        dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
     172        if (dev_phone < 0) {
    168173                munmap(comm_area, comm_size);
    169                 return ENOENT;
    170         }
    171        
    172         async_exch_t *exch = async_exchange_begin(sess);
    173         int rc = async_share_out_start(exch, comm_area,
     174                return dev_phone;
     175        }
     176
     177        rc = async_share_out_start(dev_phone, comm_area,
    174178            AS_AREA_READ | AS_AREA_WRITE);
    175         async_exchange_end(exch);
    176        
     179        if (rc != EOK) {
     180                munmap(comm_area, comm_size);
     181                async_hangup(dev_phone);
     182                return rc;
     183        }
     184
     185        if (get_block_size(dev_phone, &bsize) != EOK) {
     186                munmap(comm_area, comm_size);
     187                async_hangup(dev_phone);
     188                return rc;
     189        }
     190       
     191        rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size);
    177192        if (rc != EOK) {
    178193                munmap(comm_area, comm_size);
    179                 async_hangup(sess);
     194                async_hangup(dev_phone);
    180195                return rc;
    181196        }
    182        
    183         size_t bsize;
    184         rc = get_block_size(sess, &bsize);
    185        
    186         if (rc != EOK) {
    187                 munmap(comm_area, comm_size);
    188                 async_hangup(sess);
    189                 return rc;
    190         }
    191        
    192         rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size);
    193         if (rc != EOK) {
    194                 munmap(comm_area, comm_size);
    195                 async_hangup(sess);
    196                 return rc;
    197         }
    198        
     197
    199198        return EOK;
    200199}
     
    207206        if (devcon->cache)
    208207                (void) block_cache_fini(devmap_handle);
    209        
     208
    210209        devcon_remove(devcon);
    211        
     210
    212211        if (devcon->bb_buf)
    213212                free(devcon->bb_buf);
    214        
     213
    215214        munmap(devcon->comm_area, devcon->comm_size);
    216         async_hangup(devcon->sess);
    217        
    218         free(devcon);
     215        async_hangup(devcon->dev_phone);
     216
     217        free(devcon);   
    219218}
    220219
     
    291290       
    292291        fibril_mutex_initialize(&cache->lock);
    293         list_initialize(&cache->free_list);
     292        list_initialize(&cache->free_head);
    294293        cache->lblock_size = size;
    295294        cache->block_count = blocks;
     
    332331         * bother with the cache and block locks because we are single-threaded.
    333332         */
    334         while (!list_empty(&cache->free_list)) {
    335                 block_t *b = list_get_instance(list_first(&cache->free_list),
     333        while (!list_empty(&cache->free_head)) {
     334                block_t *b = list_get_instance(cache->free_head.next,
    336335                    block_t, free_link);
    337336
     
    364363        if (cache->blocks_cached < CACHE_LO_WATERMARK)
    365364                return true;
    366         if (!list_empty(&cache->free_list))
     365        if (!list_empty(&cache->free_head))
    367366                return false;
    368367        return true;
     
    453452                        unsigned long temp_key;
    454453recycle:
    455                         if (list_empty(&cache->free_list)) {
     454                        if (list_empty(&cache->free_head)) {
    456455                                fibril_mutex_unlock(&cache->lock);
    457456                                rc = ENOMEM;
    458457                                goto out;
    459458                        }
    460                         l = list_first(&cache->free_list);
     459                        l = cache->free_head.next;
    461460                        b = list_get_instance(l, block_t, free_link);
    462461
     
    473472                                 */
    474473                                list_remove(&b->free_link);
    475                                 list_append(&b->free_link, &cache->free_list);
     474                                list_append(&b->free_link, &cache->free_head);
    476475                                fibril_mutex_unlock(&cache->lock);
    477476                                fibril_mutex_lock(&devcon->comm_area_lock);
     
    665664                        goto retry;
    666665                }
    667                 list_append(&block->free_link, &cache->free_list);
     666                list_append(&block->free_link, &cache->free_head);
    668667        }
    669668        fibril_mutex_unlock(&block->lock);
     
    809808        assert(devcon);
    810809       
    811         return get_block_size(devcon->sess, bsize);
     810        return get_block_size(devcon->dev_phone, bsize);
    812811}
    813812
     
    821820int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
    822821{
    823         devcon_t *devcon = devcon_search(devmap_handle);
    824         assert(devcon);
    825        
    826         return get_num_blocks(devcon->sess, nblocks);
     822        devcon_t *devcon;
     823
     824        devcon = devcon_search(devmap_handle);
     825        assert(devcon);
     826       
     827        return get_num_blocks(devcon->dev_phone, nblocks);
    827828}
    828829
     
    890891static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    891892{
    892         assert(devcon);
    893        
    894         async_exch_t *exch = async_exchange_begin(devcon->sess);
    895         int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
     893        int rc;
     894
     895        assert(devcon);
     896        rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    896897            UPPER32(ba), cnt);
    897         async_exchange_end(exch);
    898        
    899898        if (rc != EOK) {
    900899                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    905904#endif
    906905        }
    907        
    908906        return rc;
    909907}
     
    920918static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    921919{
    922         assert(devcon);
    923        
    924         async_exch_t *exch = async_exchange_begin(devcon->sess);
    925         int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
     920        int rc;
     921
     922        assert(devcon);
     923        rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    926924            UPPER32(ba), cnt);
    927         async_exchange_end(exch);
    928        
    929925        if (rc != EOK) {
    930926                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    934930#endif
    935931        }
    936        
    937932        return rc;
    938933}
    939934
    940935/** Get block size used by the device. */
    941 static int get_block_size(async_sess_t *sess, size_t *bsize)
     936static int get_block_size(int dev_phone, size_t *bsize)
    942937{
    943938        sysarg_t bs;
    944        
    945         async_exch_t *exch = async_exchange_begin(sess);
    946         int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
    947         async_exchange_end(exch);
    948        
     939        int rc;
     940
     941        rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
    949942        if (rc == EOK)
    950943                *bsize = (size_t) bs;
    951        
     944
    952945        return rc;
    953946}
    954947
    955948/** Get total number of blocks on block device. */
    956 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
    957 {
    958         sysarg_t nb_l;
    959         sysarg_t nb_h;
    960        
    961         async_exch_t *exch = async_exchange_begin(sess);
    962         int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    963         async_exchange_end(exch);
    964        
    965         if (rc == EOK)
     949static int get_num_blocks(int dev_phone, aoff64_t *nblocks)
     950{
     951        sysarg_t nb_l, nb_h;
     952        int rc;
     953
     954        rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
     955        if (rc == EOK) {
    966956                *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    967        
     957        }
     958
    968959        return rc;
    969960}
Note: See TracChangeset for help on using the changeset viewer.