Ignore:
File:
1 edited

Legend:

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

    r08232ee 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);
    89 static int get_num_blocks(int dev_phone, bn_t *nblocks);
     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);
    9087
    9188static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    105102}
    106103
    107 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,
    108     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)
    109106{
    110107        link_t *cur;
    111108        devcon_t *devcon;
    112 
    113         if (comm_size < bsize)
    114                 return EINVAL;
    115109
    116110        devcon = malloc(sizeof(devcon_t));
     
    121115        devcon->dev_handle = dev_handle;
    122116        devcon->dev_phone = dev_phone;
    123         fibril_mutex_initialize(&devcon->comm_area_lock);
    124         devcon->comm_area = comm_area;
    125         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;
    126120        devcon->bb_buf = NULL;
    127         devcon->bb_addr = 0;
    128         devcon->pblock_size = bsize;
     121        devcon->bb_off = 0;
     122        devcon->bb_size = 0;
    129123        devcon->cache = NULL;
    130124
     
    150144}
    151145
    152 int block_init(dev_handle_t dev_handle, size_t comm_size)
     146int block_init(dev_handle_t dev_handle, size_t com_size)
    153147{
    154148        int rc;
    155149        int dev_phone;
    156         void *comm_area;
    157         size_t bsize;
    158 
    159         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,
    160153            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    161         if (!comm_area) {
     154        if (!com_area) {
    162155                return ENOMEM;
    163156        }
     
    165158        dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
    166159        if (dev_phone < 0) {
    167                 munmap(comm_area, comm_size);
     160                munmap(com_area, com_size);
    168161                return dev_phone;
    169162        }
    170163
    171         rc = async_share_out_start(dev_phone, comm_area,
     164        rc = ipc_share_out_start(dev_phone, com_area,
    172165            AS_AREA_READ | AS_AREA_WRITE);
    173166        if (rc != EOK) {
    174                 munmap(comm_area, comm_size);
     167                munmap(com_area, com_size);
    175168                ipc_hangup(dev_phone);
    176169                return rc;
    177170        }
    178 
    179         if (get_block_size(dev_phone, &bsize) != EOK) {
    180                 munmap(comm_area, comm_size);
    181                 ipc_hangup(dev_phone);
    182                 return rc;
    183         }
    184        
    185         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);
    186173        if (rc != EOK) {
    187                 munmap(comm_area, comm_size);
     174                munmap(com_area, com_size);
    188175                ipc_hangup(dev_phone);
    189176                return rc;
     
    208195        }
    209196
    210         munmap(devcon->comm_area, devcon->comm_size);
     197        munmap(devcon->com_area, devcon->com_size);
    211198        ipc_hangup(devcon->dev_phone);
    212199
     
    214201}
    215202
    216 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)
    217204{
    218205        void *bb_buf;
     
    224211        if (devcon->bb_buf)
    225212                return EEXIST;
    226         bb_buf = malloc(devcon->pblock_size);
     213        bb_buf = malloc(size);
    227214        if (!bb_buf)
    228215                return ENOMEM;
    229 
    230         fibril_mutex_lock(&devcon->comm_area_lock);
    231         rc = read_blocks(devcon, 0, 1);
     216       
     217        fibril_mutex_lock(&devcon->com_area_lock);
     218        rc = read_block(devcon, 0, size);
    232219        if (rc != EOK) {
    233                 fibril_mutex_unlock(&devcon->comm_area_lock);
     220                fibril_mutex_unlock(&devcon->com_area_lock);
    234221                free(bb_buf);
    235222                return rc;
    236223        }
    237         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    238         fibril_mutex_unlock(&devcon->comm_area_lock);
     224        memcpy(bb_buf, devcon->com_area, size);
     225        fibril_mutex_unlock(&devcon->com_area_lock);
    239226
    240227        devcon->bb_buf = bb_buf;
    241         devcon->bb_addr = ba;
     228        devcon->bb_off = off;
     229        devcon->bb_size = size;
    242230
    243231        return EOK;
     
    287275        fibril_mutex_initialize(&cache->lock);
    288276        list_initialize(&cache->free_head);
    289         cache->lblock_size = size;
     277        cache->block_size = size;
    290278        cache->block_count = blocks;
    291279        cache->blocks_cached = 0;
    292280        cache->mode = mode;
    293 
    294         /* No block size translation a.t.m. */
    295         assert(cache->lblock_size == devcon->pblock_size);
    296281
    297282        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     
    386371                        if (!b)
    387372                                goto recycle;
    388                         b->data = malloc(cache->lblock_size);
     373                        b->data = malloc(cache->block_size);
    389374                        if (!b->data) {
    390375                                free(b);
     
    420405                                list_append(&b->free_link, &cache->free_head);
    421406                                fibril_mutex_unlock(&cache->lock);
    422                                 fibril_mutex_lock(&devcon->comm_area_lock);
    423                                 memcpy(devcon->comm_area, b->data, b->size);
    424                                 rc = write_blocks(devcon, b->boff, 1);
    425                                 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);
    426412                                if (rc != EOK) {
    427413                                        /*
     
    458444                block_initialize(b);
    459445                b->dev_handle = dev_handle;
    460                 b->size = cache->lblock_size;
     446                b->size = cache->block_size;
    461447                b->boff = boff;
    462448                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
     
    475461                         * the new contents from the device.
    476462                         */
    477                         fibril_mutex_lock(&devcon->comm_area_lock);
    478                         rc = read_blocks(devcon, b->boff, 1);
    479                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    480                         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);
    481467                        if (rc != EOK)
    482468                                b->toxic = true;
     
    535521        if (block->dirty && (block->refcnt == 1) &&
    536522            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    537                 fibril_mutex_lock(&devcon->comm_area_lock);
    538                 memcpy(devcon->comm_area, block->data, block->size);
    539                 rc = write_blocks(devcon, block->boff, 1);
    540                 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);
    541527                block->dirty = false;
    542528        }
     
    615601 */
    616602int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
    617     off_t *pos, void *dst, size_t size)
     603    off_t *pos, void *dst, size_t size, size_t block_size)
    618604{
    619605        off_t offset = 0;
    620606        size_t left = size;
    621         size_t block_size;
    622         devcon_t *devcon;
    623 
    624         devcon = devcon_search(dev_handle);
     607        devcon_t *devcon = devcon_search(dev_handle);
    625608        assert(devcon);
    626         block_size = devcon->pblock_size;
    627        
    628         fibril_mutex_lock(&devcon->comm_area_lock);
     609       
     610        fibril_mutex_lock(&devcon->com_area_lock);
    629611        while (left > 0) {
    630612                size_t rd;
     
    640622                         * destination buffer.
    641623                         */
    642                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     624                        memcpy(dst + offset, devcon->com_area + *bufpos, rd);
    643625                        offset += rd;
    644626                        *bufpos += rd;
     
    651633                        int rc;
    652634
    653                         rc = read_blocks(devcon, *pos / block_size, 1);
     635                        rc = read_block(devcon, *pos / block_size, block_size);
    654636                        if (rc != EOK) {
    655                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     637                                fibril_mutex_unlock(&devcon->com_area_lock);
    656638                                return rc;
    657639                        }
     
    661643                }
    662644        }
    663         fibril_mutex_unlock(&devcon->comm_area_lock);
     645        fibril_mutex_unlock(&devcon->com_area_lock);
    664646       
    665647        return EOK;
    666648}
    667649
    668 /** Read blocks directly from device (bypass cache).
    669  *
    670  * @param dev_handle    Device handle of the block device.
    671  * @param ba            Address of first block.
    672  * @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.
    673655 * @param src           Buffer for storing the data.
    674656 *
    675657 * @return              EOK on success or negative error code on failure.
    676658 */
    677 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)
    678 {
    679         devcon_t *devcon;
     659static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
     660{
     661        ipcarg_t retval;
    680662        int rc;
    681663
    682         devcon = devcon_search(dev_handle);
    683664        assert(devcon);
    684        
    685         fibril_mutex_lock(&devcon->comm_area_lock);
    686 
    687         rc = read_blocks(devcon, ba, cnt);
    688         if (rc == EOK)
    689                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    690 
    691         fibril_mutex_unlock(&devcon->comm_area_lock);
    692 
    693         return rc;
    694 }
    695 
    696 /** Write blocks directly to device (bypass cache).
    697  *
    698  * @param dev_handle    Device handle of the block device.
    699  * @param ba            Address of first block.
    700  * @param cnt           Number of blocks.
    701  * @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.
    702679 *
    703680 * @return              EOK on success or negative error code on failure.
    704681 */
    705 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt,
    706     const void *data)
    707 {
    708         devcon_t *devcon;
     682static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
     683{
     684        ipcarg_t retval;
    709685        int rc;
    710686
    711         devcon = devcon_search(dev_handle);
    712687        assert(devcon);
    713        
    714         fibril_mutex_lock(&devcon->comm_area_lock);
    715 
    716         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    717         rc = write_blocks(devcon, ba, cnt);
    718 
    719         fibril_mutex_unlock(&devcon->comm_area_lock);
    720 
    721         return rc;
    722 }
    723 
    724 /** Get device block size.
    725  *
    726  * @param dev_handle    Device handle of the block device.
    727  * @param bsize         Output block size.
    728  *
    729  * @return              EOK on success or negative error code on failure.
    730  */
    731 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize)
    732 {
    733         devcon_t *devcon;
    734 
    735         devcon = devcon_search(dev_handle);
    736         assert(devcon);
    737        
    738         return get_block_size(devcon->dev_phone, bsize);
    739 }
    740 
    741 /** Get number of blocks on device.
    742  *
    743  * @param dev_handle    Device handle of the block device.
    744  * @param nblocks       Output number of blocks.
    745  *
    746  * @return              EOK on success or negative error code on failure.
    747  */
    748 int block_get_nblocks(dev_handle_t dev_handle, bn_t *nblocks)
    749 {
    750         devcon_t *devcon;
    751 
    752         devcon = devcon_search(dev_handle);
    753         assert(devcon);
    754        
    755         return get_num_blocks(devcon->dev_phone, nblocks);
    756 }
    757 
    758 /** Read blocks from block device.
    759  *
    760  * @param devcon        Device connection.
    761  * @param ba            Address of first block.
    762  * @param cnt           Number of blocks.
    763  * @param src           Buffer for storing the data.
    764  *
    765  * @return              EOK on success or negative error code on failure.
    766  */
    767 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
    768 {
    769         int rc;
    770 
    771         assert(devcon);
    772         rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    773             UPPER32(ba), cnt);
    774         return rc;
    775 }
    776 
    777 /** Write block to block device.
    778  *
    779  * @param devcon        Device connection.
    780  * @param ba            Address of first block.
    781  * @param cnt           Number of blocks.
    782  * @param src           Buffer containing the data to write.
    783  *
    784  * @return              EOK on success or negative error code on failure.
    785  */
    786 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
    787 {
    788         int rc;
    789 
    790         assert(devcon);
    791         rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    792             UPPER32(ba), cnt);
    793         return rc;
    794 }
    795 
    796 /** Get block size used by the device. */
    797 static int get_block_size(int dev_phone, size_t *bsize)
    798 {
    799         ipcarg_t bs;
    800         int rc;
    801 
    802         rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
    803         if (rc == EOK)
    804                 *bsize = (size_t) bs;
    805 
    806         return rc;
    807 }
    808 
    809 /** Get total number of blocks on block device. */
    810 static int get_num_blocks(int dev_phone, bn_t *nblocks)
    811 {
    812         ipcarg_t nb_l, nb_h;
    813         int rc;
    814 
    815         rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    816         if (rc == EOK) {
    817                 *nblocks = (bn_t) MERGE_LOUP32(nb_l, nb_h);
    818         }
    819 
    820         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;
    821694}
    822695
Note: See TracChangeset for help on using the changeset viewer.