Changeset cfa8738 in mainline for uspace/lib/libblock/libblock.c


Ignore:
Timestamp:
2009-08-30T22:30:42Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d061efe
Parents:
ff62c6d (diff), a830611 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge block device interface improvements.

File:
1 edited

Legend:

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

    rff62c6d rcfa8738  
    5050#include <adt/list.h>
    5151#include <adt/hash_table.h>
     52#include <macros.h>
    5253#include <mem.h>
    5354
     
    6263typedef struct {
    6364        fibril_mutex_t lock;
    64         size_t block_size;              /**< Block size. */
     65        size_t lblock_size;             /**< Logical block size. */
    6566        unsigned block_count;           /**< Total number of blocks. */
    6667        unsigned blocks_cached;         /**< Number of cached blocks. */
     
    7475        dev_handle_t dev_handle;
    7576        int dev_phone;
    76         fibril_mutex_t com_area_lock;
    77         void *com_area;
    78         size_t com_size;
     77        fibril_mutex_t comm_area_lock;
     78        void *comm_area;
     79        size_t comm_size;
    7980        void *bb_buf;
    80         off_t bb_off;
    81         size_t bb_size;
     81        bn_t bb_addr;
     82        size_t pblock_size;             /**< Physical block size. */
    8283        cache_t *cache;
    8384} devcon_t;
    8485
    85 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
    86 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
     86static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
     87static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
     88static size_t get_block_size(int dev_phone, size_t *bsize);
    8789
    8890static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    102104}
    103105
    104 static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,
    105    size_t com_size)
     106static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,
     107    void *comm_area, size_t comm_size)
    106108{
    107109        link_t *cur;
    108110        devcon_t *devcon;
     111
     112        if (comm_size < bsize)
     113                return EINVAL;
    109114
    110115        devcon = malloc(sizeof(devcon_t));
     
    115120        devcon->dev_handle = dev_handle;
    116121        devcon->dev_phone = dev_phone;
    117         fibril_mutex_initialize(&devcon->com_area_lock);
    118         devcon->com_area = com_area;
    119         devcon->com_size = com_size;
     122        fibril_mutex_initialize(&devcon->comm_area_lock);
     123        devcon->comm_area = comm_area;
     124        devcon->comm_size = comm_size;
    120125        devcon->bb_buf = NULL;
    121         devcon->bb_off = 0;
    122         devcon->bb_size = 0;
     126        devcon->bb_addr = 0;
     127        devcon->pblock_size = bsize;
    123128        devcon->cache = NULL;
    124129
     
    144149}
    145150
    146 int block_init(dev_handle_t dev_handle, size_t com_size)
     151int block_init(dev_handle_t dev_handle, size_t comm_size)
    147152{
    148153        int rc;
    149154        int dev_phone;
    150         void *com_area;
    151        
    152         com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
     155        void *comm_area;
     156        size_t bsize;
     157
     158        comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    153159            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    154         if (!com_area) {
     160        if (!comm_area) {
    155161                return ENOMEM;
    156162        }
     
    158164        dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
    159165        if (dev_phone < 0) {
    160                 munmap(com_area, com_size);
     166                munmap(comm_area, comm_size);
    161167                return dev_phone;
    162168        }
    163169
    164         rc = ipc_share_out_start(dev_phone, com_area,
     170        rc = ipc_share_out_start(dev_phone, comm_area,
    165171            AS_AREA_READ | AS_AREA_WRITE);
    166172        if (rc != EOK) {
    167                 munmap(com_area, com_size);
     173                munmap(comm_area, comm_size);
    168174                ipc_hangup(dev_phone);
    169175                return rc;
    170176        }
     177
     178        if (get_block_size(dev_phone, &bsize) != EOK) {
     179                munmap(comm_area, comm_size);
     180                ipc_hangup(dev_phone);
     181                return rc;
     182        }
    171183       
    172         rc = devcon_add(dev_handle, dev_phone, com_area, com_size);
     184        rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size);
    173185        if (rc != EOK) {
    174                 munmap(com_area, com_size);
     186                munmap(comm_area, comm_size);
    175187                ipc_hangup(dev_phone);
    176188                return rc;
     
    195207        }
    196208
    197         munmap(devcon->com_area, devcon->com_size);
     209        munmap(devcon->comm_area, devcon->comm_size);
    198210        ipc_hangup(devcon->dev_phone);
    199211
     
    201213}
    202214
    203 int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)
     215int block_bb_read(dev_handle_t dev_handle, bn_t ba)
    204216{
    205217        void *bb_buf;
     
    211223        if (devcon->bb_buf)
    212224                return EEXIST;
    213         bb_buf = malloc(size);
     225        bb_buf = malloc(devcon->pblock_size);
    214226        if (!bb_buf)
    215227                return ENOMEM;
    216        
    217         fibril_mutex_lock(&devcon->com_area_lock);
    218         rc = read_block(devcon, 0, size);
     228
     229        fibril_mutex_lock(&devcon->comm_area_lock);
     230        rc = read_blocks(devcon, 0, 1);
    219231        if (rc != EOK) {
    220                 fibril_mutex_unlock(&devcon->com_area_lock);
     232                fibril_mutex_unlock(&devcon->comm_area_lock);
    221233                free(bb_buf);
    222234                return rc;
    223235        }
    224         memcpy(bb_buf, devcon->com_area, size);
    225         fibril_mutex_unlock(&devcon->com_area_lock);
     236        memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
     237        fibril_mutex_unlock(&devcon->comm_area_lock);
    226238
    227239        devcon->bb_buf = bb_buf;
    228         devcon->bb_off = off;
    229         devcon->bb_size = size;
     240        devcon->bb_addr = ba;
    230241
    231242        return EOK;
     
    275286        fibril_mutex_initialize(&cache->lock);
    276287        list_initialize(&cache->free_head);
    277         cache->block_size = size;
     288        cache->lblock_size = size;
    278289        cache->block_count = blocks;
    279290        cache->blocks_cached = 0;
    280291        cache->mode = mode;
     292
     293        /* No block size translation a.t.m. */
     294        assert(cache->lblock_size == devcon->pblock_size);
    281295
    282296        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     
    368382                        if (!b)
    369383                                goto recycle;
    370                         b->data = malloc(cache->block_size);
     384                        b->data = malloc(cache->lblock_size);
    371385                        if (!b->data) {
    372386                                free(b);
     
    398412                                list_append(&b->free_link, &cache->free_head);
    399413                                fibril_mutex_unlock(&cache->lock);
    400                                 fibril_mutex_lock(&devcon->com_area_lock);
    401                                 memcpy(devcon->com_area, b->data, b->size);
    402                                 rc = write_block(devcon, b->boff,
    403                                     cache->block_size);
    404                                 fibril_mutex_unlock(&devcon->com_area_lock);
     414                                fibril_mutex_lock(&devcon->comm_area_lock);
     415                                memcpy(devcon->comm_area, b->data, b->size);
     416                                rc = write_blocks(devcon, b->boff, 1);
     417                                fibril_mutex_unlock(&devcon->comm_area_lock);
    405418                                if (rc != EOK) {
    406419                                        /*
     
    437450                block_initialize(b);
    438451                b->dev_handle = dev_handle;
    439                 b->size = cache->block_size;
     452                b->size = cache->lblock_size;
    440453                b->boff = boff;
    441454                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
     
    454467                         * the new contents from the device.
    455468                         */
    456                         fibril_mutex_lock(&devcon->com_area_lock);
    457                         rc = read_block(devcon, b->boff, cache->block_size);
    458                         memcpy(b->data, devcon->com_area, cache->block_size);
    459                         fibril_mutex_unlock(&devcon->com_area_lock);
     469                        fibril_mutex_lock(&devcon->comm_area_lock);
     470                        rc = read_blocks(devcon, b->boff, 1);
     471                        memcpy(b->data, devcon->comm_area, cache->lblock_size);
     472                        fibril_mutex_unlock(&devcon->comm_area_lock);
    460473                        if (rc != EOK)
    461474                                b->toxic = true;
     
    508521        if (block->dirty && (block->refcnt == 1) &&
    509522            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    510                 fibril_mutex_lock(&devcon->com_area_lock);
    511                 memcpy(devcon->com_area, block->data, block->size);
    512                 rc = write_block(devcon, block->boff, block->size);
    513                 fibril_mutex_unlock(&devcon->com_area_lock);
     523                fibril_mutex_lock(&devcon->comm_area_lock);
     524                memcpy(devcon->comm_area, block->data, block->size);
     525                rc = write_blocks(devcon, block->boff, 1);
     526                fibril_mutex_unlock(&devcon->comm_area_lock);
    514527                block->dirty = false;
    515528        }
     
    588601 */
    589602int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
    590     off_t *pos, void *dst, size_t size, size_t block_size)
     603    off_t *pos, void *dst, size_t size)
    591604{
    592605        off_t offset = 0;
    593606        size_t left = size;
    594         devcon_t *devcon = devcon_search(dev_handle);
     607        size_t block_size;
     608        devcon_t *devcon;
     609
     610        devcon = devcon_search(dev_handle);
    595611        assert(devcon);
     612        block_size = devcon->pblock_size;
    596613       
    597         fibril_mutex_lock(&devcon->com_area_lock);
     614        fibril_mutex_lock(&devcon->comm_area_lock);
    598615        while (left > 0) {
    599616                size_t rd;
     
    609626                         * destination buffer.
    610627                         */
    611                         memcpy(dst + offset, devcon->com_area + *bufpos, rd);
     628                        memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
    612629                        offset += rd;
    613630                        *bufpos += rd;
     
    620637                        int rc;
    621638
    622                         rc = read_block(devcon, *pos / block_size, block_size);
     639                        rc = read_blocks(devcon, *pos / block_size, 1);
    623640                        if (rc != EOK) {
    624                                 fibril_mutex_unlock(&devcon->com_area_lock);
     641                                fibril_mutex_unlock(&devcon->comm_area_lock);
    625642                                return rc;
    626643                        }
     
    630647                }
    631648        }
    632         fibril_mutex_unlock(&devcon->com_area_lock);
     649        fibril_mutex_unlock(&devcon->comm_area_lock);
    633650       
    634651        return EOK;
    635652}
    636653
    637 /** Read block from block device.
     654/** Read blocks from block device.
    638655 *
    639656 * @param devcon        Device connection.
    640  * @param boff          Block index.
    641  * @param block_size    Block size.
     657 * @param ba            Address of first block.
     658 * @param cnt           Number of blocks.
    642659 * @param src           Buffer for storing the data.
    643660 *
    644661 * @return              EOK on success or negative error code on failure.
    645662 */
    646 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
    647 {
    648         ipcarg_t retval;
     663static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
     664{
    649665        int rc;
    650666
    651667        assert(devcon);
    652         rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
    653             &retval);
    654         if ((rc != EOK) || (retval != EOK))
    655                 return (rc != EOK ? rc : (int) retval);
    656 
    657         return EOK;
     668        rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
     669            UPPER32(ba), cnt);
     670        return rc;
    658671}
    659672
     
    661674 *
    662675 * @param devcon        Device connection.
    663  * @param boff          Block index.
    664  * @param block_size    Block size.
     676 * @param ba            Address of first block.
     677 * @param cnt           Number of blocks.
    665678 * @param src           Buffer containing the data to write.
    666679 *
    667680 * @return              EOK on success or negative error code on failure.
    668681 */
    669 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
    670 {
    671         ipcarg_t retval;
     682static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
     683{
    672684        int rc;
    673685
    674686        assert(devcon);
    675         rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
    676             &retval);
    677         if ((rc != EOK) || (retval != EOK))
    678                 return (rc != EOK ? rc : (int) retval);
    679 
    680         return EOK;
     687        rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
     688            UPPER32(ba), cnt);
     689        return rc;
     690}
     691
     692/** Get block size used by the device. */
     693static size_t get_block_size(int dev_phone, size_t *bsize)
     694{
     695        ipcarg_t bs;
     696        int rc;
     697
     698        rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
     699        if (rc == EOK)
     700                *bsize = (size_t) bs;
     701
     702        return rc;
    681703}
    682704
Note: See TracChangeset for help on using the changeset viewer.