Ignore:
File:
1 edited

Legend:

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

    r1e4cada r7a56b1ed  
    4747#include <as.h>
    4848#include <assert.h>
    49 #include <fibril_synch.h>
     49#include <fibril_sync.h>
    5050#include <adt/list.h>
    5151#include <adt/hash_table.h>
    52 #include <macros.h>
    5352#include <mem.h>
    5453
     
    6362typedef struct {
    6463        fibril_mutex_t lock;
    65         size_t lblock_size;             /**< Logical block size. */
     64        size_t block_size;              /**< Block size. */
    6665        unsigned block_count;           /**< Total number of blocks. */
    6766        unsigned blocks_cached;         /**< Number of cached blocks. */
     
    7574        dev_handle_t dev_handle;
    7675        int dev_phone;
    77         fibril_mutex_t comm_area_lock;
    78         void *comm_area;
    79         size_t comm_size;
     76        fibril_mutex_t com_area_lock;
     77        void *com_area;
     78        size_t com_size;
    8079        void *bb_buf;
    81         bn_t bb_addr;
    82         size_t pblock_size;             /**< Physical block size. */
     80        off_t bb_off;
     81        size_t bb_size;
    8382        cache_t *cache;
    8483} devcon_t;
    8584
    86 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
    87 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
    88 static int get_block_size(int dev_phone, size_t *bsize);
     85static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
     86static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
    8987
    9088static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    104102}
    105103
    106 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,
    107     void *comm_area, size_t comm_size)
     104static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,
     105   size_t com_size)
    108106{
    109107        link_t *cur;
    110108        devcon_t *devcon;
    111 
    112         if (comm_size < bsize)
    113                 return EINVAL;
    114109
    115110        devcon = malloc(sizeof(devcon_t));
     
    120115        devcon->dev_handle = dev_handle;
    121116        devcon->dev_phone = dev_phone;
    122         fibril_mutex_initialize(&devcon->comm_area_lock);
    123         devcon->comm_area = comm_area;
    124         devcon->comm_size = comm_size;
     117        fibril_mutex_initialize(&devcon->com_area_lock);
     118        devcon->com_area = com_area;
     119        devcon->com_size = com_size;
    125120        devcon->bb_buf = NULL;
    126         devcon->bb_addr = 0;
    127         devcon->pblock_size = bsize;
     121        devcon->bb_off = 0;
     122        devcon->bb_size = 0;
    128123        devcon->cache = NULL;
    129124
     
    149144}
    150145
    151 int block_init(dev_handle_t dev_handle, size_t comm_size)
     146int block_init(dev_handle_t dev_handle, size_t com_size)
    152147{
    153148        int rc;
    154149        int dev_phone;
    155         void *comm_area;
    156         size_t bsize;
    157 
    158         comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
     150        void *com_area;
     151       
     152        com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
    159153            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    160         if (!comm_area) {
     154        if (!com_area) {
    161155                return ENOMEM;
    162156        }
     
    164158        dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
    165159        if (dev_phone < 0) {
    166                 munmap(comm_area, comm_size);
     160                munmap(com_area, com_size);
    167161                return dev_phone;
    168162        }
    169163
    170         rc = async_share_out_start(dev_phone, comm_area,
     164        rc = ipc_share_out_start(dev_phone, com_area,
    171165            AS_AREA_READ | AS_AREA_WRITE);
    172166        if (rc != EOK) {
    173                 munmap(comm_area, comm_size);
     167                munmap(com_area, com_size);
    174168                ipc_hangup(dev_phone);
    175169                return rc;
    176170        }
    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         }
    183        
    184         rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size);
     171       
     172        rc = devcon_add(dev_handle, dev_phone, com_area, com_size);
    185173        if (rc != EOK) {
    186                 munmap(comm_area, comm_size);
     174                munmap(com_area, com_size);
    187175                ipc_hangup(dev_phone);
    188176                return rc;
     
    207195        }
    208196
    209         munmap(devcon->comm_area, devcon->comm_size);
     197        munmap(devcon->com_area, devcon->com_size);
    210198        ipc_hangup(devcon->dev_phone);
    211199
     
    213201}
    214202
    215 int block_bb_read(dev_handle_t dev_handle, bn_t ba)
     203int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)
    216204{
    217205        void *bb_buf;
     
    223211        if (devcon->bb_buf)
    224212                return EEXIST;
    225         bb_buf = malloc(devcon->pblock_size);
     213        bb_buf = malloc(size);
    226214        if (!bb_buf)
    227215                return ENOMEM;
    228 
    229         fibril_mutex_lock(&devcon->comm_area_lock);
    230         rc = read_blocks(devcon, 0, 1);
     216       
     217        fibril_mutex_lock(&devcon->com_area_lock);
     218        rc = read_block(devcon, 0, size);
    231219        if (rc != EOK) {
    232                 fibril_mutex_unlock(&devcon->comm_area_lock);
     220                fibril_mutex_unlock(&devcon->com_area_lock);
    233221                free(bb_buf);
    234222                return rc;
    235223        }
    236         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    237         fibril_mutex_unlock(&devcon->comm_area_lock);
     224        memcpy(bb_buf, devcon->com_area, size);
     225        fibril_mutex_unlock(&devcon->com_area_lock);
    238226
    239227        devcon->bb_buf = bb_buf;
    240         devcon->bb_addr = ba;
     228        devcon->bb_off = off;
     229        devcon->bb_size = size;
    241230
    242231        return EOK;
     
    286275        fibril_mutex_initialize(&cache->lock);
    287276        list_initialize(&cache->free_head);
    288         cache->lblock_size = size;
     277        cache->block_size = size;
    289278        cache->block_count = blocks;
    290279        cache->blocks_cached = 0;
    291280        cache->mode = mode;
    292 
    293         /* No block size translation a.t.m. */
    294         assert(cache->lblock_size == devcon->pblock_size);
    295281
    296282        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     
    385371                        if (!b)
    386372                                goto recycle;
    387                         b->data = malloc(cache->lblock_size);
     373                        b->data = malloc(cache->block_size);
    388374                        if (!b->data) {
    389375                                free(b);
     
    419405                                list_append(&b->free_link, &cache->free_head);
    420406                                fibril_mutex_unlock(&cache->lock);
    421                                 fibril_mutex_lock(&devcon->comm_area_lock);
    422                                 memcpy(devcon->comm_area, b->data, b->size);
    423                                 rc = write_blocks(devcon, b->boff, 1);
    424                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     407                                fibril_mutex_lock(&devcon->com_area_lock);
     408                                memcpy(devcon->com_area, b->data, b->size);
     409                                rc = write_block(devcon, b->boff,
     410                                    cache->block_size);
     411                                fibril_mutex_unlock(&devcon->com_area_lock);
    425412                                if (rc != EOK) {
    426413                                        /*
     
    457444                block_initialize(b);
    458445                b->dev_handle = dev_handle;
    459                 b->size = cache->lblock_size;
     446                b->size = cache->block_size;
    460447                b->boff = boff;
    461448                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
     
    474461                         * the new contents from the device.
    475462                         */
    476                         fibril_mutex_lock(&devcon->comm_area_lock);
    477                         rc = read_blocks(devcon, b->boff, 1);
    478                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    479                         fibril_mutex_unlock(&devcon->comm_area_lock);
     463                        fibril_mutex_lock(&devcon->com_area_lock);
     464                        rc = read_block(devcon, b->boff, cache->block_size);
     465                        memcpy(b->data, devcon->com_area, cache->block_size);
     466                        fibril_mutex_unlock(&devcon->com_area_lock);
    480467                        if (rc != EOK)
    481468                                b->toxic = true;
     
    534521        if (block->dirty && (block->refcnt == 1) &&
    535522            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    536                 fibril_mutex_lock(&devcon->comm_area_lock);
    537                 memcpy(devcon->comm_area, block->data, block->size);
    538                 rc = write_blocks(devcon, block->boff, 1);
    539                 fibril_mutex_unlock(&devcon->comm_area_lock);
     523                fibril_mutex_lock(&devcon->com_area_lock);
     524                memcpy(devcon->com_area, block->data, block->size);
     525                rc = write_block(devcon, block->boff, block->size);
     526                fibril_mutex_unlock(&devcon->com_area_lock);
    540527                block->dirty = false;
    541528        }
     
    614601 */
    615602int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
    616     off_t *pos, void *dst, size_t size)
     603    off_t *pos, void *dst, size_t size, size_t block_size)
    617604{
    618605        off_t offset = 0;
    619606        size_t left = size;
    620         size_t block_size;
    621         devcon_t *devcon;
    622 
    623         devcon = devcon_search(dev_handle);
     607        devcon_t *devcon = devcon_search(dev_handle);
    624608        assert(devcon);
    625         block_size = devcon->pblock_size;
    626        
    627         fibril_mutex_lock(&devcon->comm_area_lock);
     609       
     610        fibril_mutex_lock(&devcon->com_area_lock);
    628611        while (left > 0) {
    629612                size_t rd;
     
    639622                         * destination buffer.
    640623                         */
    641                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     624                        memcpy(dst + offset, devcon->com_area + *bufpos, rd);
    642625                        offset += rd;
    643626                        *bufpos += rd;
     
    650633                        int rc;
    651634
    652                         rc = read_blocks(devcon, *pos / block_size, 1);
     635                        rc = read_block(devcon, *pos / block_size, block_size);
    653636                        if (rc != EOK) {
    654                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     637                                fibril_mutex_unlock(&devcon->com_area_lock);
    655638                                return rc;
    656639                        }
     
    660643                }
    661644        }
    662         fibril_mutex_unlock(&devcon->comm_area_lock);
     645        fibril_mutex_unlock(&devcon->com_area_lock);
    663646       
    664647        return EOK;
    665648}
    666649
    667 /** Read blocks directly from device (bypass cache).
    668  *
    669  * @param dev_handle    Device handle of the block device.
    670  * @param ba            Address of first block.
    671  * @param cnt           Number of blocks.
     650/** Read block from block device.
     651 *
     652 * @param devcon        Device connection.
     653 * @param boff          Block index.
     654 * @param block_size    Block size.
    672655 * @param src           Buffer for storing the data.
    673656 *
    674657 * @return              EOK on success or negative error code on failure.
    675658 */
    676 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)
    677 {
    678         devcon_t *devcon;
     659static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
     660{
     661        ipcarg_t retval;
    679662        int rc;
    680663
    681         devcon = devcon_search(dev_handle);
    682664        assert(devcon);
    683        
    684         fibril_mutex_lock(&devcon->comm_area_lock);
    685 
    686         rc = read_blocks(devcon, ba, cnt);
    687         if (rc == EOK)
    688                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    689 
    690         fibril_mutex_unlock(&devcon->comm_area_lock);
    691 
    692         return rc;
    693 }
    694 
    695 /** Write blocks directly to device (bypass cache).
    696  *
    697  * @param dev_handle    Device handle of the block device.
    698  * @param ba            Address of first block.
    699  * @param cnt           Number of blocks.
    700  * @param src           The data to be written.
     665        rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
     666            &retval);
     667        if ((rc != EOK) || (retval != EOK))
     668                return (rc != EOK ? rc : (int) retval);
     669
     670        return EOK;
     671}
     672
     673/** Write block to block device.
     674 *
     675 * @param devcon        Device connection.
     676 * @param boff          Block index.
     677 * @param block_size    Block size.
     678 * @param src           Buffer containing the data to write.
    701679 *
    702680 * @return              EOK on success or negative error code on failure.
    703681 */
    704 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt,
    705     const void *data)
    706 {
    707         devcon_t *devcon;
     682static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
     683{
     684        ipcarg_t retval;
    708685        int rc;
    709686
    710         devcon = devcon_search(dev_handle);
    711687        assert(devcon);
    712        
    713         fibril_mutex_lock(&devcon->comm_area_lock);
    714 
    715         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    716         rc = read_blocks(devcon, ba, cnt);
    717 
    718         fibril_mutex_unlock(&devcon->comm_area_lock);
    719 
    720         return rc;
    721 }
    722 
    723 /** Get device block size.
    724  *
    725  * @param dev_handle    Device handle of the block device.
    726  * @param bsize         Output block size.
    727  *
    728  * @return              EOK on success or negative error code on failure.
    729  */
    730 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize)
    731 {
    732         devcon_t *devcon;
    733 
    734         devcon = devcon_search(dev_handle);
    735         assert(devcon);
    736        
    737         return get_block_size(devcon->dev_phone, bsize);
    738 }
    739 
    740 /** Read blocks from block device.
    741  *
    742  * @param devcon        Device connection.
    743  * @param ba            Address of first block.
    744  * @param cnt           Number of blocks.
    745  * @param src           Buffer for storing the data.
    746  *
    747  * @return              EOK on success or negative error code on failure.
    748  */
    749 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
    750 {
    751         int rc;
    752 
    753         assert(devcon);
    754         rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    755             UPPER32(ba), cnt);
    756         return rc;
    757 }
    758 
    759 /** Write block to block device.
    760  *
    761  * @param devcon        Device connection.
    762  * @param ba            Address of first block.
    763  * @param cnt           Number of blocks.
    764  * @param src           Buffer containing the data to write.
    765  *
    766  * @return              EOK on success or negative error code on failure.
    767  */
    768 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
    769 {
    770         int rc;
    771 
    772         assert(devcon);
    773         rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    774             UPPER32(ba), cnt);
    775         return rc;
    776 }
    777 
    778 /** Get block size used by the device. */
    779 static int get_block_size(int dev_phone, size_t *bsize)
    780 {
    781         ipcarg_t bs;
    782         int rc;
    783 
    784         rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
    785         if (rc == EOK)
    786                 *bsize = (size_t) bs;
    787 
    788         return rc;
     688        rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
     689            &retval);
     690        if ((rc != EOK) || (retval != EOK))
     691                return (rc != EOK ? rc : (int) retval);
     692
     693        return EOK;
    789694}
    790695
Note: See TracChangeset for help on using the changeset viewer.