/trunk/uspace/srv/fs/devfs/devfs.c |
---|
0,0 → 1,127 |
/* |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup fs |
* @{ |
*/ |
/** |
* @file devfs.c |
* @brief Devices file system. |
* |
* Every device registered to device mapper is represented as a file in this |
* file system. |
*/ |
#include <stdio.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <async.h> |
#include <errno.h> |
#include <libfs.h> |
#include "devfs.h" |
#include "devfs_ops.h" |
#define NAME "devfs" |
static vfs_info_t devfs_vfs_info = { |
.name = "devfs", |
}; |
fs_reg_t devfs_reg; |
static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
if (iid) |
ipc_answer_0(iid, EOK); |
while (true) { |
ipc_call_t call; |
ipc_callid_t callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case VFS_MOUNTED: |
devfs_mounted(callid, &call); |
break; |
case VFS_MOUNT: |
devfs_mount(callid, &call); |
break; |
case VFS_LOOKUP: |
devfs_lookup(callid, &call); |
break; |
case VFS_READ: |
devfs_read(callid, &call); |
break; |
case VFS_WRITE: |
devfs_write(callid, &call); |
break; |
case VFS_TRUNCATE: |
devfs_truncate(callid, &call); |
break; |
case VFS_DESTROY: |
devfs_destroy(callid, &call); |
break; |
default: |
ipc_answer_0(callid, ENOTSUP); |
break; |
} |
} |
} |
int main(int argc, char *argv[]) |
{ |
printf(NAME ": HelenOS Device Filesystem\n"); |
if (!devfs_init()) { |
printf(NAME ": failed to initialize devfs\n"); |
return -1; |
} |
int vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); |
if (vfs_phone < EOK) { |
printf(NAME ": Unable to connect to VFS\n"); |
return -1; |
} |
int rc = fs_register(vfs_phone, &devfs_reg, &devfs_vfs_info, |
devfs_connection); |
if (rc != EOK) { |
printf(NAME ": Failed to register file system (%d)\n", rc); |
return rc; |
} |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Not reached */ |
return 0; |
} |
/** |
* @} |
*/ |
/trunk/uspace/srv/fs/devfs/devfs_ops.c |
---|
0,0 → 1,242 |
/* |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup fs |
* @{ |
*/ |
/** |
* @file devfs_ops.c |
* @brief Implementation of VFS operations for the devfs file system server. |
*/ |
#include <ipc/ipc.h> |
#include <bool.h> |
#include <errno.h> |
#include <malloc.h> |
#include <string.h> |
#include <libfs.h> |
#include "devfs.h" |
#include "devfs_ops.h" |
#define PLB_GET_CHAR(pos) (devfs_reg.plb_ro[pos % PLB_SIZE]) |
bool devfs_init(void) |
{ |
if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0) |
return false; |
return true; |
} |
void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) |
{ |
/* Accept the mount options */ |
ipc_callid_t callid; |
size_t size; |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
char *opts = malloc(size + 1); |
if (!opts) { |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
ipcarg_t retval = ipc_data_write_finalize(callid, opts, size); |
if (retval != EOK) { |
ipc_answer_0(rid, retval); |
free(opts); |
return; |
} |
free(opts); |
ipc_answer_3(rid, EOK, 0, 0, 0); |
} |
void devfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
ipc_answer_0(rid, ENOTSUP); |
} |
void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) |
{ |
ipcarg_t first = IPC_GET_ARG1(*request); |
ipcarg_t last = IPC_GET_ARG2(*request); |
dev_handle_t dev_handle = IPC_GET_ARG3(*request); |
ipcarg_t lflag = IPC_GET_ARG4(*request); |
fs_index_t index = IPC_GET_ARG5(*request); |
/* Hierarchy is flat, no altroot is supported */ |
if (index != 0) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
/* This is a read-only filesystem */ |
if ((lflag & L_CREATE) || (lflag & L_LINK) || (lflag & L_UNLINK)) { |
ipc_answer_0(rid, ENOTSUP); |
return; |
} |
/* Eat slash */ |
if (PLB_GET_CHAR(first) == '/') { |
first++; |
first %= PLB_SIZE; |
} |
if (first >= last) { |
/* Root entry */ |
if (lflag & L_DIRECTORY) |
ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0); |
else |
ipc_answer_0(rid, ENOENT); |
} else { |
if (lflag & L_FILE) { |
count_t len; |
if (last >= first) |
len = last - first + 1; |
else |
len = first + PLB_SIZE - last + 1; |
char *name = (char *) malloc(len + 1); |
if (name == NULL) { |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
count_t i; |
for (i = 0; i < len; i++) |
name[i] = PLB_GET_CHAR(first + i); |
name[len] = 0; |
dev_handle_t handle; |
if (devmap_device_get_handle(name, &handle, 0) != EOK) { |
free(name); |
ipc_answer_0(rid, ENOENT); |
return; |
} |
free(name); |
ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, handle, 0, 1); |
} else |
ipc_answer_0(rid, ENOENT); |
} |
} |
void devfs_read(ipc_callid_t rid, ipc_call_t *request) |
{ |
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); |
off_t pos = (off_t) IPC_GET_ARG3(*request); |
if (index != 0) { |
ipc_answer_1(rid, ENOENT, 0); |
return; |
} |
/* |
* Receive the read request. |
*/ |
ipc_callid_t callid; |
size_t size; |
if (!ipc_data_read_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
size_t bytes = 0; |
if (index != 0) { |
(void) ipc_data_read_finalize(callid, NULL, bytes); |
} else { |
count_t count = devmap_device_get_count(); |
dev_desc_t *desc = malloc(count * sizeof(dev_desc_t)); |
if (desc == NULL) { |
ipc_answer_0(callid, ENOENT); |
ipc_answer_1(rid, ENOENT, 0); |
return; |
} |
count_t max = devmap_device_get_devices(count, desc); |
if (pos < max) { |
ipc_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); |
} else { |
ipc_answer_0(callid, ENOENT); |
ipc_answer_1(rid, ENOENT, 0); |
return; |
} |
free(desc); |
bytes = 1; |
} |
ipc_answer_1(rid, EOK, bytes); |
} |
void devfs_write(ipc_callid_t rid, ipc_call_t *request) |
{ |
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); |
off_t pos = (off_t) IPC_GET_ARG3(*request); |
/* |
* Receive the write request. |
*/ |
ipc_callid_t callid; |
size_t size; |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
// TODO |
ipc_answer_0(callid, ENOENT); |
ipc_answer_2(rid, ENOENT, 0, 0); |
} |
void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) |
{ |
ipc_answer_0(rid, ENOTSUP); |
} |
void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) |
{ |
ipc_answer_0(rid, ENOTSUP); |
} |
/** |
* @} |
*/ |
/trunk/uspace/srv/fs/devfs/Makefile |
---|
0,0 → 1,82 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../../../lib/libc |
LIBFS_PREFIX = ../../../lib/libfs |
SOFTINT_PREFIX = ../../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I $(LIBFS_PREFIX) |
LIBS = \ |
$(LIBFS_PREFIX)/libfs.a \ |
$(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = devfs |
SOURCES = \ |
devfs.c \ |
devfs_ops.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/trunk/uspace/srv/fs/devfs/devfs.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup fs |
* @{ |
*/ |
#ifndef DEVFS_DEVFS_H_ |
#define DEVFS_DEVFS_H_ |
#include <libfs.h> |
extern fs_reg_t devfs_reg; |
#endif |
/** |
* @} |
*/ |
/trunk/uspace/srv/fs/devfs/devfs_ops.h |
---|
0,0 → 1,53 |
/* |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup fs |
* @{ |
*/ |
#ifndef DEVFS_DEVFS_OPS_H_ |
#define DEVFS_DEVFS_OPS_H_ |
#include <ipc/ipc.h> |
#include <bool.h> |
extern bool devfs_init(void); |
extern void devfs_mounted(ipc_callid_t, ipc_call_t *); |
extern void devfs_mount(ipc_callid_t, ipc_call_t *); |
extern void devfs_lookup(ipc_callid_t, ipc_call_t *); |
extern void devfs_read(ipc_callid_t, ipc_call_t *); |
extern void devfs_write(ipc_callid_t, ipc_call_t *); |
extern void devfs_truncate(ipc_callid_t, ipc_call_t *); |
extern void devfs_destroy(ipc_callid_t, ipc_call_t *); |
#endif |
/** |
* @} |
*/ |