Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 9dec6d4 in mainline


Ignore:
Timestamp:
2012-08-14T19:27:42Z (9 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master
Children:
f7ea5400
Parents:
14c5005 (diff), 4802dd7 (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 mainline changes

Location:
uspace
Files:
4 added
16 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbmast/main.c

    r14c5005 r9dec6d4  
    3737#include <as.h>
    3838#include <async.h>
    39 #include <ipc/bd.h>
     39#include <bd_srv.h>
    4040#include <macros.h>
    4141#include <usb/dev/driver.h>
     
    8282    void *arg);
    8383
     84static int usbmast_bd_open(bd_srv_t *);
     85static int usbmast_bd_close(bd_srv_t *);
     86static int usbmast_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     87static int usbmast_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     88static int usbmast_bd_get_block_size(bd_srv_t *, size_t *);
     89static int usbmast_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     90
     91static bd_ops_t usbmast_bd_ops = {
     92        .open = usbmast_bd_open,
     93        .close = usbmast_bd_close,
     94        .read_blocks = usbmast_bd_read_blocks,
     95        .write_blocks = usbmast_bd_write_blocks,
     96        .get_block_size = usbmast_bd_get_block_size,
     97        .get_num_blocks = usbmast_bd_get_num_blocks
     98};
     99
     100static usbmast_fun_t *bd_srv_usbmast(bd_srv_t *bd)
     101{
     102        return (usbmast_fun_t *)bd->arg;
     103}
     104
    84105/** Callback when a device is removed from the system.
    85106 *
     
    219240        mfun->lun = lun;
    220241
     242        bd_srv_init(&mfun->bd);
     243        mfun->bd.ops = &usbmast_bd_ops;
     244        mfun->bd.arg = mfun;
     245
    221246        /* Set up a connection handler. */
    222247        fun->conn_handler = usbmast_bd_connection;
     
    284309{
    285310        usbmast_fun_t *mfun;
    286         void *comm_buf = NULL;
    287         size_t comm_size;
    288         ipc_callid_t callid;
    289         ipc_call_t call;
    290         unsigned int flags;
    291         sysarg_t method;
    292         uint64_t ba;
    293         size_t cnt;
    294         int retval;
    295 
    296         async_answer_0(iid, EOK);
    297 
    298         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    299                 async_answer_0(callid, EHANGUP);
    300                 return;
    301         }
    302        
    303         (void) async_share_out_finalize(callid, &comm_buf);
    304         if (comm_buf == AS_MAP_FAILED) {
    305                 async_answer_0(callid, EHANGUP);
    306                 return;
    307         }
    308        
     311
    309312        mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
    310 
    311         while (true) {
    312                 callid = async_get_call(&call);
    313                 method = IPC_GET_IMETHOD(call);
    314 
    315                 if (!method) {
    316                         /* The other side hung up. */
    317                         async_answer_0(callid, EOK);
    318                         return;
    319                 }
    320 
    321                 switch (method) {
    322                 case BD_GET_BLOCK_SIZE:
    323                         async_answer_1(callid, EOK, mfun->block_size);
    324                         break;
    325                 case BD_GET_NUM_BLOCKS:
    326                         async_answer_2(callid, EOK, LOWER32(mfun->nblocks),
    327                             UPPER32(mfun->nblocks));
    328                         break;
    329                 case BD_READ_BLOCKS:
    330                         ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    331                         cnt = IPC_GET_ARG3(call);
    332                         retval = usbmast_read(mfun, ba, cnt, comm_buf);
    333                         async_answer_0(callid, retval);
    334                         break;
    335                 case BD_WRITE_BLOCKS:
    336                         ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    337                         cnt = IPC_GET_ARG3(call);
    338                         retval = usbmast_write(mfun, ba, cnt, comm_buf);
    339                         async_answer_0(callid, retval);
    340                         break;
    341                 default:
    342                         async_answer_0(callid, EINVAL);
    343                 }
    344         }
    345 }
     313        bd_conn(iid, icall, &mfun->bd);
     314}
     315
     316/** Open device. */
     317static int usbmast_bd_open(bd_srv_t *bd)
     318{
     319        return EOK;
     320}
     321
     322/** Close device. */
     323static int usbmast_bd_close(bd_srv_t *bd)
     324{
     325        return EOK;
     326}
     327
     328/** Read blocks from the device. */
     329static int usbmast_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf,
     330    size_t size)
     331{
     332        usbmast_fun_t *mfun = bd_srv_usbmast(bd);
     333
     334        if (size < cnt * mfun->block_size)
     335                return EINVAL;
     336
     337        return usbmast_read(mfun, ba, cnt, buf);
     338}
     339
     340/** Write blocks to the device. */
     341static int usbmast_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
     342    const void *buf, size_t size)
     343{
     344        usbmast_fun_t *mfun = bd_srv_usbmast(bd);
     345
     346        if (size < cnt * mfun->block_size)
     347                return EINVAL;
     348
     349        return usbmast_write(mfun, ba, cnt, buf);
     350}
     351
     352/** Get device block size. */
     353static int usbmast_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     354{
     355        usbmast_fun_t *mfun = bd_srv_usbmast(bd);
     356        *rsize = mfun->block_size;
     357        return EOK;
     358}
     359
     360/** Get number of blocks on device. */
     361static int usbmast_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     362{
     363        usbmast_fun_t *mfun = bd_srv_usbmast(bd);
     364        *rnb = mfun->nblocks;
     365        return EOK;
     366}
     367
    346368
    347369/** USB mass storage driver ops. */
  • uspace/drv/bus/usb/usbmast/usbmast.h

    r14c5005 r9dec6d4  
    3737#define USBMAST_H_
    3838
     39#include <bd_srv.h>
    3940#include <sys/types.h>
    4041#include <usb/usb.h>
     
    6869        /** Block size in bytes */
    6970        size_t block_size;
     71        /** Block device server structure */
     72        bd_srv_t bd;
    7073} usbmast_fun_t;
    7174
  • uspace/lib/block/libblock.c

    r14c5005 r9dec6d4  
    4040#include "../../srv/vfs/vfs.h"
    4141#include <ipc/loc.h>
    42 #include <ipc/bd.h>
    4342#include <ipc/services.h>
    4443#include <errno.h>
     
    4746#include <as.h>
    4847#include <assert.h>
     48#include <bd.h>
    4949#include <fibril_synch.h>
    5050#include <adt/list.h>
     
    8080        service_id_t service_id;
    8181        async_sess_t *sess;
    82         fibril_mutex_t comm_area_lock;
    83         void *comm_area;
    84         size_t comm_size;
     82        bd_t *bd;
    8583        void *bb_buf;
    8684        aoff64_t bb_addr;
     
    8987} devcon_t;
    9088
    91 static int read_blocks(devcon_t *, aoff64_t, size_t);
    92 static int write_blocks(devcon_t *, aoff64_t, size_t);
    93 static int get_block_size(async_sess_t *, size_t *);
    94 static int get_num_blocks(async_sess_t *, aoff64_t *);
     89static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
     90static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t);
    9591static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9692
     
    112108
    113109static int devcon_add(service_id_t service_id, async_sess_t *sess,
    114     size_t bsize, void *comm_area, size_t comm_size)
     110    size_t bsize, bd_t *bd)
    115111{
    116112        devcon_t *devcon;
    117        
    118         if (comm_size < bsize)
    119                 return EINVAL;
    120113       
    121114        devcon = malloc(sizeof(devcon_t));
     
    126119        devcon->service_id = service_id;
    127120        devcon->sess = sess;
    128         fibril_mutex_initialize(&devcon->comm_area_lock);
    129         devcon->comm_area = comm_area;
    130         devcon->comm_size = comm_size;
     121        devcon->bd = bd;
    131122        devcon->bb_buf = NULL;
    132123        devcon->bb_addr = 0;
     
    158149    size_t comm_size)
    159150{
    160         void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
    161             MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    162         if (!comm_area)
    163                 return ENOMEM;
    164        
     151        bd_t *bd;
     152
    165153        async_sess_t *sess = loc_service_connect(mgmt, service_id,
    166154            IPC_FLAG_BLOCKING);
    167155        if (!sess) {
    168                 munmap(comm_area, comm_size);
    169156                return ENOENT;
    170157        }
    171158       
    172         async_exch_t *exch = async_exchange_begin(sess);
    173         int rc = async_share_out_start(exch, comm_area,
    174             AS_AREA_READ | AS_AREA_WRITE);
    175         async_exchange_end(exch);
    176        
     159        int rc = bd_open(sess, &bd);
    177160        if (rc != EOK) {
    178                 munmap(comm_area, comm_size);
    179161                async_hangup(sess);
    180162                return rc;
     
    182164       
    183165        size_t bsize;
    184         rc = get_block_size(sess, &bsize);
    185        
     166        rc = bd_get_block_size(bd, &bsize);
    186167        if (rc != EOK) {
    187                 munmap(comm_area, comm_size);
     168                bd_close(bd);
    188169                async_hangup(sess);
    189170                return rc;
    190171        }
    191172       
    192         rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
     173        rc = devcon_add(service_id, sess, bsize, bd);
    193174        if (rc != EOK) {
    194                 munmap(comm_area, comm_size);
     175                bd_close(bd);
    195176                async_hangup(sess);
    196177                return rc;
     
    213194                free(devcon->bb_buf);
    214195       
    215         munmap(devcon->comm_area, devcon->comm_size);
     196        bd_close(devcon->bd);
    216197        async_hangup(devcon->sess);
    217198       
     
    233214                return ENOMEM;
    234215
    235         fibril_mutex_lock(&devcon->comm_area_lock);
    236         rc = read_blocks(devcon, 0, 1);
     216        rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size);
    237217        if (rc != EOK) {
    238                 fibril_mutex_unlock(&devcon->comm_area_lock);
    239218                free(bb_buf);
    240219                return rc;
    241220        }
    242         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    243         fibril_mutex_unlock(&devcon->comm_area_lock);
    244221
    245222        devcon->bb_buf = bb_buf;
     
    338315                list_remove(&b->free_link);
    339316                if (b->dirty) {
    340                         memcpy(devcon->comm_area, b->data, b->size);
    341                         rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
     317                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster,
     318                            b->data, b->size);
    342319                        if (rc != EOK)
    343320                                return rc;
     
    481458                                list_append(&b->free_link, &cache->free_list);
    482459                                fibril_mutex_unlock(&cache->lock);
    483                                 fibril_mutex_lock(&devcon->comm_area_lock);
    484                                 memcpy(devcon->comm_area, b->data, b->size);
    485460                                rc = write_blocks(devcon, b->pba,
    486                                     cache->blocks_cluster);
    487                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     461                                    cache->blocks_cluster, b->data, b->size);
    488462                                if (rc != EOK) {
    489463                                        /*
     
    555529                         * the new contents from the device.
    556530                         */
    557                         fibril_mutex_lock(&devcon->comm_area_lock);
    558                         rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    559                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    560                         fibril_mutex_unlock(&devcon->comm_area_lock);
     531                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster,
     532                            b->data, cache->lblock_size);
    561533                        if (rc != EOK)
    562534                                b->toxic = true;
     
    616588        if (block->dirty && (block->refcnt == 1) &&
    617589            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    618                 fibril_mutex_lock(&devcon->comm_area_lock);
    619                 memcpy(devcon->comm_area, block->data, block->size);
    620                 rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    621                 fibril_mutex_unlock(&devcon->comm_area_lock);
     590                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
     591                    block->data, block->size);
    622592                block->dirty = false;
    623593        }
     
    688658 *
    689659 * @param service_id    Service ID of the block device.
     660 * @param buf           Buffer for holding one block
    690661 * @param bufpos        Pointer to the first unread valid offset within the
    691662 *                      communication buffer.
     
    699670 * @return              EOK on success or a negative return code on failure.
    700671 */
    701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
    702     aoff64_t *pos, void *dst, size_t size)
     672int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,
     673    size_t *buflen, aoff64_t *pos, void *dst, size_t size)
    703674{
    704675        size_t offset = 0;
     
    711682        block_size = devcon->pblock_size;
    712683       
    713         fibril_mutex_lock(&devcon->comm_area_lock);
    714684        while (left > 0) {
    715685                size_t rd;
     
    725695                         * destination buffer.
    726696                         */
    727                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     697                        memcpy(dst + offset, buf + *bufpos, rd);
    728698                        offset += rd;
    729699                        *bufpos += rd;
     
    736706                        int rc;
    737707
    738                         rc = read_blocks(devcon, *pos / block_size, 1);
     708                        rc = read_blocks(devcon, *pos / block_size, 1, buf,
     709                            devcon->pblock_size);
    739710                        if (rc != EOK) {
    740                                 fibril_mutex_unlock(&devcon->comm_area_lock);
    741711                                return rc;
    742712                        }
     
    746716                }
    747717        }
    748         fibril_mutex_unlock(&devcon->comm_area_lock);
    749718       
    750719        return EOK;
     
    763732{
    764733        devcon_t *devcon;
    765         int rc;
    766734
    767735        devcon = devcon_search(service_id);
    768736        assert(devcon);
    769        
    770         fibril_mutex_lock(&devcon->comm_area_lock);
    771 
    772         rc = read_blocks(devcon, ba, cnt);
    773         if (rc == EOK)
    774                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    775 
    776         fibril_mutex_unlock(&devcon->comm_area_lock);
    777 
    778         return rc;
     737
     738        return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt);
    779739}
    780740
     
    792752{
    793753        devcon_t *devcon;
    794         int rc;
    795754
    796755        devcon = devcon_search(service_id);
    797756        assert(devcon);
    798        
    799         fibril_mutex_lock(&devcon->comm_area_lock);
    800 
    801         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    802         rc = write_blocks(devcon, ba, cnt);
    803 
    804         fibril_mutex_unlock(&devcon->comm_area_lock);
    805 
    806         return rc;
     757
     758        return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt);
    807759}
    808760
     
    820772        devcon = devcon_search(service_id);
    821773        assert(devcon);
    822        
    823         return get_block_size(devcon->sess, bsize);
     774
     775        return bd_get_block_size(devcon->bd, bsize);
    824776}
    825777
     
    836788        assert(devcon);
    837789       
    838         return get_num_blocks(devcon->sess, nblocks);
     790        return bd_get_num_blocks(devcon->bd, nblocks);
    839791}
    840792
     
    887839        memcpy(data, buffer + offset, bytes);
    888840        free(buffer);
    889        
     841
    890842        return EOK;
    891843}
     
    903855{
    904856        devcon_t *devcon = devcon_search(service_id);
    905         assert(devcon);
    906        
    907857        toc_block_t *toc = NULL;
    908        
    909         fibril_mutex_lock(&devcon->comm_area_lock);
    910        
    911         async_exch_t *exch = async_exchange_begin(devcon->sess);
    912         int rc = async_req_1_0(exch, BD_READ_TOC, session);
    913         async_exchange_end(exch);
    914        
    915         if (rc == EOK) {
    916                 toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    917                 if (toc != NULL) {
    918                         memset(toc, 0, sizeof(toc_block_t));
    919                         memcpy(toc, devcon->comm_area,
    920                             min(devcon->pblock_size, sizeof(toc_block_t)));
    921                 }
    922         }
    923        
    924        
    925         fibril_mutex_unlock(&devcon->comm_area_lock);
     858        int rc;
     859       
     860        assert(devcon);
     861       
     862        toc = (toc_block_t *) malloc(sizeof(toc_block_t));
     863        if (toc == NULL)
     864                return NULL;
     865       
     866        rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
     867        if (rc != EOK) {
     868                free(toc);
     869                return NULL;
     870        }
    926871       
    927872        return toc;
     
    937882 * @return              EOK on success or negative error code on failure.
    938883 */
    939 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    940 {
    941         assert(devcon);
    942        
    943         async_exch_t *exch = async_exchange_begin(devcon->sess);
    944         int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
    945             UPPER32(ba), cnt);
    946         async_exchange_end(exch);
    947        
     884static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf,
     885    size_t size)
     886{
     887        assert(devcon);
     888       
     889        int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size);
    948890        if (rc != EOK) {
    949891                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     
    967909 * @return              EOK on success or negative error code on failure.
    968910 */
    969 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    970 {
    971         assert(devcon);
    972        
    973         async_exch_t *exch = async_exchange_begin(devcon->sess);
    974         int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
    975             UPPER32(ba), cnt);
    976         async_exchange_end(exch);
    977        
     911static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data,
     912    size_t size)
     913{
     914        assert(devcon);
     915       
     916        int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size);
    978917        if (rc != EOK) {
    979918                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     
    987926}
    988927
    989 /** Get block size used by the device. */
    990 static int get_block_size(async_sess_t *sess, size_t *bsize)
    991 {
    992         sysarg_t bs;
    993        
    994         async_exch_t *exch = async_exchange_begin(sess);
    995         int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
    996         async_exchange_end(exch);
    997        
    998         if (rc == EOK)
    999                 *bsize = (size_t) bs;
    1000        
    1001         return rc;
    1002 }
    1003 
    1004 /** Get total number of blocks on block device. */
    1005 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
    1006 {
    1007         sysarg_t nb_l;
    1008         sysarg_t nb_h;
    1009        
    1010         async_exch_t *exch = async_exchange_begin(sess);
    1011         int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
    1012         async_exchange_end(exch);
    1013        
    1014         if (rc == EOK)
    1015                 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
    1016        
    1017         return rc;
    1018 }
    1019 
    1020928/** Convert logical block address to physical block address. */
    1021929static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
  • uspace/lib/block/libblock.h

    r14c5005 r9dec6d4  
    122122extern int block_put(block_t *);
    123123
    124 extern int block_seqread(service_id_t, size_t *, size_t *, aoff64_t *, void *,
    125     size_t);
     124extern int block_seqread(service_id_t, void *, size_t *, size_t *, aoff64_t *,
     125    void *, size_t);
    126126
    127127extern int block_get_bsize(service_id_t, size_t *);
  • uspace/lib/c/Makefile

    r14c5005 r9dec6d4  
    6262        generic/ddi.c \
    6363        generic/as.c \
     64        generic/bd.c \
     65        generic/bd_srv.c \
    6466        generic/cap.c \
    6567        generic/cfg.c \
  • uspace/lib/c/generic/iplink_srv.c

    r14c5005 r9dec6d4  
    139139                if (!method) {
    140140                        /* The other side has hung up */
     141                        fibril_mutex_lock(&srv->lock);
     142                        srv->connected = false;
     143                        fibril_mutex_unlock(&srv->lock);
    141144                        async_answer_0(callid, EOK);
    142145                        break;
  • uspace/srv/bd/ata_bd/ata_bd.c

    r14c5005 r9dec6d4  
    5151#include <libarch/ddi.h>
    5252#include <ddi.h>
    53 #include <ipc/bd.h>
    5453#include <async.h>
    5554#include <as.h>
     55#include <bd_srv.h>
    5656#include <fibril_synch.h>
    5757#include <stdint.h>
     
    9898
    9999/** Per-disk state. */
    100 static disk_t disk[MAX_DISKS];
     100static disk_t ata_disk[MAX_DISKS];
    101101
    102102static void print_syntax(void);
    103103static int ata_bd_init(void);
    104104static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
    105 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
    106     void *buf);
    107 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
    108     const void *buf);
     105
     106static int ata_bd_open(bd_srv_t *);
     107static int ata_bd_close(bd_srv_t *);
     108static int ata_bd_read_blocks(bd_srv_t *, uint64_t ba, size_t cnt, void *buf,
     109    size_t);
     110static int ata_bd_read_toc(bd_srv_t *, uint8_t session, void *buf, size_t);
     111static int ata_bd_write_blocks(bd_srv_t *, uint64_t ba, size_t cnt,
     112    const void *buf, size_t);
     113static int ata_bd_get_block_size(bd_srv_t *, size_t *);
     114static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     115
    109116static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
    110117    void *buf);
     
    127134    unsigned timeout);
    128135
     136static bd_ops_t ata_bd_ops = {
     137        .open = ata_bd_open,
     138        .close = ata_bd_close,
     139        .read_blocks = ata_bd_read_blocks,
     140        .read_toc = ata_bd_read_toc,
     141        .write_blocks = ata_bd_write_blocks,
     142        .get_block_size = ata_bd_get_block_size,
     143        .get_num_blocks = ata_bd_get_num_blocks
     144};
     145
     146static disk_t *bd_srv_disk(bd_srv_t *bd)
     147{
     148        return (disk_t *)bd->arg;
     149}
     150
    129151int main(int argc, char **argv)
    130152{
     
    161183                fflush(stdout);
    162184
    163                 rc = disk_init(&disk[i], i);
     185                rc = disk_init(&ata_disk[i], i);
    164186
    165187                if (rc == EOK) {
    166                         disk_print_summary(&disk[i]);
     188                        disk_print_summary(&ata_disk[i]);
    167189                } else {
    168190                        printf("Not found.\n");
     
    174196        for (i = 0; i < MAX_DISKS; i++) {
    175197                /* Skip unattached drives. */
    176                 if (disk[i].present == false)
     198                if (ata_disk[i].present == false)
    177199                        continue;
    178200               
    179201                snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
    180                 rc = loc_service_register(name, &disk[i].service_id);
     202                rc = loc_service_register(name, &ata_disk[i].service_id);
    181203                if (rc != EOK) {
    182204                        printf(NAME ": Unable to register device %s.\n", name);
     
    217239                case am_chs:
    218240                        printf("CHS %u cylinders, %u heads, %u sectors",
    219                             disk->geom.cylinders, disk->geom.heads,
    220                             disk->geom.sectors);
     241                            d->geom.cylinders, d->geom.heads,
     242                            d->geom.sectors);
    221243                        break;
    222244                case am_lba28:
     
    273295static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    274296{
    275         void *fs_va = NULL;
    276         ipc_callid_t callid;
    277         ipc_call_t call;
    278         sysarg_t method;
    279297        service_id_t dsid;
    280         size_t comm_size;       /**< Size of the communication area. */
    281         unsigned int flags;
    282         int retval;
    283         uint64_t ba;
    284         size_t cnt;
    285298        int disk_id, i;
    286299
     
    291304        disk_id = -1;
    292305        for (i = 0; i < MAX_DISKS; i++)
    293                 if (disk[i].service_id == dsid)
     306                if (ata_disk[i].service_id == dsid)
    294307                        disk_id = i;
    295308
    296         if (disk_id < 0 || disk[disk_id].present == false) {
     309        if (disk_id < 0 || ata_disk[disk_id].present == false) {
    297310                async_answer_0(iid, EINVAL);
    298311                return;
    299312        }
    300313
    301         /* Answer the IPC_M_CONNECT_ME_TO call. */
    302         async_answer_0(iid, EOK);
    303 
    304         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    305                 async_answer_0(callid, EHANGUP);
    306                 return;
    307         }
    308 
    309         (void) async_share_out_finalize(callid, &fs_va);
    310         if (fs_va == AS_MAP_FAILED) {
    311                 async_answer_0(callid, EHANGUP);
    312                 return;
    313         }
    314 
    315         while (true) {
    316                 callid = async_get_call(&call);
    317                 method = IPC_GET_IMETHOD(call);
    318                
    319                 if (!method) {
    320                         /* The other side has hung up. */
    321                         async_answer_0(callid, EOK);
    322                         return;
    323                 }
    324                
    325                 switch (method) {
    326                 case BD_READ_BLOCKS:
    327                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    328                             IPC_GET_ARG2(call));
    329                         cnt = IPC_GET_ARG3(call);
    330                         if (cnt * disk[disk_id].block_size > comm_size) {
    331                                 retval = ELIMIT;
    332                                 break;
    333                         }
    334                         retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va);
    335                         break;
    336                 case BD_WRITE_BLOCKS:
    337                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    338                             IPC_GET_ARG2(call));
    339                         cnt = IPC_GET_ARG3(call);
    340                         if (cnt * disk[disk_id].block_size > comm_size) {
    341                                 retval = ELIMIT;
    342                                 break;
    343                         }
    344                         retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va);
    345                         break;
    346                 case BD_GET_BLOCK_SIZE:
    347                         async_answer_1(callid, EOK, disk[disk_id].block_size);
    348                         continue;
    349                 case BD_GET_NUM_BLOCKS:
    350                         async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
    351                             UPPER32(disk[disk_id].blocks));
    352                         continue;
    353                 case BD_READ_TOC:
    354                         cnt = IPC_GET_ARG1(call);
    355                         if (disk[disk_id].dev_type == ata_pkt_dev)
    356                                 retval = ata_pcmd_read_toc(disk_id, cnt, fs_va,
    357                                     disk[disk_id].block_size);
    358                         else
    359                                 retval = EINVAL;
    360                         break;
    361                 default:
    362                         retval = EINVAL;
    363                         break;
    364                 }
    365                 async_answer_0(callid, retval);
    366         }
     314        bd_conn(iid, icall, &ata_disk[disk_id].bd);
    367315}
    368316
     
    384332        unsigned i;
    385333
     334        d->disk_id = disk_id;
    386335        d->present = false;
    387336        fibril_mutex_initialize(&d->lock);
     337
     338        bd_srv_init(&d->bd);
     339        d->bd.ops = &ata_bd_ops;
     340        d->bd.arg = d;
    388341
    389342        /* Try identify command. */
     
    514467}
    515468
     469static int ata_bd_open(bd_srv_t *bd)
     470{
     471        return EOK;
     472}
     473
     474static int ata_bd_close(bd_srv_t *bd)
     475{
     476        return EOK;
     477}
     478
    516479/** Read multiple blocks from the device. */
    517 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
    518     void *buf) {
    519 
     480static int ata_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
     481    void *buf, size_t size)
     482{
     483        disk_t *disk = bd_srv_disk(bd);
    520484        int rc;
    521485
     486        if (size < cnt * disk->block_size)
     487                return EINVAL;
     488
    522489        while (cnt > 0) {
    523                 if (disk[disk_id].dev_type == ata_reg_dev)
    524                         rc = ata_rcmd_read(disk_id, ba, 1, buf);
     490                if (disk->dev_type == ata_reg_dev)
     491                        rc = ata_rcmd_read(disk->disk_id, ba, 1, buf);
    525492                else
    526                         rc = ata_pcmd_read_12(disk_id, ba, 1, buf,
    527                             disk[disk_id].block_size);
     493                        rc = ata_pcmd_read_12(disk->disk_id, ba, 1, buf,
     494                            disk->block_size);
    528495
    529496                if (rc != EOK)
     
    532499                ++ba;
    533500                --cnt;
    534                 buf += disk[disk_id].block_size;
    535         }
    536 
    537         return EOK;
     501                buf += disk->block_size;
     502        }
     503
     504        return EOK;
     505}
     506
     507/** Read TOC from device. */
     508static int ata_bd_read_toc(bd_srv_t *bd, uint8_t session, void *buf, size_t size)
     509{
     510        disk_t *disk = bd_srv_disk(bd);
     511
     512        return ata_pcmd_read_toc(disk->disk_id, session, buf, size);
    538513}
    539514
    540515/** Write multiple blocks to the device. */
    541 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
    542     const void *buf) {
    543 
     516static int ata_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
     517    const void *buf, size_t size)
     518{
     519        disk_t *disk = bd_srv_disk(bd);
    544520        int rc;
    545521
    546         if (disk[disk_id].dev_type != ata_reg_dev)
     522        if (disk->dev_type != ata_reg_dev)
    547523                return ENOTSUP;
    548524
     525        if (size < cnt * disk->block_size)
     526                return EINVAL;
     527
    549528        while (cnt > 0) {
    550                 rc = ata_rcmd_write(disk_id, ba, 1, buf);
     529                rc = ata_rcmd_write(disk->disk_id, ba, 1, buf);
    551530                if (rc != EOK)
    552531                        return rc;
     
    554533                ++ba;
    555534                --cnt;
    556                 buf += disk[disk_id].block_size;
    557         }
    558 
     535                buf += disk->block_size;
     536        }
     537
     538        return EOK;
     539}
     540
     541/** Get device block size. */
     542static int ata_bd_get_block_size(bd_srv_t *bd, size_t *rbsize)
     543{
     544        disk_t *disk = bd_srv_disk(bd);
     545
     546        *rbsize = disk->block_size;
     547        return EOK;
     548}
     549
     550/** Get device number of blocks. */
     551static int ata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     552{
     553        disk_t *disk = bd_srv_disk(bd);
     554
     555        *rnb = disk->blocks;
    559556        return EOK;
    560557}
     
    685682        uint16_t val;
    686683
    687         d = &disk[dev_idx];
     684        d = &ata_disk[dev_idx];
    688685        fibril_mutex_lock(&d->lock);
    689686
     
    874871        block_coord_t bc;
    875872
    876         d = &disk[disk_id];
     873        d = &ata_disk[disk_id];
    877874       
    878875        /* Silence warning. */
     
    919916                /* Read data from the device buffer. */
    920917
    921                 for (i = 0; i < disk[disk_id].block_size / 2; i++) {
     918                for (i = 0; i < ata_disk[disk_id].block_size / 2; i++) {
    922919                        data = pio_read_16(&cmd->data_port);
    923920                        ((uint16_t *) buf)[i] = data;
     
    950947        block_coord_t bc;
    951948
    952         d = &disk[disk_id];
     949        d = &ata_disk[disk_id];
    953950       
    954951        /* Silence warning. */
     
    995992                /* Write data to the device buffer. */
    996993
    997                 for (i = 0; i < disk[disk_id].block_size / 2; i++) {
     994                for (i = 0; i < d->block_size / 2; i++) {
    998995                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    999996                }
  • uspace/srv/bd/ata_bd/ata_bd.h

    r14c5005 r9dec6d4  
    3636#define __ATA_BD_H__
    3737
     38#include <bd_srv.h>
    3839#include <sys/types.h>
    3940#include <fibril_synch.h>
     
    117118        fibril_mutex_t lock;
    118119        service_id_t service_id;
     120        int disk_id;
     121        bd_srv_t bd;
    119122} disk_t;
    120123
  • uspace/srv/bd/file_bd/file_bd.c

    r14c5005 r9dec6d4  
    4141#include <stdio.h>
    4242#include <unistd.h>
    43 #include <ipc/bd.h>
    4443#include <async.h>
    4544#include <as.h>
     45#include <bd_srv.h>
    4646#include <fibril_synch.h>
    4747#include <loc.h>
     
    6262
    6363static service_id_t service_id;
     64static bd_srv_t bd_srv;
    6465static fibril_mutex_t dev_lock;
    6566
     
    6768static int file_bd_init(const char *fname);
    6869static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
    69 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf);
    70 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
     70
     71static int file_bd_open(bd_srv_t *);
     72static int file_bd_close(bd_srv_t *);
     73static int file_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     74static int file_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     75static int file_bd_get_block_size(bd_srv_t *, size_t *);
     76static int file_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     77
     78static bd_ops_t file_bd_ops = {
     79        .open = file_bd_open,
     80        .close = file_bd_close,
     81        .read_blocks = file_bd_read_blocks,
     82        .write_blocks = file_bd_write_blocks,
     83        .get_block_size = file_bd_get_block_size,
     84        .get_num_blocks = file_bd_get_num_blocks
     85};
    7186
    7287int main(int argc, char **argv)
     
    139154static int file_bd_init(const char *fname)
    140155{
     156        bd_srv_init(&bd_srv);
     157        bd_srv.ops = &file_bd_ops;
     158       
    141159        async_set_client_connection(file_bd_connection);
    142160        int rc = loc_server_register(NAME);
     
    170188static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    171189{
    172         void *fs_va = NULL;
    173         ipc_callid_t callid;
    174         ipc_call_t call;
    175         sysarg_t method;
    176         size_t comm_size;
    177         unsigned int flags;
    178         int retval;
    179         uint64_t ba;
    180         size_t cnt;
    181 
    182         /* Answer the IPC_M_CONNECT_ME_TO call. */
    183         async_answer_0(iid, EOK);
    184 
    185         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    186                 async_answer_0(callid, EHANGUP);
    187                 return;
    188         }
    189 
    190         (void) async_share_out_finalize(callid, &fs_va);
    191         if (fs_va == AS_MAP_FAILED) {
    192                 async_answer_0(callid, EHANGUP);
    193                 return;
    194         }
    195 
    196         while (true) {
    197                 callid = async_get_call(&call);
    198                 method = IPC_GET_IMETHOD(call);
    199                
    200                 if (!method) {
    201                         /* The other side has hung up. */
    202                         async_answer_0(callid, EOK);
    203                         return;
    204                 }
    205                
    206                 switch (method) {
    207                 case BD_READ_BLOCKS:
    208                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    209                             IPC_GET_ARG2(call));
    210                         cnt = IPC_GET_ARG3(call);
    211                         if (cnt * block_size > comm_size) {
    212                                 retval = ELIMIT;
    213                                 break;
    214                         }
    215                         retval = file_bd_read_blocks(ba, cnt, fs_va);
    216                         break;
    217                 case BD_WRITE_BLOCKS:
    218                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    219                             IPC_GET_ARG2(call));
    220                         cnt = IPC_GET_ARG3(call);
    221                         if (cnt * block_size > comm_size) {
    222                                 retval = ELIMIT;
    223                                 break;
    224                         }
    225                         retval = file_bd_write_blocks(ba, cnt, fs_va);
    226                         break;
    227                 case BD_GET_BLOCK_SIZE:
    228                         async_answer_1(callid, EOK, block_size);
    229                         continue;
    230                 case BD_GET_NUM_BLOCKS:
    231                         async_answer_2(callid, EOK, LOWER32(num_blocks),
    232                             UPPER32(num_blocks));
    233                         continue;
    234                 default:
    235                         retval = EINVAL;
    236                         break;
    237                 }
    238                 async_answer_0(callid, retval);
    239         }
     190        bd_conn(iid, icall, &bd_srv);
     191}
     192
     193/** Open device. */
     194static int file_bd_open(bd_srv_t *bd)
     195{
     196        return EOK;
     197}
     198
     199/** Close device. */
     200static int file_bd_close(bd_srv_t *bd)
     201{
     202        return EOK;
    240203}
    241204
    242205/** Read blocks from the device. */
    243 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     206static int file_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf,
     207    size_t size)
    244208{
    245209        size_t n_rd;
    246210        int rc;
     211
     212        if (size < cnt * block_size)
     213                return EINVAL;
    247214
    248215        /* Check whether access is within device address bounds. */
     
    279246
    280247/** Write blocks to the device. */
    281 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     248static int file_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
     249    const void *buf, size_t size)
    282250{
    283251        size_t n_wr;
    284252        int rc;
     253
     254        if (size < cnt * block_size)
     255                return EINVAL;
    285256
    286257        /* Check whether access is within device address bounds. */
     
    318289}
    319290
     291/** Get device block size. */
     292static int file_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     293{
     294        *rsize = block_size;
     295        return EOK;
     296}
     297
     298/** Get number of blocks on device. */
     299static int file_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     300{
     301        *rnb = num_blocks;
     302        return EOK;
     303}
     304
    320305/**
    321306 * @}
  • uspace/srv/bd/gxe_bd/gxe_bd.c

    r14c5005 r9dec6d4  
    3939#include <libarch/ddi.h>
    4040#include <ddi.h>
    41 #include <ipc/bd.h>
    4241#include <async.h>
    4342#include <as.h>
     43#include <bd_srv.h>
    4444#include <fibril_synch.h>
    4545#include <loc.h>
     
    6565};
    6666
     67/** GXE disk hardware registers */
    6768typedef struct {
    6869        uint32_t offset_lo;
     
    8384
    8485        uint8_t buffer[512];
     86} gxe_bd_hw_t;
     87
     88/** GXE block device soft state */
     89typedef struct {
     90        /** Block device server structure */
     91        bd_srv_t bd;
     92        int disk_id;
    8593} gxe_bd_t;
    8694
    87 
    8895static const size_t block_size = 512;
    89 static size_t comm_size;
    9096
    9197static uintptr_t dev_physical = 0x13000000;
    92 static gxe_bd_t *dev;
     98static gxe_bd_hw_t *dev;
    9399
    94100static service_id_t service_id[MAX_DISKS];
    95101
    96102static fibril_mutex_t dev_lock[MAX_DISKS];
     103
     104static gxe_bd_t gxe_bd[MAX_DISKS];
    97105
    98106static int gxe_bd_init(void);
    99107static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
    100 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
    101     void *buf);
    102 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
    103     const void *buf);
    104108static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf);
    105109static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf);
     110
     111static int gxe_bd_open(bd_srv_t *);
     112static int gxe_bd_close(bd_srv_t *);
     113static int gxe_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     114static int gxe_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     115static int gxe_bd_get_block_size(bd_srv_t *, size_t *);
     116static int gxe_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     117
     118static bd_ops_t gxe_bd_ops = {
     119        .open = gxe_bd_open,
     120        .close = gxe_bd_close,
     121        .read_blocks = gxe_bd_read_blocks,
     122        .write_blocks = gxe_bd_write_blocks,
     123        .get_block_size = gxe_bd_get_block_size,
     124        .get_num_blocks = gxe_bd_get_num_blocks
     125};
     126
     127static gxe_bd_t *bd_srv_gxe(bd_srv_t *bd)
     128{
     129        return (gxe_bd_t *)bd->arg;
     130}
    106131
    107132int main(int argc, char **argv)
     
    130155       
    131156        void *vaddr;
    132         rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_t), &vaddr);
     157        rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_hw_t), &vaddr);
    133158        if (rc != EOK) {
    134159                printf("%s: Could not initialize device I/O space.\n", NAME);
     
    140165        for (unsigned int i = 0; i < MAX_DISKS; i++) {
    141166                char name[16];
     167               
     168                bd_srv_init(&gxe_bd[i].bd);
     169                gxe_bd[i].bd.ops = &gxe_bd_ops;
     170                gxe_bd[i].bd.arg = (void *)&gxe_bd[i];
    142171               
    143172                snprintf(name, 16, "%s/disk%u", NAMESPACE, i);
     
    157186static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    158187{
    159         void *fs_va = NULL;
    160         ipc_callid_t callid;
    161         ipc_call_t call;
    162         sysarg_t method;
    163188        service_id_t dsid;
    164         unsigned int flags;
    165         int retval;
    166         uint64_t ba;
    167         unsigned cnt;
    168189        int disk_id, i;
    169190
     
    182203        }
    183204
    184         /* Answer the IPC_M_CONNECT_ME_TO call. */
    185         async_answer_0(iid, EOK);
    186 
    187         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    188                 async_answer_0(callid, EHANGUP);
    189                 return;
    190         }
    191 
    192         if (comm_size < block_size) {
    193                 async_answer_0(callid, EHANGUP);
    194                 return;
    195         }
    196 
    197         (void) async_share_out_finalize(callid, &fs_va);
    198         if (fs_va == AS_MAP_FAILED) {
    199                 async_answer_0(callid, EHANGUP);
    200                 return;
    201         }
    202 
    203         while (true) {
    204                 callid = async_get_call(&call);
    205                 method = IPC_GET_IMETHOD(call);
    206                
    207                 if (!method) {
    208                         /* The other side has hung up. */
    209                         async_answer_0(callid, EOK);
    210                         return;
    211                 }
    212                
    213                 switch (method) {
    214                 case BD_READ_BLOCKS:
    215                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    216                             IPC_GET_ARG2(call));
    217                         cnt = IPC_GET_ARG3(call);
    218                         if (cnt * block_size > comm_size) {
    219                                 retval = ELIMIT;
    220                                 break;
    221                         }
    222                         retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va);
    223                         break;
    224                 case BD_WRITE_BLOCKS:
    225                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    226                             IPC_GET_ARG2(call));
    227                         cnt = IPC_GET_ARG3(call);
    228                         if (cnt * block_size > comm_size) {
    229                                 retval = ELIMIT;
    230                                 break;
    231                         }
    232                         retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va);
    233                         break;
    234                 case BD_GET_BLOCK_SIZE:
    235                         async_answer_1(callid, EOK, block_size);
    236                         continue;
    237                 case BD_GET_NUM_BLOCKS:
    238                         retval = ENOTSUP;
    239                         break;
    240                 default:
    241                         retval = EINVAL;
    242                         break;
    243                 }
    244                 async_answer_0(callid, retval);
    245         }
     205        bd_conn(iid, icall, &gxe_bd[disk_id].bd);
     206}
     207
     208/** Open device. */
     209static int gxe_bd_open(bd_srv_t *bd)
     210{
     211        return EOK;
     212}
     213
     214/** Close device. */
     215static int gxe_bd_close(bd_srv_t *bd)
     216{
     217        return EOK;
    246218}
    247219
    248220/** Read multiple blocks from the device. */
    249 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
    250     void *buf) {
    251 
     221static int gxe_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     222    void *buf, size_t size)
     223{
     224        int disk_id = bd_srv_gxe(bd)->disk_id;
    252225        int rc;
     226
     227        if (size < cnt * block_size)
     228                return EINVAL;
    253229
    254230        while (cnt > 0) {
     
    266242
    267243/** Write multiple blocks to the device. */
    268 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
    269     const void *buf) {
    270 
     244static int gxe_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     245    const void *buf, size_t size)
     246{
     247        int disk_id = bd_srv_gxe(bd)->disk_id;
    271248        int rc;
     249
     250        if (size < cnt * block_size)
     251                return EINVAL;
    272252
    273253        while (cnt > 0) {
     
    282262
    283263        return EOK;
     264}
     265
     266/** Get device block size. */
     267static int gxe_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     268{
     269        *rsize = block_size;
     270        return EOK;
     271}
     272
     273/** Get number of blocks on device. */
     274static int gxe_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     275{
     276        return ENOTSUP;
    284277}
    285278
  • uspace/srv/bd/part/guid_part/guid_part.c

    r14c5005 r9dec6d4  
    4747#include <stdlib.h>
    4848#include <unistd.h>
    49 #include <ipc/bd.h>
    5049#include <async.h>
    5150#include <as.h>
     51#include <bd_srv.h>
    5252#include <fibril_synch.h>
    5353#include <loc.h>
     
    8383        /** Service representing the partition (outbound device) */
    8484        service_id_t dsid;
     85        /** Block device server structure */
     86        bd_srv_t bd;
    8587        /** Points to next partition structure. */
    8688        struct part *next;
     
    100102static void gpt_pte_to_part(const gpt_entry_t *pte, part_t *part);
    101103static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    102 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf);
    103 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf);
    104104static int gpt_bsa_translate(part_t *p, aoff64_t ba, size_t cnt, aoff64_t *gba);
     105
     106static int gpt_bd_open(bd_srv_t *);
     107static int gpt_bd_close(bd_srv_t *);
     108static int gpt_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     109static int gpt_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     110static int gpt_bd_get_block_size(bd_srv_t *, size_t *);
     111static int gpt_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     112
     113static bd_ops_t gpt_bd_ops = {
     114        .open = gpt_bd_open,
     115        .close = gpt_bd_close,
     116        .read_blocks = gpt_bd_read_blocks,
     117        .write_blocks = gpt_bd_write_blocks,
     118        .get_block_size = gpt_bd_get_block_size,
     119        .get_num_blocks = gpt_bd_get_num_blocks
     120};
     121
     122static part_t *bd_srv_part(bd_srv_t *bd)
     123{
     124        return (part_t *)bd->arg;
     125}
    105126
    106127int main(int argc, char **argv)
     
    304325        }
    305326
     327        bd_srv_init(&part->bd);
     328        part->bd.ops = &gpt_bd_ops;
     329        part->bd.arg = part;
     330
    306331        part->dsid = 0;
    307332        part->next = NULL;
     
    310335static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    311336{
    312         size_t comm_size;
    313         void *fs_va = NULL;
    314         ipc_callid_t callid;
    315         ipc_call_t call;
    316         sysarg_t method;
    317337        service_id_t dh;
    318         unsigned int flags;
    319         int retval;
    320         aoff64_t ba;
    321         size_t cnt;
    322338        part_t *part;
    323339
     
    341357        assert(part->present == true);
    342358
    343         /* Answer the IPC_M_CONNECT_ME_TO call. */
    344         async_answer_0(iid, EOK);
    345 
    346         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    347                 async_answer_0(callid, EHANGUP);
    348                 return;
    349         }
    350 
    351         (void) async_share_out_finalize(callid, &fs_va);
    352         if (fs_va == AS_MAP_FAILED) {
    353                 async_answer_0(callid, EHANGUP);
    354                 return;
    355         }
    356 
    357         while (true) {
    358                 callid = async_get_call(&call);
    359                 method = IPC_GET_IMETHOD(call);
    360                
    361                 if (!method) {
    362                         /* The other side has hung up. */
    363                         async_answer_0(callid, EOK);
    364                         return;
    365                 }
    366                
    367                 switch (method) {
    368                 case BD_READ_BLOCKS:
    369                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    370                             IPC_GET_ARG2(call));
    371                         cnt = IPC_GET_ARG3(call);
    372                         if (cnt * block_size > comm_size) {
    373                                 retval = ELIMIT;
    374                                 break;
    375                         }
    376                         retval = gpt_bd_read(part, ba, cnt, fs_va);
    377                         break;
    378                 case BD_WRITE_BLOCKS:
    379                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    380                             IPC_GET_ARG2(call));
    381                         cnt = IPC_GET_ARG3(call);
    382                         if (cnt * block_size > comm_size) {
    383                                 retval = ELIMIT;
    384                                 break;
    385                         }
    386                         retval = gpt_bd_write(part, ba, cnt, fs_va);
    387                         break;
    388                 case BD_GET_BLOCK_SIZE:
    389                         async_answer_1(callid, EOK, block_size);
    390                         continue;
    391                 case BD_GET_NUM_BLOCKS:
    392                         async_answer_2(callid, EOK, LOWER32(part->length),
    393                             UPPER32(part->length));
    394                         continue;
    395                 default:
    396                         retval = EINVAL;
    397                         break;
    398                 }
    399                 async_answer_0(callid, retval);
    400         }
     359        bd_conn(iid, icall, &part->bd);
     360}
     361
     362/** Open device. */
     363static int gpt_bd_open(bd_srv_t *bd)
     364{
     365        return EOK;
     366}
     367
     368/** Close device. */
     369static int gpt_bd_close(bd_srv_t *bd)
     370{
     371        return EOK;
    401372}
    402373
    403374/** Read blocks from partition. */
    404 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf)
    405 {
     375static int gpt_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
     376    size_t size)
     377{
     378        part_t *p = bd_srv_part(bd);
    406379        aoff64_t gba;
     380
     381        if (cnt * block_size < size)
     382                return EINVAL;
    407383
    408384        if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK)
     
    413389
    414390/** Write blocks to partition. */
    415 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf)
    416 {
     391static int gpt_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     392    const void *buf, size_t size)
     393{
     394        part_t *p = bd_srv_part(bd);
    417395        aoff64_t gba;
     396
     397        if (cnt * block_size < size)
     398                return EINVAL;
    418399
    419400        if (gpt_bsa_translate(p, ba, cnt, &gba) != EOK)
     
    422403        return block_write_direct(indev_sid, gba, cnt, buf);
    423404}
     405
     406/** Get device block size. */
     407static int gpt_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     408{
     409        *rsize = block_size;
     410        return EOK;
     411}
     412
     413/** Get number of blocks on device. */
     414static int gpt_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     415{
     416        part_t *part = bd_srv_part(bd);
     417
     418        *rnb = part->length;
     419        return EOK;
     420}
     421
    424422
    425423/** Translate block segment address with range checking. */
  • uspace/srv/bd/part/mbr_part/mbr_part.c

    r14c5005 r9dec6d4  
    4444 *
    4545 * Referemces:
    46  *     
     46 *
    4747 * The source of MBR structures for this driver have been the following
    4848 * Wikipedia articles:
     
    5757#include <stdlib.h>
    5858#include <unistd.h>
    59 #include <ipc/bd.h>
    6059#include <async.h>
    6160#include <as.h>
     61#include <bd_srv.h>
    6262#include <fibril_synch.h>
    6363#include <loc.h>
     
    100100        /** Device representing the partition (outbound device) */
    101101        service_id_t dsid;
     102        /** Block device server structure */
     103        bd_srv_t bd;
    102104        /** Points to next partition structure. */
    103105        struct part *next;
     
    140142
    141143/** Partitioned device (inbound device) */
    142 static service_id_t indef_sid;
     144static service_id_t indev_sid;
    143145
    144146/** List of partitions. This structure is an empty head. */
     
    150152static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
    151153static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    152 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);
    153 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf);
    154154static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
     155
     156static int mbr_bd_open(bd_srv_t *);
     157static int mbr_bd_close(bd_srv_t *);
     158static int mbr_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     159static int mbr_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     160static int mbr_bd_get_block_size(bd_srv_t *, size_t *);
     161static int mbr_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     162
     163static bd_ops_t mbr_bd_ops = {
     164        .open = mbr_bd_open,
     165        .close = mbr_bd_close,
     166        .read_blocks = mbr_bd_read_blocks,
     167        .write_blocks = mbr_bd_write_blocks,
     168        .get_block_size = mbr_bd_get_block_size,
     169        .get_num_blocks = mbr_bd_get_num_blocks
     170};
     171
     172static part_t *bd_srv_part(bd_srv_t *bd)
     173{
     174        return (part_t *)bd->arg;
     175}
    155176
    156177int main(int argc, char **argv)
     
    183204        part_t *part;
    184205
    185         rc = loc_service_get_id(dev_name, &indef_sid, 0);
     206        rc = loc_service_get_id(dev_name, &indev_sid, 0);
    186207        if (rc != EOK) {
    187208                printf(NAME ": could not resolve device `%s'.\n", dev_name);
     
    189210        }
    190211
    191         rc = block_init(EXCHANGE_SERIALIZE, indef_sid, 2048);
     212        rc = block_init(EXCHANGE_SERIALIZE, indev_sid, 2048);
    192213        if (rc != EOK)  {
    193214                printf(NAME ": could not init libblock.\n");
     
    197218        /* Determine and verify block size. */
    198219
    199         rc = block_get_bsize(indef_sid, &block_size);
     220        rc = block_get_bsize(indev_sid, &block_size);
    200221        if (rc != EOK) {
    201222                printf(NAME ": error getting block size.\n");
     
    281302         */
    282303
    283         rc = block_read_direct(indef_sid, 0, 1, brb);
     304        rc = block_read_direct(indev_sid, 0, 1, brb);
    284305        if (rc != EOK) {
    285306                printf(NAME ": Failed reading MBR block.\n");
     
    332353                 */
    333354                ba = cp.start_addr;
    334                 rc = block_read_direct(indef_sid, ba, 1, brb);
     355                rc = block_read_direct(indev_sid, ba, 1, brb);
    335356                if (rc != EOK) {
    336357                        printf(NAME ": Failed reading EBR block at %"
     
    381402        part->present = (pte->ptype != PT_UNUSED) ? true : false;
    382403
     404        bd_srv_init(&part->bd);
     405        part->bd.ops = &mbr_bd_ops;
     406        part->bd.arg = part;
     407
    383408        part->dsid = 0;
    384409        part->next = NULL;
     
    387412static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    388413{
    389         size_t comm_size;
    390         void *fs_va = NULL;
    391         ipc_callid_t callid;
    392         ipc_call_t call;
    393         sysarg_t method;
    394414        service_id_t dh;
    395         unsigned int flags;
    396         int retval;
    397         uint64_t ba;
    398         size_t cnt;
    399415        part_t *part;
    400416
     
    417433
    418434        assert(part->present == true);
    419 
    420         /* Answer the IPC_M_CONNECT_ME_TO call. */
    421         async_answer_0(iid, EOK);
    422 
    423         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    424                 async_answer_0(callid, EHANGUP);
    425                 return;
    426         }
    427 
    428         (void) async_share_out_finalize(callid, &fs_va);
    429         if (fs_va == AS_MAP_FAILED) {
    430                 async_answer_0(callid, EHANGUP);
    431                 return;
    432         }
    433 
    434         while (1) {
    435                 callid = async_get_call(&call);
    436                 method = IPC_GET_IMETHOD(call);
    437                
    438                 if (!method) {
    439                         /* The other side has hung up. */
    440                         async_answer_0(callid, EOK);
    441                         return;
    442                 }
    443                
    444                 switch (method) {
    445                 case BD_READ_BLOCKS:
    446                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    447                             IPC_GET_ARG2(call));
    448                         cnt = IPC_GET_ARG3(call);
    449                         if (cnt * block_size > comm_size) {
    450                                 retval = ELIMIT;
    451                                 break;
    452                         }
    453                         retval = mbr_bd_read(part, ba, cnt, fs_va);
    454                         break;
    455                 case BD_WRITE_BLOCKS:
    456                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    457                             IPC_GET_ARG2(call));
    458                         cnt = IPC_GET_ARG3(call);
    459                         if (cnt * block_size > comm_size) {
    460                                 retval = ELIMIT;
    461                                 break;
    462                         }
    463                         retval = mbr_bd_write(part, ba, cnt, fs_va);
    464                         break;
    465                 case BD_GET_BLOCK_SIZE:
    466                         async_answer_1(callid, EOK, block_size);
    467                         continue;
    468                 case BD_GET_NUM_BLOCKS:
    469                         async_answer_2(callid, EOK, LOWER32(part->length),
    470                             UPPER32(part->length));
    471                         continue;
    472                 default:
    473                         retval = EINVAL;
    474                         break;
    475                 }
    476                 async_answer_0(callid, retval);
    477         }
     435        bd_conn(iid, icall, &part->bd);
     436}
     437
     438/** Open device. */
     439static int mbr_bd_open(bd_srv_t *bd)
     440{
     441        return EOK;
     442}
     443
     444/** Close device. */
     445static int mbr_bd_close(bd_srv_t *bd)
     446{
     447        return EOK;
    478448}
    479449
    480450/** Read blocks from partition. */
    481 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf)
    482 {
    483         uint64_t gba;
     451static int mbr_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
     452    size_t size)
     453{
     454        part_t *p = bd_srv_part(bd);
     455        aoff64_t gba;
     456
     457        if (cnt * block_size < size)
     458                return EINVAL;
    484459
    485460        if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
    486461                return ELIMIT;
    487462
    488         return block_read_direct(indef_sid, gba, cnt, buf);
     463        return block_read_direct(indev_sid, gba, cnt, buf);
    489464}
    490465
    491466/** Write blocks to partition. */
    492 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf)
    493 {
    494         uint64_t gba;
     467static int mbr_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     468    const void *buf, size_t size)
     469{
     470        part_t *p = bd_srv_part(bd);
     471        aoff64_t gba;
     472
     473        if (cnt * block_size < size)
     474                return EINVAL;
    495475
    496476        if (mbr_bsa_translate(p, ba, cnt, &gba) != EOK)
    497477                return ELIMIT;
    498478
    499         return block_write_direct(indef_sid, gba, cnt, buf);
     479        return block_write_direct(indev_sid, gba, cnt, buf);
     480}
     481
     482/** Get device block size. */
     483static int mbr_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     484{
     485        *rsize = block_size;
     486        return EOK;
     487}
     488
     489/** Get number of blocks on device. */
     490static int mbr_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     491{
     492        part_t *part = bd_srv_part(bd);
     493
     494        *rnb = part->length;
     495        return EOK;
    500496}
    501497
  • uspace/srv/bd/rd/rd.c

    r14c5005 r9dec6d4  
    4343#include <sysinfo.h>
    4444#include <as.h>
     45#include <bd_srv.h>
    4546#include <ddi.h>
    4647#include <align.h>
     
    5354#include <stdio.h>
    5455#include <loc.h>
    55 #include <ipc/bd.h>
    5656#include <macros.h>
    5757#include <inttypes.h>
     
    6868static const size_t block_size = 512;
    6969
    70 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf);
    71 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
     70static int rd_open(bd_srv_t *);
     71static int rd_close(bd_srv_t *);
     72static int rd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     73static int rd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     74static int rd_get_block_size(bd_srv_t *, size_t *);
     75static int rd_get_num_blocks(bd_srv_t *, aoff64_t *);
    7276
    7377/** This rwlock protects the ramdisk's data.
     
    7882 *
    7983 */
    80 fibril_rwlock_t rd_lock;
    81 
    82 /** Handle one connection to ramdisk.
    83  *
    84  * @param iid   Hash of the request that opened the connection.
    85  * @param icall Call data of the request that opened the connection.
    86  */
    87 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    88 {
    89         ipc_callid_t callid;
    90         ipc_call_t call;
    91         int retval;
    92         void *fs_va = NULL;
    93         uint64_t ba;
    94         size_t cnt;
    95         size_t comm_size;
    96        
    97         /*
    98          * Answer the first IPC_M_CONNECT_ME_TO call.
    99          */
    100         async_answer_0(iid, EOK);
    101        
    102         /*
    103          * Now we wait for the client to send us its communication as_area.
    104          */
    105         unsigned int flags;
    106         if (async_share_out_receive(&callid, &comm_size, &flags)) {
    107                 (void) async_share_out_finalize(callid, &fs_va);
    108                 if (fs_va == AS_MAP_FAILED) {
    109                         async_answer_0(callid, EHANGUP);
    110                         return;
    111                 }
    112         } else {
    113                 /*
    114                  * The client doesn't speak the same protocol.
    115                  * At this point we can't handle protocol variations.
    116                  * Close the connection.
    117                  */
    118                 async_answer_0(callid, EHANGUP);
    119                 return;
    120         }
    121        
    122         while (true) {
    123                 callid = async_get_call(&call);
    124                
    125                 if (!IPC_GET_IMETHOD(call)) {
    126                         /*
    127                          * The other side has hung up.
    128                          * Exit the fibril.
    129                          */
    130                         async_answer_0(callid, EOK);
    131                         return;
    132                 }
    133                
    134                 switch (IPC_GET_IMETHOD(call)) {
    135                 case BD_READ_BLOCKS:
    136                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    137                             IPC_GET_ARG2(call));
    138                         cnt = IPC_GET_ARG3(call);
    139                         if (cnt * block_size > comm_size) {
    140                                 retval = ELIMIT;
    141                                 break;
    142                         }
    143                         retval = rd_read_blocks(ba, cnt, fs_va);
    144                         break;
    145                 case BD_WRITE_BLOCKS:
    146                         ba = MERGE_LOUP32(IPC_GET_ARG1(call),
    147                             IPC_GET_ARG2(call));
    148                         cnt = IPC_GET_ARG3(call);
    149                         if (cnt * block_size > comm_size) {
    150                                 retval = ELIMIT;
    151                                 break;
    152                         }
    153                         retval = rd_write_blocks(ba, cnt, fs_va);
    154                         break;
    155                 case BD_GET_BLOCK_SIZE:
    156                         async_answer_1(callid, EOK, block_size);
    157                         continue;
    158                 case BD_GET_NUM_BLOCKS:
    159                         async_answer_2(callid, EOK, LOWER32(rd_size / block_size),
    160                             UPPER32(rd_size / block_size));
    161                         continue;
    162                 default:
    163                         /*
    164                          * The client doesn't speak the same protocol.
    165                          * Instead of closing the connection, we just ignore
    166                          * the call. This can be useful if the client uses a
    167                          * newer version of the protocol.
    168                          */
    169                         retval = EINVAL;
    170                         break;
    171                 }
    172                 async_answer_0(callid, retval);
    173         }
     84static fibril_rwlock_t rd_lock;
     85
     86static bd_ops_t rd_bd_ops = {
     87        .open = rd_open,
     88        .close = rd_close,
     89        .read_blocks = rd_read_blocks,
     90        .write_blocks = rd_write_blocks,
     91        .get_block_size = rd_get_block_size,
     92        .get_num_blocks = rd_get_num_blocks
     93};
     94
     95static bd_srv_t bd_srv;
     96
     97static void rd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     98{
     99        bd_conn(iid, icall, &bd_srv);
     100}
     101
     102/** Open device. */
     103static int rd_open(bd_srv_t *bd)
     104{
     105        return EOK;
     106}
     107
     108/** Close device. */
     109static int rd_close(bd_srv_t *bd)
     110{
     111        return EOK;
    174112}
    175113
    176114/** Read blocks from the device. */
    177 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf)
     115static int rd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
     116    size_t size)
    178117{
    179118        if ((ba + cnt) * block_size > rd_size) {
     
    183122       
    184123        fibril_rwlock_read_lock(&rd_lock);
    185         memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
     124        memcpy(buf, rd_addr + ba * block_size, min(block_size * cnt, size));
    186125        fibril_rwlock_read_unlock(&rd_lock);
    187126       
     
    190129
    191130/** Write blocks to the device. */
    192 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf)
     131static int rd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     132    const void *buf, size_t size)
    193133{
    194134        if ((ba + cnt) * block_size > rd_size) {
     
    198138       
    199139        fibril_rwlock_write_lock(&rd_lock);
    200         memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
     140        memcpy(rd_addr + ba * block_size, buf, min(block_size * cnt, size));
    201141        fibril_rwlock_write_unlock(&rd_lock);
    202142       
     
    235175            (void *) addr_phys, size);
    236176       
    237         async_set_client_connection(rd_connection);
     177        bd_srv_init(&bd_srv);
     178        bd_srv.ops = &rd_bd_ops;
     179       
     180        async_set_client_connection(rd_client_conn);
    238181        ret = loc_server_register(NAME);
    239182        if (ret != EOK) {
     
    254197}
    255198
     199/** Get device block size. */
     200static int rd_get_block_size(bd_srv_t *bd, size_t *rsize)
     201{
     202        *rsize = block_size;
     203        return EOK;
     204}
     205
     206/** Get number of blocks on device. */
     207static int rd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     208{
     209        *rnb = rd_size / block_size;
     210        return EOK;
     211}
     212
    256213int main(int argc, char **argv)
    257214{
  • uspace/srv/bd/sata_bd/sata_bd.c

    r14c5005 r9dec6d4  
    3838
    3939#include <sys/types.h>
     40#include <bd_srv.h>
    4041#include <errno.h>
    4142#include <stdio.h>
    42 #include <ipc/bd.h>
    4343#include <str.h>
    4444#include <loc.h>
     
    5656static sata_bd_dev_t disk[MAXDISKS];
    5757static int disk_count;
     58
     59static int sata_bd_open(bd_srv_t *);
     60static int sata_bd_close(bd_srv_t *);
     61static int sata_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     62static int sata_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     63static int sata_bd_get_block_size(bd_srv_t *, size_t *);
     64static int sata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     65
     66static bd_ops_t sata_bd_ops = {
     67        .open = sata_bd_open,
     68        .close = sata_bd_close,
     69        .read_blocks = sata_bd_read_blocks,
     70        .write_blocks = sata_bd_write_blocks,
     71        .get_block_size = sata_bd_get_block_size,
     72        .get_num_blocks = sata_bd_get_num_blocks
     73};
     74
     75static sata_bd_dev_t *bd_srv_sata(bd_srv_t *bd)
     76{
     77        return (sata_bd_dev_t *)bd->arg;
     78}
    5879
    5980/** Find SATA devices in device tree.
     
    82103               
    83104                ahci_get_num_blocks(disk[disk_count].sess, &disk[disk_count].blocks);
    84                                
     105               
     106                bd_srv_init(&disk[disk_count].bd);
     107                disk[disk_count].bd.ops = &sata_bd_ops;
     108                disk[disk_count].bd.arg = &disk[disk_count];
     109               
    85110                printf("Device %s - %s , blocks: %lu, block_size: %lu\n",
    86111                    disk[disk_count].dev_name, disk[disk_count].sata_dev_name,
     
    141166static void sata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    142167{
    143         void *fs_va = NULL;
    144         ipc_callid_t callid;
    145         ipc_call_t call;
    146         sysarg_t method;
    147168        service_id_t dsid;
    148         /* Size of the communication area. */
    149         size_t comm_size;       
    150         unsigned int flags;
    151         int retval = 0;
    152         uint64_t ba;
    153         size_t cnt;
    154169        int disk_id, i;
    155170
     
    168183        }
    169184
    170         /* Answer the IPC_M_CONNECT_ME_TO call. */
    171         async_answer_0(iid, EOK);
    172 
    173         if (!async_share_out_receive(&callid, &comm_size, &flags)) {
    174                 async_answer_0(callid, EHANGUP);
    175                 return;
    176         }
    177 
    178         (void) async_share_out_finalize(callid, &fs_va);
    179         if (fs_va == (void *) -1) {
    180                 async_answer_0(callid, EHANGUP);
    181                 return;
    182         }
    183 
    184         while (true) {
    185                 callid = async_get_call(&call);
    186                 method = IPC_GET_IMETHOD(call);
    187                
    188                 if (!method) {
    189                         /* The other side has hung up. */
    190                         async_answer_0(callid, EOK);
    191                         return;
    192                 }
    193                
    194                 switch (method) {
    195                         case BD_READ_BLOCKS:
    196                                 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    197                                 cnt = IPC_GET_ARG3(call);
    198                                 if (cnt * disk[disk_id].block_size > comm_size) {
    199                                         retval = ELIMIT;
    200                                         break;
    201                                 }
    202                                 retval = ahci_read_blocks(disk[disk_id].sess, ba, cnt, fs_va);
    203                                 break;
    204                         case BD_WRITE_BLOCKS:
    205                                 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    206                                 cnt = IPC_GET_ARG3(call);
    207                                 if (cnt * disk[disk_id].block_size > comm_size) {
    208                                         retval = ELIMIT;
    209                                         break;
    210                                 }
    211                                 retval = ahci_write_blocks(disk[disk_id].sess, ba, cnt, fs_va);
    212                                 break;
    213                         case BD_GET_BLOCK_SIZE:
    214                                 async_answer_1(callid, EOK, disk[disk_id].block_size);
    215                                 continue;
    216                         case BD_GET_NUM_BLOCKS:
    217                                 async_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
    218                                     UPPER32(disk[disk_id].blocks));
    219                                 break;
    220                         default:
    221                                 retval = EINVAL;
    222                                 break;
    223                         }
    224                 async_answer_0(callid, retval);
    225         }
    226 }
     185        bd_conn(iid, icall, &disk[disk_id].bd);
     186}
     187
     188/** Open device. */
     189static int sata_bd_open(bd_srv_t *bd)
     190{
     191        return EOK;
     192}
     193
     194/** Close device. */
     195static int sata_bd_close(bd_srv_t *bd)
     196{
     197        return EOK;
     198}
     199
     200/** Read blocks from partition. */
     201static int sata_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
     202    size_t size)
     203{
     204        sata_bd_dev_t *sbd = bd_srv_sata(bd);
     205
     206        if (size < cnt * sbd->block_size)
     207                return EINVAL;
     208
     209        return ahci_read_blocks(sbd->sess, ba, cnt, buf);
     210}
     211
     212/** Write blocks to partition. */
     213static int sata_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     214    const void *buf, size_t size)
     215{
     216        sata_bd_dev_t *sbd = bd_srv_sata(bd);
     217
     218        if (size < cnt * sbd->block_size)
     219                return EINVAL;
     220
     221        return ahci_write_blocks(sbd->sess, ba, cnt, (void *)buf);
     222}
     223
     224/** Get device block size. */
     225static int sata_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     226{
     227        sata_bd_dev_t *sbd = bd_srv_sata(bd);
     228
     229        *rsize = sbd->block_size;
     230        return EOK;
     231}
     232
     233/** Get number of blocks on device. */
     234static int sata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     235{
     236        sata_bd_dev_t *sbd = bd_srv_sata(bd);
     237
     238        *rnb = sbd->blocks;
     239        return EOK;
     240}
     241
    227242
    228243int main(int argc, char **argv)
  • uspace/srv/bd/sata_bd/sata_bd.h

    r14c5005 r9dec6d4  
    3838#define SATA_DEV_NAME_LENGTH 256
    3939
     40#include <async.h>
     41#include <bd_srv.h>
     42#include <loc.h>
    4043#include <sys/types.h>
    41 #include <loc.h>
    4244
    4345/** SATA Block Device. */
    4446typedef struct {
    45         /** Device name in device tree. */ 
    46         char* dev_name;
    47         /** SATA Device name. */ 
    48         char sata_dev_name[SATA_DEV_NAME_LENGTH]; 
     47        /** Device name in device tree. */
     48        char *dev_name;
     49        /** SATA Device name. */
     50        char sata_dev_name[SATA_DEV_NAME_LENGTH];
    4951        /** Session to device methods. */
    50         async_sess_t* sess;
     52        async_sess_t *sess;
    5153        /** Loc service id. */
    5254        service_id_t service_id;
    5355        /** Number of blocks. */
    54         uint64_t blocks; 
     56        uint64_t blocks;
    5557        /** Size of block. */
    56         size_t block_size;
     58        size_t block_size;
     59        /** Block device server structure */
     60        bd_srv_t bd;
    5761} sata_bd_dev_t;
    5862
  • uspace/srv/fs/tmpfs/tmpfs_dump.c

    r14c5005 r9dec6d4  
    4949#define TMPFS_COMM_SIZE         1024
    5050
     51static uint8_t tmpfs_buf[TMPFS_COMM_SIZE];
     52
    5153struct rdentry {
    5254        uint8_t type;
     
    6870                uint32_t size;
    6971               
    70                 if (block_seqread(dsid, bufpos, buflen, pos, &entry,
     72                if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &entry,
    7173                    sizeof(entry)) != EOK)
    7274                        return false;
     
    8890                        }
    8991                       
    90                         if (block_seqread(dsid, bufpos, buflen, pos, fname,
     92                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname,
    9193                            entry.len) != EOK) {
    9294                                (void) ops->destroy(fn);
     
    104106                        free(fname);
    105107                       
    106                         if (block_seqread(dsid, bufpos, buflen, pos, &size,
     108                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &size,
    107109                            sizeof(size)) != EOK)
    108110                                return false;
     
    116118                       
    117119                        nodep->size = size;
    118                         if (block_seqread(dsid, bufpos, buflen, pos, nodep->data,
     120                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, nodep->data,
    119121                            size) != EOK)
    120122                                return false;
     
    132134                        }
    133135                       
    134                         if (block_seqread(dsid, bufpos, buflen, pos, fname,
     136                        if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname,
    135137                            entry.len) != EOK) {
    136138                                (void) ops->destroy(fn);
     
    176178       
    177179        char tag[6];
    178         if (block_seqread(dsid, &bufpos, &buflen, &pos, tag, 5) != EOK)
     180        if (block_seqread(dsid, tmpfs_buf, &bufpos, &buflen, &pos, tag, 5) != EOK)
    179181                goto error;
    180182       
Note: See TracChangeset for help on using the changeset viewer.