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


Ignore:
Timestamp:
2009-09-21T11:53:03Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4098e38
Parents:
2f636b6 (diff), c1618ed (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r2f636b6 rf6b5593  
    4747#include <sys/types.h>
    4848#include <errno.h>
     49#include <macros.h>
    4950#include <task.h>
    5051
     
    9798static int gxe_bd_init(void);
    9899static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
    99 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
     100static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
    100101    void *buf);
    101 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
    102     void *buf);
    103 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
     102static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
    104103    const void *buf);
     104static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf);
     105static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf);
    105106
    106107int main(int argc, char **argv)
     
    163164        int flags;
    164165        int retval;
    165         off_t idx;
    166         size_t size;
     166        uint64_t ba;
     167        unsigned cnt;
    167168        int disk_id, i;
    168169
     
    185186
    186187        if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
     188                ipc_answer_0(callid, EHANGUP);
     189                return;
     190        }
     191
     192        if (comm_size < block_size) {
    187193                ipc_answer_0(callid, EHANGUP);
    188194                return;
     
    205211                        ipc_answer_0(callid, EOK);
    206212                        return;
    207                 case BD_READ_BLOCK:
    208                 case BD_WRITE_BLOCK:
    209                         idx = IPC_GET_ARG1(call);
    210                         size = IPC_GET_ARG2(call);
    211                         if (size > comm_size) {
    212                                 retval = EINVAL;
     213                case BD_READ_BLOCKS:
     214                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     215                            IPC_GET_ARG2(call));
     216                        cnt = IPC_GET_ARG3(call);
     217                        if (cnt * block_size > comm_size) {
     218                                retval = ELIMIT;
    213219                                break;
    214220                        }
    215                         retval = gx_bd_rdwr(disk_id, method, idx * size,
    216                             size, fs_va);
     221                        retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va);
    217222                        break;
     223                case BD_WRITE_BLOCKS:
     224                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     225                            IPC_GET_ARG2(call));
     226                        cnt = IPC_GET_ARG3(call);
     227                        if (cnt * block_size > comm_size) {
     228                                retval = ELIMIT;
     229                                break;
     230                        }
     231                        retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va);
     232                        break;
     233                case BD_GET_BLOCK_SIZE:
     234                        ipc_answer_1(callid, EOK, block_size);
     235                        continue;
    218236                default:
    219237                        retval = EINVAL;
     
    224242}
    225243
    226 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
    227     void *buf)
    228 {
     244/** Read multiple blocks from the device. */
     245static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     246    void *buf) {
     247
    229248        int rc;
    230         size_t now;
    231 
    232         while (size > 0) {
    233                 now = size < block_size ? size : block_size;
    234 
    235                 if (method == BD_READ_BLOCK)
    236                         rc = gxe_bd_read_block(disk_id, offset, now, buf);
    237                 else
    238                         rc = gxe_bd_write_block(disk_id, offset, now, buf);
    239 
     249
     250        while (cnt > 0) {
     251                rc = gxe_bd_read_block(disk_id, ba, buf);
    240252                if (rc != EOK)
    241253                        return rc;
    242254
     255                ++ba;
     256                --cnt;
    243257                buf += block_size;
    244                 offset += block_size;
    245 
    246                 if (size > block_size)
    247                         size -= block_size;
    248                 else
    249                         size = 0;
    250         }
    251 
    252         return EOK;
    253 }
    254 
    255 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
    256     void *buf)
     258        }
     259
     260        return EOK;
     261}
     262
     263/** Write multiple blocks to the device. */
     264static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
     265    const void *buf) {
     266
     267        int rc;
     268
     269        while (cnt > 0) {
     270                rc = gxe_bd_write_block(disk_id, ba, buf);
     271                if (rc != EOK)
     272                        return rc;
     273
     274                ++ba;
     275                --cnt;
     276                buf += block_size;
     277        }
     278
     279        return EOK;
     280}
     281
     282/** Read a block from the device. */
     283static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf)
    257284{
    258285        uint32_t status;
     286        uint64_t byte_addr;
    259287        size_t i;
    260288        uint32_t w;
    261289
     290        byte_addr = ba * block_size;
     291
    262292        fibril_mutex_lock(&dev_lock[disk_id]);
    263         pio_write_32(&dev->offset_lo, (uint32_t) offset);
    264         pio_write_32(&dev->offset_hi, offset >> 32);
     293        pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
     294        pio_write_32(&dev->offset_hi, byte_addr >> 32);
    265295        pio_write_32(&dev->disk_id, disk_id);
    266296        pio_write_32(&dev->control, CTL_READ_START);
     
    272302        }
    273303
    274         for (i = 0; i < size; i++) {
     304        for (i = 0; i < block_size; i++) {
    275305                ((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]);
    276306        }
     
    280310}
    281311
    282 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
    283     const void *buf)
     312/** Write a block to the device. */
     313static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf)
    284314{
    285315        uint32_t status;
     316        uint64_t byte_addr;
    286317        size_t i;
    287318
    288         for (i = 0; i < size; i++) {
     319        byte_addr = ba * block_size;
     320
     321        fibril_mutex_lock(&dev_lock[disk_id]);
     322
     323        for (i = 0; i < block_size; i++) {
    289324                pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]);
    290325        }
    291326
    292         fibril_mutex_lock(&dev_lock[disk_id]);
    293         pio_write_32(&dev->offset_lo, (uint32_t) offset);
    294         pio_write_32(&dev->offset_hi, offset >> 32);
     327        pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
     328        pio_write_32(&dev->offset_hi, byte_addr >> 32);
    295329        pio_write_32(&dev->disk_id, disk_id);
    296330        pio_write_32(&dev->control, CTL_WRITE_START);
Note: See TracChangeset for help on using the changeset viewer.