Changeset beb9336 in mainline for uspace/srv/bd/gxe_bd/gxe_bd.c


Ignore:
Timestamp:
2012-08-24T14:07:52Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
041ab64
Parents:
bd29f9c9 (diff), db81577 (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 with mainline

File:
1 edited

Legend:

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

    rbd29f9c9 rbeb9336  
    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 service structure */
     91        bd_srvs_t bds;
     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_srvs_t *, 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->srvs->sarg;
     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_srvs_init(&gxe_bd[i].bds);
     169                gxe_bd[i].bds.ops = &gxe_bd_ops;
     170                gxe_bd[i].bds.sarg = (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].bds);
     206}
     207
     208/** Open device. */
     209static int gxe_bd_open(bd_srvs_t *bds, 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
Note: See TracChangeset for help on using the changeset viewer.