Ignore:
File:
1 edited

Legend:

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

    r4802dd7 rfaba839  
    5151#include <libarch/ddi.h>
    5252#include <ddi.h>
     53#include <ipc/bd.h>
    5354#include <async.h>
    5455#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 ata_disk[MAX_DISKS];
     100static disk_t 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 
    106 static int ata_bd_open(bd_srv_t *);
    107 static int ata_bd_close(bd_srv_t *);
    108 static int ata_bd_read_blocks(bd_srv_t *, uint64_t ba, size_t cnt, void *buf,
    109     size_t);
    110 static int ata_bd_read_toc(bd_srv_t *, uint8_t session, void *buf, size_t);
    111 static int ata_bd_write_blocks(bd_srv_t *, uint64_t ba, size_t cnt,
    112     const void *buf, size_t);
    113 static int ata_bd_get_block_size(bd_srv_t *, size_t *);
    114 static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    115 
     105static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     106    void *buf);
     107static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     108    const void *buf);
    116109static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
    117110    void *buf);
     
    134127    unsigned timeout);
    135128
    136 static 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 
    146 static disk_t *bd_srv_disk(bd_srv_t *bd)
    147 {
    148         return (disk_t *)bd->arg;
    149 }
    150 
    151129int main(int argc, char **argv)
    152130{
     
    183161                fflush(stdout);
    184162
    185                 rc = disk_init(&ata_disk[i], i);
     163                rc = disk_init(&disk[i], i);
    186164
    187165                if (rc == EOK) {
    188                         disk_print_summary(&ata_disk[i]);
     166                        disk_print_summary(&disk[i]);
    189167                } else {
    190168                        printf("Not found.\n");
     
    196174        for (i = 0; i < MAX_DISKS; i++) {
    197175                /* Skip unattached drives. */
    198                 if (ata_disk[i].present == false)
     176                if (disk[i].present == false)
    199177                        continue;
    200178               
    201179                snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
    202                 rc = loc_service_register(name, &ata_disk[i].service_id);
     180                rc = loc_service_register(name, &disk[i].service_id);
    203181                if (rc != EOK) {
    204182                        printf(NAME ": Unable to register device %s.\n", name);
     
    239217                case am_chs:
    240218                        printf("CHS %u cylinders, %u heads, %u sectors",
    241                             d->geom.cylinders, d->geom.heads,
    242                             d->geom.sectors);
     219                            disk->geom.cylinders, disk->geom.heads,
     220                            disk->geom.sectors);
    243221                        break;
    244222                case am_lba28:
     
    295273static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    296274{
     275        void *fs_va = NULL;
     276        ipc_callid_t callid;
     277        ipc_call_t call;
     278        sysarg_t method;
    297279        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;
    298285        int disk_id, i;
    299286
     
    304291        disk_id = -1;
    305292        for (i = 0; i < MAX_DISKS; i++)
    306                 if (ata_disk[i].service_id == dsid)
     293                if (disk[i].service_id == dsid)
    307294                        disk_id = i;
    308295
    309         if (disk_id < 0 || ata_disk[disk_id].present == false) {
     296        if (disk_id < 0 || disk[disk_id].present == false) {
    310297                async_answer_0(iid, EINVAL);
    311298                return;
    312299        }
    313300
    314         bd_conn(iid, icall, &ata_disk[disk_id].bd);
     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        }
    315367}
    316368
     
    332384        unsigned i;
    333385
    334         d->disk_id = disk_id;
    335386        d->present = false;
    336387        fibril_mutex_initialize(&d->lock);
    337 
    338         bd_srv_init(&d->bd);
    339         d->bd.ops = &ata_bd_ops;
    340         d->bd.arg = d;
    341388
    342389        /* Try identify command. */
     
    467514}
    468515
    469 static int ata_bd_open(bd_srv_t *bd)
    470 {
    471         return EOK;
    472 }
    473 
    474 static int ata_bd_close(bd_srv_t *bd)
    475 {
    476         return EOK;
    477 }
    478 
    479516/** Read multiple blocks from the device. */
    480 static 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);
     517static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     518    void *buf) {
     519
    484520        int rc;
    485521
    486         if (size < cnt * disk->block_size)
    487                 return EINVAL;
    488 
    489522        while (cnt > 0) {
    490                 if (disk->dev_type == ata_reg_dev)
    491                         rc = ata_rcmd_read(disk->disk_id, ba, 1, buf);
     523                if (disk[disk_id].dev_type == ata_reg_dev)
     524                        rc = ata_rcmd_read(disk_id, ba, 1, buf);
    492525                else
    493                         rc = ata_pcmd_read_12(disk->disk_id, ba, 1, buf,
    494                             disk->block_size);
     526                        rc = ata_pcmd_read_12(disk_id, ba, 1, buf,
     527                            disk[disk_id].block_size);
    495528
    496529                if (rc != EOK)
     
    499532                ++ba;
    500533                --cnt;
    501                 buf += disk->block_size;
    502         }
    503 
    504         return EOK;
    505 }
    506 
    507 /** Read TOC from device. */
    508 static 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);
     534                buf += disk[disk_id].block_size;
     535        }
     536
     537        return EOK;
    513538}
    514539
    515540/** Write multiple blocks to the device. */
    516 static 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);
     541static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     542    const void *buf) {
     543
    520544        int rc;
    521545
    522         if (disk->dev_type != ata_reg_dev)
     546        if (disk[disk_id].dev_type != ata_reg_dev)
    523547                return ENOTSUP;
    524548
    525         if (size < cnt * disk->block_size)
    526                 return EINVAL;
    527 
    528549        while (cnt > 0) {
    529                 rc = ata_rcmd_write(disk->disk_id, ba, 1, buf);
     550                rc = ata_rcmd_write(disk_id, ba, 1, buf);
    530551                if (rc != EOK)
    531552                        return rc;
     
    533554                ++ba;
    534555                --cnt;
    535                 buf += disk->block_size;
    536         }
    537 
    538         return EOK;
    539 }
    540 
    541 /** Get device block size. */
    542 static 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. */
    551 static 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;
     556                buf += disk[disk_id].block_size;
     557        }
     558
    556559        return EOK;
    557560}
     
    682685        uint16_t val;
    683686
    684         d = &ata_disk[dev_idx];
     687        d = &disk[dev_idx];
    685688        fibril_mutex_lock(&d->lock);
    686689
     
    871874        block_coord_t bc;
    872875
    873         d = &ata_disk[disk_id];
     876        d = &disk[disk_id];
    874877       
    875878        /* Silence warning. */
     
    916919                /* Read data from the device buffer. */
    917920
    918                 for (i = 0; i < ata_disk[disk_id].block_size / 2; i++) {
     921                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    919922                        data = pio_read_16(&cmd->data_port);
    920923                        ((uint16_t *) buf)[i] = data;
     
    947950        block_coord_t bc;
    948951
    949         d = &ata_disk[disk_id];
     952        d = &disk[disk_id];
    950953       
    951954        /* Silence warning. */
     
    992995                /* Write data to the device buffer. */
    993996
    994                 for (i = 0; i < d->block_size / 2; i++) {
     997                for (i = 0; i < disk[disk_id].block_size / 2; i++) {
    995998                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    996999                }
Note: See TracChangeset for help on using the changeset viewer.