Changeset 4802dd7 in mainline for uspace/srv


Ignore:
Timestamp:
2012-08-13T22:01:04Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
135486d, 71b0d4d4, 9dec6d4, cddcc4a3
Parents:
4820360
Message:

Factor out client and server IPC stubs for block devices.

Location:
uspace/srv
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/ata_bd/ata_bd.c

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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

    r4820360 r4802dd7  
    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.