Changeset 1ee00b7 in mainline


Ignore:
Timestamp:
2009-08-30T22:25:48Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a830611
Parents:
ff62c6d
Message:

Revamp block device interface: (1) block size is fixed, determined by BDD. (2) block address is 64-bit, (3) allow reading/writing more blocks at a time.

Location:
uspace
Files:
9 edited

Legend:

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

    rff62c6d r1ee00b7  
    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. */
     
    7879        size_t com_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 *com_area, size_t com_size)
    106108{
    107109        link_t *cur;
    108110        devcon_t *devcon;
     111
     112        if (com_size < bsize)
     113                return EINVAL;
    109114
    110115        devcon = malloc(sizeof(devcon_t));
     
    119124        devcon->com_size = com_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
     
    149154        int dev_phone;
    150155        void *com_area;
    151        
     156        size_t bsize;
     157
    152158        com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
    153159            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
     
    169175                return rc;
    170176        }
     177
     178        if (get_block_size(dev_phone, &bsize) != EOK) {
     179                munmap(com_area, com_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, com_area, com_size);
    173185        if (rc != EOK) {
    174186                munmap(com_area, com_size);
     
    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        
     228
    217229        fibril_mutex_lock(&devcon->com_area_lock);
    218         rc = read_block(devcon, 0, size);
     230        rc = read_blocks(devcon, 0, 1);
    219231        if (rc != EOK) {
    220232                fibril_mutex_unlock(&devcon->com_area_lock);
     
    222234                return rc;
    223235        }
    224         memcpy(bb_buf, devcon->com_area, size);
     236        memcpy(bb_buf, devcon->com_area, devcon->pblock_size);
    225237        fibril_mutex_unlock(&devcon->com_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);
     
    400414                                fibril_mutex_lock(&devcon->com_area_lock);
    401415                                memcpy(devcon->com_area, b->data, b->size);
    402                                 rc = write_block(devcon, b->boff,
    403                                     cache->block_size);
     416                                rc = write_blocks(devcon, b->boff, 1);
    404417                                fibril_mutex_unlock(&devcon->com_area_lock);
    405418                                if (rc != EOK) {
     
    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);
     
    455468                         */
    456469                        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);
     470                        rc = read_blocks(devcon, b->boff, 1);
     471                        memcpy(b->data, devcon->com_area, cache->lblock_size);
    459472                        fibril_mutex_unlock(&devcon->com_area_lock);
    460473                        if (rc != EOK)
     
    510523                fibril_mutex_lock(&devcon->com_area_lock);
    511524                memcpy(devcon->com_area, block->data, block->size);
    512                 rc = write_block(devcon, block->boff, block->size);
     525                rc = write_blocks(devcon, block->boff, 1);
    513526                fibril_mutex_unlock(&devcon->com_area_lock);
    514527                block->dirty = false;
     
    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       
    597614        fibril_mutex_lock(&devcon->com_area_lock);
     
    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) {
    624641                                fibril_mutex_unlock(&devcon->com_area_lock);
     
    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
  • uspace/lib/libblock/libblock.h

    rff62c6d r1ee00b7  
    6060#define BLOCK_FLAGS_NOREAD      1
    6161
    62 typedef unsigned bn_t;  /**< Block number type. */
     62typedef uint64_t bn_t;  /**< Block number type. */
    6363
    6464typedef struct block {
     
    9898extern void block_fini(dev_handle_t);
    9999
    100 extern int block_bb_read(dev_handle_t, off_t, size_t);
     100extern int block_bb_read(dev_handle_t, bn_t);
    101101extern void *block_bb_get(dev_handle_t);
    102102
     
    107107
    108108extern int block_seqread(dev_handle_t, off_t *, size_t *, off_t *, void *,
    109     size_t, size_t);
     109    size_t);
    110110
    111111#endif
  • uspace/lib/libc/include/ipc/bd.h

    rff62c6d r1ee00b7  
    3939
    4040typedef enum {
    41         BD_READ_BLOCK = IPC_FIRST_USER_METHOD,
    42         BD_WRITE_BLOCK
     41        BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD,
     42        BD_READ_BLOCKS,
     43        BD_WRITE_BLOCKS
    4344} bd_request_t;
    4445
  • uspace/srv/bd/ata_bd/ata_bd.c

    rff62c6d r1ee00b7  
    6262#include <bool.h>
    6363#include <task.h>
     64#include <macros.h>
    6465
    6566#include "ata_bd.h"
     
    8687static int ata_bd_init(void);
    8788static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
    88 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
     89static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
    8990    void *buf);
    90 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     91static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     92    const void *buf);
     93static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt,
    9194    void *buf);
    92 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     95static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
    9396    const void *buf);
    9497static int disk_init(disk_t *d, int disk_id);
    9598static int drive_identify(int drive_id, void *buf);
    9699static void disk_print_summary(disk_t *d);
    97 static int coord_calc(disk_t *d, uint64_t blk_idx, block_coord_t *bc);
     100static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
    98101static void coord_sc_program(const block_coord_t *bc, uint16_t scnt);
    99102static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
     
    228231        int flags;
    229232        int retval;
    230         off_t idx;
    231         size_t size;
     233        uint64_t ba;
     234        size_t cnt;
    232235        int disk_id, i;
    233236
     
    270273                        ipc_answer_0(callid, EOK);
    271274                        return;
    272                 case BD_READ_BLOCK:
    273                 case BD_WRITE_BLOCK:
    274                         idx = IPC_GET_ARG1(call);
    275                         size = IPC_GET_ARG2(call);
    276                         if (size > comm_size) {
    277                                 retval = EINVAL;
     275                case BD_READ_BLOCKS:
     276                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     277                            IPC_GET_ARG2(call));
     278                        cnt = IPC_GET_ARG3(call);
     279                        if (cnt * block_size > comm_size) {
     280                                retval = ELIMIT;
    278281                                break;
    279282                        }
    280                         retval = ata_bd_rdwr(disk_id, method, idx,
    281                             size, fs_va);
     283                        retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va);
    282284                        break;
     285                case BD_WRITE_BLOCKS:
     286                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     287                            IPC_GET_ARG2(call));
     288                        cnt = IPC_GET_ARG3(call);
     289                        if (cnt * block_size > comm_size) {
     290                                retval = ELIMIT;
     291                                break;
     292                        }
     293                        retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va);
     294                        break;
     295                case BD_GET_BLOCK_SIZE:
     296                        ipc_answer_1(callid, EOK, block_size);
     297                        continue;
    283298                default:
    284299                        retval = EINVAL;
     
    373388}
    374389
    375 /** Transfer a logical block from/to the device.
    376  *
    377  * @param disk_id       Device index (0 or 1)
    378  * @param method        @c BD_READ_BLOCK or @c BD_WRITE_BLOCK
    379  * @param blk_idx       Index of the first block.
    380  * @param size          Size of the logical block.
    381  * @param buf           Data buffer.
    382  *
    383  * @return EOK on success, EIO on error.
    384  */
    385 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size,
    386     void *buf)
    387 {
     390/** Read multiple blocks from the device. */
     391static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     392    void *buf) {
     393
    388394        int rc;
    389         size_t now;
    390 
    391         while (size > 0) {
    392                 now = size < block_size ? size : block_size;
    393                 if (now != block_size)
    394                         return EINVAL;
    395 
    396                 if (method == BD_READ_BLOCK)
    397                         rc = ata_bd_read_block(disk_id, blk_idx, 1, buf);
    398                 else
    399                         rc = ata_bd_write_block(disk_id, blk_idx, 1, buf);
    400 
     395
     396        while (cnt > 0) {
     397                rc = ata_bd_read_block(disk_id, ba, 1, buf);
    401398                if (rc != EOK)
    402399                        return rc;
    403400
     401                ++ba;
     402                --cnt;
    404403                buf += block_size;
    405                 blk_idx++;
    406 
    407                 if (size > block_size)
    408                         size -= block_size;
    409                 else
    410                         size = 0;
     404        }
     405
     406        return EOK;
     407}
     408
     409/** Write multiple blocks to the device. */
     410static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     411    const void *buf) {
     412
     413        int rc;
     414
     415        while (cnt > 0) {
     416                rc = ata_bd_write_block(disk_id, ba, 1, buf);
     417                if (rc != EOK)
     418                        return rc;
     419
     420                ++ba;
     421                --cnt;
     422                buf += block_size;
    411423        }
    412424
     
    466478 *
    467479 * @param disk_id       Device index (0 or 1)
    468  * @param blk_idx       Index of the first block.
    469  * @param blk_cnt       Number of blocks to transfer.
     480 * @param ba            Address the first block.
     481 * @param cnt           Number of blocks to transfer.
    470482 * @param buf           Buffer for holding the data.
    471483 *
    472484 * @return EOK on success, EIO on error.
    473485 */
    474 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     486static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,
    475487    void *buf)
    476488{
     
    486498
    487499        /* Compute block coordinates. */
    488         if (coord_calc(d, blk_idx, &bc) != EOK)
     500        if (coord_calc(d, ba, &bc) != EOK)
    489501                return EINVAL;
    490502
     
    541553 *
    542554 * @param disk_id       Device index (0 or 1)
    543  * @param blk_idx       Index of the first block.
    544  * @param blk_cnt       Number of blocks to transfer.
     555 * @param ba            Address of the first block.
     556 * @param cnt           Number of blocks to transfer.
    545557 * @param buf           Buffer holding the data to write.
    546558 *
    547559 * @return EOK on success, EIO on error.
    548560 */
    549 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
     561static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
    550562    const void *buf)
    551563{
     
    560572
    561573        /* Compute block coordinates. */
    562         if (coord_calc(d, blk_idx, &bc) != EOK)
     574        if (coord_calc(d, ba, &bc) != EOK)
    563575                return EINVAL;
    564576
     
    620632 * @return EOK on success or EINVAL if block index is past end of device.
    621633 */
    622 static int coord_calc(disk_t *d, uint64_t blk_idx, block_coord_t *bc)
     634static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc)
    623635{
    624636        uint64_t c;
     
    626638
    627639        /* Check device bounds. */
    628         if (blk_idx >= d->blocks)
     640        if (ba >= d->blocks)
    629641                return EINVAL;
    630642
     
    634646        case am_chs:
    635647                /* Compute CHS coordinates. */
    636                 c = blk_idx / (d->geom.heads * d->geom.sectors);
    637                 idx = blk_idx % (d->geom.heads * d->geom.sectors);
     648                c = ba / (d->geom.heads * d->geom.sectors);
     649                idx = ba % (d->geom.heads * d->geom.sectors);
    638650
    639651                bc->cyl_lo = c & 0xff;
     
    645657        case am_lba28:
    646658                /* Compute LBA-28 coordinates. */
    647                 bc->c0 = blk_idx & 0xff;                /* bits 0-7 */
    648                 bc->c1 = (blk_idx >> 8) & 0xff;         /* bits 8-15 */
    649                 bc->c2 = (blk_idx >> 16) & 0xff;        /* bits 16-23 */
    650                 bc->h  = (blk_idx >> 24) & 0x0f;        /* bits 24-27 */
     659                bc->c0 = ba & 0xff;             /* bits 0-7 */
     660                bc->c1 = (ba >> 8) & 0xff;      /* bits 8-15 */
     661                bc->c2 = (ba >> 16) & 0xff;     /* bits 16-23 */
     662                bc->h  = (ba >> 24) & 0x0f;     /* bits 24-27 */
    651663                break;
    652664
    653665        case am_lba48:
    654666                /* Compute LBA-48 coordinates. */
    655                 bc->c0 = blk_idx & 0xff;                /* bits 0-7 */
    656                 bc->c1 = (blk_idx >> 8) & 0xff;         /* bits 8-15 */
    657                 bc->c2 = (blk_idx >> 16) & 0xff;        /* bits 16-23 */
    658                 bc->c3 = (blk_idx >> 24) & 0xff;        /* bits 24-31 */
    659                 bc->c4 = (blk_idx >> 32) & 0xff;        /* bits 32-39 */
    660                 bc->c5 = (blk_idx >> 40) & 0xff;        /* bits 40-47 */
     667                bc->c0 = ba & 0xff;             /* bits 0-7 */
     668                bc->c1 = (ba >> 8) & 0xff;      /* bits 8-15 */
     669                bc->c2 = (ba >> 16) & 0xff;     /* bits 16-23 */
     670                bc->c3 = (ba >> 24) & 0xff;     /* bits 24-31 */
     671                bc->c4 = (ba >> 32) & 0xff;     /* bits 32-39 */
     672                bc->c5 = (ba >> 40) & 0xff;     /* bits 40-47 */
    661673                bc->h  = 0;
    662674                break;
  • uspace/srv/bd/file_bd/file_bd.c

    rff62c6d r1ee00b7  
    5151#include <bool.h>
    5252#include <task.h>
     53#include <macros.h>
    5354
    5455#define NAME "file_bd"
    5556
    56 static size_t comm_size;
     57static const size_t block_size = 512;
    5758static FILE *img;
    5859
     
    6263static int file_bd_init(const char *fname);
    6364static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
    64 static int file_bd_read(off_t blk_idx, size_t size, void *buf);
    65 static int file_bd_write(off_t blk_idx, size_t size, void *buf);
     65static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf);
     66static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
    6667
    6768int main(int argc, char **argv)
     
    120121        ipc_call_t call;
    121122        ipcarg_t method;
     123        size_t comm_size;
    122124        int flags;
    123125        int retval;
    124         off_t idx;
    125         size_t size;
     126        uint64_t ba;
     127        size_t cnt;
    126128
    127129        /* Answer the IPC_M_CONNECT_ME_TO call. */
     
    149151                        ipc_answer_0(callid, EOK);
    150152                        return;
    151                 case BD_READ_BLOCK:
    152                 case BD_WRITE_BLOCK:
    153                         idx = IPC_GET_ARG1(call);
    154                         size = IPC_GET_ARG2(call);
    155                         if (size > comm_size) {
    156                                 retval = EINVAL;
     153                case BD_READ_BLOCKS:
     154                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     155                            IPC_GET_ARG2(call));
     156                        cnt = IPC_GET_ARG3(call);
     157                        if (cnt * block_size > comm_size) {
     158                                retval = ELIMIT;
    157159                                break;
    158160                        }
    159                         if (method == BD_READ_BLOCK)
    160                                 retval = file_bd_read(idx, size, fs_va);
    161                         else
    162                                 retval = file_bd_write(idx, size, fs_va);
     161                        retval = file_bd_read_blocks(ba, cnt, fs_va);
    163162                        break;
     163                case BD_WRITE_BLOCKS:
     164                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     165                            IPC_GET_ARG2(call));
     166                        cnt = IPC_GET_ARG3(call);
     167                        if (cnt * block_size > comm_size) {
     168                                retval = ELIMIT;
     169                                break;
     170                        }
     171                        retval = file_bd_write_blocks(ba, cnt, fs_va);
     172                        break;
     173                case BD_GET_BLOCK_SIZE:
     174                        ipc_answer_1(callid, EOK, block_size);
     175                        continue;
    164176                default:
    165177                        retval = EINVAL;
     
    170182}
    171183
    172 static int file_bd_read(off_t blk_idx, size_t size, void *buf)
     184/** Read blocks from the device. */
     185static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf)
    173186{
    174187        size_t n_rd;
     
    176189        fibril_mutex_lock(&dev_lock);
    177190
    178         fseek(img, blk_idx * size, SEEK_SET);
    179         n_rd = fread(buf, 1, size, img);
     191        fseek(img, ba * block_size, SEEK_SET);
     192        n_rd = fread(buf, block_size, cnt, img);
    180193
    181194        if (ferror(img)) {
     
    186199        fibril_mutex_unlock(&dev_lock);
    187200
    188         if (n_rd < size)
    189                 return EINVAL;  /* Read beyond end of disk */
     201        if (n_rd < cnt)
     202                return EINVAL;  /* Read beyond end of device */
    190203
    191204        return EOK;
    192205}
    193206
    194 static int file_bd_write(off_t blk_idx, size_t size, void *buf)
     207/** Write blocks to the device. */
     208static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
    195209{
    196210        size_t n_wr;
     
    198212        fibril_mutex_lock(&dev_lock);
    199213
    200         fseek(img, blk_idx * size, SEEK_SET);
    201         n_wr = fread(buf, 1, size, img);
    202 
    203         if (ferror(img) || n_wr < size) {
     214        fseek(img, ba * block_size, SEEK_SET);
     215        n_wr = fread(buf, block_size, cnt, img);
     216
     217        if (ferror(img) || n_wr < cnt) {
    204218                fibril_mutex_unlock(&dev_lock);
    205219                return EIO;     /* Write error */
  • uspace/srv/bd/gxe_bd/gxe_bd.c

    rff62c6d r1ee00b7  
    4747#include <sys/types.h>
    4848#include <errno.h>
     49#include <macros.h>
    4950#include <task.h>
    5051
     
    9798static int gxe_bd_init(void);
    9899static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
    99 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
     100static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
    100101    void *buf);
    101 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
    102     void *buf);
    103 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
     102static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
    104103    const void *buf);
     104static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf);
     105static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf);
    105106
    106107int main(int argc, char **argv)
     
    163164        int flags;
    164165        int retval;
    165         off_t idx;
    166         size_t size;
     166        uint64_t ba;
     167        unsigned cnt;
    167168        int disk_id, i;
    168169
     
    185186
    186187        if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
     188                ipc_answer_0(callid, EHANGUP);
     189                return;
     190        }
     191
     192        if (comm_size < block_size) {
    187193                ipc_answer_0(callid, EHANGUP);
    188194                return;
     
    205211                        ipc_answer_0(callid, EOK);
    206212                        return;
    207                 case BD_READ_BLOCK:
    208                 case BD_WRITE_BLOCK:
    209                         idx = IPC_GET_ARG1(call);
    210                         size = IPC_GET_ARG2(call);
    211                         if (size > comm_size) {
    212                                 retval = EINVAL;
     213                case BD_READ_BLOCKS:
     214                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     215                            IPC_GET_ARG2(call));
     216                        cnt = IPC_GET_ARG3(call);
     217                        if (cnt * block_size > comm_size) {
     218                                retval = ELIMIT;
    213219                                break;
    214220                        }
    215                         retval = gx_bd_rdwr(disk_id, method, idx * size,
    216                             size, fs_va);
     221                        retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va);
    217222                        break;
     223                case BD_WRITE_BLOCKS:
     224                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     225                            IPC_GET_ARG2(call));
     226                        cnt = IPC_GET_ARG3(call);
     227                        if (cnt * block_size > comm_size) {
     228                                retval = ELIMIT;
     229                                break;
     230                        }
     231                        retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va);
     232                        break;
     233                case BD_GET_BLOCK_SIZE:
     234                        ipc_answer_1(callid, EOK, block_size);
     235                        continue;
    218236                default:
    219237                        retval = EINVAL;
     
    224242}
    225243
    226 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
    227     void *buf)
    228 {
     244/** Read multiple blocks from the device. */
     245static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     246    void *buf) {
     247
    229248        int rc;
    230         size_t now;
    231 
    232         while (size > 0) {
    233                 now = size < block_size ? size : block_size;
    234 
    235                 if (method == BD_READ_BLOCK)
    236                         rc = gxe_bd_read_block(disk_id, offset, now, buf);
    237                 else
    238                         rc = gxe_bd_write_block(disk_id, offset, now, buf);
    239 
     249
     250        while (cnt > 0) {
     251                rc = gxe_bd_read_block(disk_id, ba, buf);
    240252                if (rc != EOK)
    241253                        return rc;
    242254
     255                ++ba;
     256                --cnt;
    243257                buf += block_size;
    244                 offset += block_size;
    245 
    246                 if (size > block_size)
    247                         size -= block_size;
    248                 else
    249                         size = 0;
    250         }
    251 
    252         return EOK;
    253 }
    254 
    255 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
    256     void *buf)
     258        }
     259
     260        return EOK;
     261}
     262
     263/** Write multiple blocks to the device. */
     264static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
     265    const void *buf) {
     266
     267        int rc;
     268
     269        while (cnt > 0) {
     270                rc = gxe_bd_write_block(disk_id, ba, buf);
     271                if (rc != EOK)
     272                        return rc;
     273
     274                ++ba;
     275                --cnt;
     276                buf += block_size;
     277        }
     278
     279        return EOK;
     280}
     281
     282/** Read a block from the device. */
     283static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf)
    257284{
    258285        uint32_t status;
     286        uint64_t byte_addr;
    259287        size_t i;
    260288        uint32_t w;
    261289
     290        byte_addr = ba * block_size;
     291
    262292        fibril_mutex_lock(&dev_lock[disk_id]);
    263         pio_write_32(&dev->offset_lo, (uint32_t) offset);
    264         pio_write_32(&dev->offset_hi, offset >> 32);
     293        pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
     294        pio_write_32(&dev->offset_hi, byte_addr >> 32);
    265295        pio_write_32(&dev->disk_id, disk_id);
    266296        pio_write_32(&dev->control, CTL_READ_START);
     
    272302        }
    273303
    274         for (i = 0; i < size; i++) {
     304        for (i = 0; i < block_size; i++) {
    275305                ((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]);
    276306        }
     
    280310}
    281311
    282 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
    283     const void *buf)
     312/** Write a block to the device. */
     313static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf)
    284314{
    285315        uint32_t status;
     316        uint64_t byte_addr;
    286317        size_t i;
    287318
    288         for (i = 0; i < size; i++) {
     319        byte_addr = ba * block_size;
     320
     321        fibril_mutex_lock(&dev_lock[disk_id]);
     322
     323        for (i = 0; i < block_size; i++) {
    289324                pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]);
    290325        }
    291326
    292         fibril_mutex_lock(&dev_lock[disk_id]);
    293         pio_write_32(&dev->offset_lo, (uint32_t) offset);
    294         pio_write_32(&dev->offset_hi, offset >> 32);
     327        pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
     328        pio_write_32(&dev->offset_hi, byte_addr >> 32);
    295329        pio_write_32(&dev->disk_id, disk_id);
    296330        pio_write_32(&dev->control, CTL_WRITE_START);
  • uspace/srv/bd/rd/rd.c

    rff62c6d r1ee00b7  
    5555#include <devmap.h>
    5656#include <ipc/bd.h>
     57#include <macros.h>
    5758
    5859#define NAME "rd"
    5960
    60 /** Pointer to the ramdisk's image. */
     61/** Pointer to the ramdisk's image */
    6162static void *rd_addr;
    62 /** Size of the ramdisk. */
     63/** Size of the ramdisk */
    6364static size_t rd_size;
     65
     66/** Block size */
     67static const size_t block_size = 512;
     68
     69static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
     70static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
    6471
    6572/**
     
    8289        int retval;
    8390        void *fs_va = NULL;
    84         off_t offset;
    85         size_t block_size;
    86         size_t maxblock_size;
     91        uint64_t ba;
     92        size_t cnt;
     93        size_t comm_size;
    8794
    8895        /*
     
    95102         */
    96103        int flags;
    97         if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
    98                 fs_va = as_get_mappable_page(maxblock_size);
     104        if (ipc_share_out_receive(&callid, &comm_size, &flags)) {
     105                fs_va = as_get_mappable_page(comm_size);
    99106                if (fs_va) {
    100107                        (void) ipc_share_out_finalize(callid, fs_va);
     
    123130                        ipc_answer_0(callid, EOK);
    124131                        return;
    125                 case BD_READ_BLOCK:
    126                         offset = IPC_GET_ARG1(call);
    127                         block_size = IPC_GET_ARG2(call);
    128                         if (block_size > maxblock_size) {
    129                                 /*
    130                                  * Maximum block size exceeded.
    131                                  */
     132                case BD_READ_BLOCKS:
     133                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     134                            IPC_GET_ARG2(call));
     135                        cnt = IPC_GET_ARG3(call);
     136                        if (cnt * block_size > comm_size) {
    132137                                retval = ELIMIT;
    133138                                break;
    134139                        }
    135                         if (offset * block_size > rd_size - block_size) {
    136                                 /*
    137                                  * Reading past the end of the device.
    138                                  */
     140                        retval = rd_read_blocks(ba, cnt, fs_va);
     141                        break;
     142                case BD_WRITE_BLOCKS:
     143                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     144                            IPC_GET_ARG2(call));
     145                        cnt = IPC_GET_ARG3(call);
     146                        if (cnt * block_size > comm_size) {
    139147                                retval = ELIMIT;
    140148                                break;
    141149                        }
    142                         fibril_rwlock_read_lock(&rd_lock);
    143                         memcpy(fs_va, rd_addr + offset * block_size, block_size);
    144                         fibril_rwlock_read_unlock(&rd_lock);
    145                         retval = EOK;
     150                        retval = rd_write_blocks(ba, cnt, fs_va);
    146151                        break;
    147                 case BD_WRITE_BLOCK:
    148                         offset = IPC_GET_ARG1(call);
    149                         block_size = IPC_GET_ARG2(call);
    150                         if (block_size > maxblock_size) {
    151                                 /*
    152                                  * Maximum block size exceeded.
    153                                  */
    154                                 retval = ELIMIT;
    155                                 break;
    156                         }
    157                         if (offset * block_size > rd_size - block_size) {
    158                                 /*
    159                                  * Writing past the end of the device.
    160                                  */
    161                                 retval = ELIMIT;
    162                                 break;
    163                         }
    164                         fibril_rwlock_write_lock(&rd_lock);
    165                         memcpy(rd_addr + offset * block_size, fs_va, block_size);
    166                         fibril_rwlock_write_unlock(&rd_lock);
    167                         retval = EOK;
    168                         break;
     152                case BD_GET_BLOCK_SIZE:
     153                        ipc_answer_1(callid, EOK, block_size);
     154                        continue;
    169155                default:
    170156                        /*
     
    181167}
    182168
     169/** Read blocks from the device. */
     170static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     171{
     172        if ((ba + cnt) * block_size > rd_size) {
     173                /* Reading past the end of the device. */
     174                return ELIMIT;
     175        }
     176
     177        fibril_rwlock_read_lock(&rd_lock);
     178        memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
     179        fibril_rwlock_read_unlock(&rd_lock);
     180
     181        return EOK;
     182}
     183
     184/** Write blocks to the device. */
     185static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     186{
     187        if ((ba + cnt) * block_size > rd_size) {
     188                /* Writing past the end of the device. */
     189                return ELIMIT;
     190        }
     191
     192        fibril_rwlock_write_lock(&rd_lock);
     193        memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
     194        fibril_rwlock_write_unlock(&rd_lock);
     195
     196        return EOK;
     197}
     198
    183199/** Prepare the ramdisk image for operation. */
    184200static bool rd_init(void)
  • uspace/srv/fs/fat/fat_ops.c

    rff62c6d r1ee00b7  
    818818
    819819        /* prepare the boot block */
    820         rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE);
     820        rc = block_bb_read(dev_handle, BS_BLOCK);
    821821        if (rc != EOK) {
    822822                block_fini(dev_handle);
  • uspace/srv/fs/tmpfs/tmpfs_dump.c

    rff62c6d r1ee00b7  
    4747#include <byteorder.h>
    4848
    49 #define TMPFS_BLOCK_SIZE        1024
     49#define TMPFS_COMM_SIZE         1024
    5050
    5151struct rdentry {
     
    6969               
    7070                if (block_seqread(dev, bufpos, buflen, pos, &entry,
    71                     sizeof(entry), TMPFS_BLOCK_SIZE) != EOK)
     71                    sizeof(entry)) != EOK)
    7272                        return false;
    7373               
     
    8989                       
    9090                        if (block_seqread(dev, bufpos, buflen, pos, fname,
    91                             entry.len, TMPFS_BLOCK_SIZE) != EOK) {
     91                            entry.len) != EOK) {
    9292                                ops->destroy(fn);
    9393                                free(fname);
     
    105105                       
    106106                        if (block_seqread(dev, bufpos, buflen, pos, &size,
    107                             sizeof(size), TMPFS_BLOCK_SIZE) != EOK)
     107                            sizeof(size)) != EOK)
    108108                                return false;
    109109                       
     
    117117                        nodep->size = size;
    118118                        if (block_seqread(dev, bufpos, buflen, pos, nodep->data,
    119                             size, TMPFS_BLOCK_SIZE) != EOK)
     119                            size) != EOK)
    120120                                return false;
    121121                       
     
    133133                       
    134134                        if (block_seqread(dev, bufpos, buflen, pos, fname,
    135                             entry.len, TMPFS_BLOCK_SIZE) != EOK) {
     135                            entry.len) != EOK) {
    136136                                ops->destroy(fn);
    137137                                free(fname);
     
    166166        int rc;
    167167
    168         rc = block_init(dev, TMPFS_BLOCK_SIZE);
     168        rc = block_init(dev, TMPFS_COMM_SIZE);
    169169        if (rc != EOK)
    170170                return false;
     
    175175       
    176176        char tag[6];
    177         if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5,
    178             TMPFS_BLOCK_SIZE) != EOK)
     177        if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5) != EOK)
    179178                goto error;
    180179       
Note: See TracChangeset for help on using the changeset viewer.