Changeset 04803bf in mainline for uspace/srv/bd/gxe_bd/gxe_bd.c


Ignore:
Timestamp:
2011-03-21T22:00:17Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
143932e
Parents:
b50b5af2 (diff), 7308e84 (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 (needs fixes).

File:
1 edited

Legend:

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

    rb50b5af2 r04803bf  
    3939#include <libarch/ddi.h>
    4040#include <ddi.h>
    41 #include <ipc/ipc.h>
    4241#include <ipc/bd.h>
    4342#include <async.h>
    4443#include <as.h>
    45 #include <fibril_sync.h>
     44#include <fibril_synch.h>
    4645#include <devmap.h>
    4746#include <sys/types.h>
    4847#include <errno.h>
     48#include <macros.h>
    4949#include <task.h>
    5050
    51 #define NAME "gxe_bd"
     51#define NAME       "gxe_bd"
     52#define NAMESPACE  "bd"
    5253
    5354enum {
     
    9192static gxe_bd_t *dev;
    9293
    93 static dev_handle_t dev_handle[MAX_DISKS];
     94static devmap_handle_t devmap_handle[MAX_DISKS];
    9495
    9596static fibril_mutex_t dev_lock[MAX_DISKS];
     
    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)
     
    140141
    141142        for (i = 0; i < MAX_DISKS; i++) {
    142                 snprintf(name, 16, "disk%d", i);
    143                 rc = devmap_device_register(name, &dev_handle[i]);
     143                snprintf(name, 16, "%s/disk%d", NAMESPACE, i);
     144                rc = devmap_device_register(name, &devmap_handle[i]);
    144145                if (rc != EOK) {
    145                         devmap_hangup_phone(DEVMAP_DRIVER);
    146                         printf(NAME ": Unable to register device %s.\n",
    147                                 name);
     146                        printf(NAME ": Unable to register device %s.\n", name);
    148147                        return rc;
    149148                }
     
    159158        ipc_callid_t callid;
    160159        ipc_call_t call;
    161         ipcarg_t method;
    162         dev_handle_t dh;
    163         int flags;
     160        sysarg_t method;
     161        devmap_handle_t dh;
     162        unsigned int flags;
    164163        int retval;
    165         off_t idx;
    166         size_t size;
     164        uint64_t ba;
     165        unsigned cnt;
    167166        int disk_id, i;
    168167
     
    173172        disk_id = -1;
    174173        for (i = 0; i < MAX_DISKS; i++)
    175                 if (dev_handle[i] == dh)
     174                if (devmap_handle[i] == dh)
    176175                        disk_id = i;
    177176
    178177        if (disk_id < 0) {
    179                 ipc_answer_0(iid, EINVAL);
     178                async_answer_0(iid, EINVAL);
    180179                return;
    181180        }
    182181
    183182        /* Answer the IPC_M_CONNECT_ME_TO call. */
    184         ipc_answer_0(iid, EOK);
    185 
    186         if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
    187                 ipc_answer_0(callid, EHANGUP);
     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        if (comm_size < block_size) {
     191                async_answer_0(callid, EHANGUP);
    188192                return;
    189193        }
     
    191195        fs_va = as_get_mappable_page(comm_size);
    192196        if (fs_va == NULL) {
    193                 ipc_answer_0(callid, EHANGUP);
     197                async_answer_0(callid, EHANGUP);
    194198                return;
    195199        }
    196200
    197         (void) ipc_share_out_finalize(callid, fs_va);
     201        (void) async_share_out_finalize(callid, fs_va);
    198202
    199203        while (1) {
    200204                callid = async_get_call(&call);
    201                 method = IPC_GET_METHOD(call);
     205                method = IPC_GET_IMETHOD(call);
    202206                switch (method) {
    203207                case IPC_M_PHONE_HUNGUP:
    204208                        /* The other side has hung up. */
    205                         ipc_answer_0(callid, EOK);
     209                        async_answer_0(callid, EOK);
    206210                        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;
     211                case BD_READ_BLOCKS:
     212                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     213                            IPC_GET_ARG2(call));
     214                        cnt = IPC_GET_ARG3(call);
     215                        if (cnt * block_size > comm_size) {
     216                                retval = ELIMIT;
    213217                                break;
    214218                        }
    215                         retval = gx_bd_rdwr(disk_id, method, idx * size,
    216                             size, fs_va);
     219                        retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va);
     220                        break;
     221                case BD_WRITE_BLOCKS:
     222                        ba = MERGE_LOUP32(IPC_GET_ARG1(call),
     223                            IPC_GET_ARG2(call));
     224                        cnt = IPC_GET_ARG3(call);
     225                        if (cnt * block_size > comm_size) {
     226                                retval = ELIMIT;
     227                                break;
     228                        }
     229                        retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va);
     230                        break;
     231                case BD_GET_BLOCK_SIZE:
     232                        async_answer_1(callid, EOK, block_size);
     233                        continue;
     234                case BD_GET_NUM_BLOCKS:
     235                        retval = ENOTSUP;
    217236                        break;
    218237                default:
     
    220239                        break;
    221240                }
    222                 ipc_answer_0(callid, retval);
    223         }
    224 }
    225 
    226 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
    227     void *buf)
    228 {
     241                async_answer_0(callid, retval);
     242        }
     243}
     244
     245/** Read multiple blocks from the device. */
     246static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     247    void *buf) {
     248
    229249        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 
     250
     251        while (cnt > 0) {
     252                rc = gxe_bd_read_block(disk_id, ba, buf);
    240253                if (rc != EOK)
    241254                        return rc;
    242255
     256                ++ba;
     257                --cnt;
    243258                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)
     259        }
     260
     261        return EOK;
     262}
     263
     264/** Write multiple blocks to the device. */
     265static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt,
     266    const void *buf) {
     267
     268        int rc;
     269
     270        while (cnt > 0) {
     271                rc = gxe_bd_write_block(disk_id, ba, buf);
     272                if (rc != EOK)
     273                        return rc;
     274
     275                ++ba;
     276                --cnt;
     277                buf += block_size;
     278        }
     279
     280        return EOK;
     281}
     282
     283/** Read a block from the device. */
     284static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf)
    257285{
    258286        uint32_t status;
     287        uint64_t byte_addr;
    259288        size_t i;
    260289        uint32_t w;
    261290
     291        byte_addr = ba * block_size;
     292
    262293        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);
     294        pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
     295        pio_write_32(&dev->offset_hi, byte_addr >> 32);
    265296        pio_write_32(&dev->disk_id, disk_id);
    266297        pio_write_32(&dev->control, CTL_READ_START);
     
    272303        }
    273304
    274         for (i = 0; i < size; i++) {
     305        for (i = 0; i < block_size; i++) {
    275306                ((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]);
    276307        }
     
    280311}
    281312
    282 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
    283     const void *buf)
     313/** Write a block to the device. */
     314static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf)
    284315{
    285316        uint32_t status;
     317        uint64_t byte_addr;
    286318        size_t i;
    287319
    288         for (i = 0; i < size; i++) {
     320        byte_addr = ba * block_size;
     321
     322        fibril_mutex_lock(&dev_lock[disk_id]);
     323
     324        for (i = 0; i < block_size; i++) {
    289325                pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]);
    290326        }
    291327
    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);
     328        pio_write_32(&dev->offset_lo, (uint32_t) byte_addr);
     329        pio_write_32(&dev->offset_hi, byte_addr >> 32);
    295330        pio_write_32(&dev->disk_id, disk_id);
    296331        pio_write_32(&dev->control, CTL_WRITE_START);
Note: See TracChangeset for help on using the changeset viewer.