Changeset 4802dd7 in mainline for uspace/srv/bd/ata_bd/ata_bd.c


Ignore:
Timestamp:
2012-08-13T22:01:04Z (12 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.

File:
1 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                }
Note: See TracChangeset for help on using the changeset viewer.