Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4307 → Rev 4327

/branches/network/uspace/srv/kbd/include/layout.h
41,6 → 41,7
#include <sys/types.h>
 
typedef struct {
void (*reset)(void);
wchar_t (*parse_ev)(kbd_event_t *);
} layout_op_t;
 
/branches/network/uspace/srv/kbd/include/sun.h
0,0 → 1,47
/*
* 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 kbdgen generic
* @brief Sun keyboard virtual port driver.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_SUN_H_
#define KBD_SUN_H_
 
extern int ns16550_port_init(void);
extern int z8530_port_init(void);
 
#endif
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/ns16550.c
35,10 → 35,12
*/
 
#include <ipc/ipc.h>
#include <ipc/bus.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <ddi.h>
 
/* NS16550 registers */
89,7 → 91,7
static uintptr_t ns16550_physical;
static uintptr_t ns16550_kernel;
 
int kbd_port_init(void)
int ns16550_port_init(void)
{
void *vaddr;
 
100,7 → 102,7
ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &ns16550_kbd);
sysinfo_value("kbd.inr"), &ns16550_kbd);
return pio_enable((void *) ns16550_physical, 8, &vaddr);
}
 
108,6 → 110,10
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
if (cir_service)
async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
IPC_GET_METHOD(*call));
}
 
/**
/branches/network/uspace/srv/kbd/port/sun.c
0,0 → 1,66
/*
* 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 kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Sun keyboard virtual port driver.
*/
 
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <sysinfo.h>
 
/** Sun keyboard virtual port driver.
*
* This is a virtual port driver which can use
* both ns16550_port_init and z8530_port_init
* according to the information passed from the
* kernel. This is just a temporal hack.
*
*/
int kbd_port_init(void)
{
if (sysinfo_value("kbd.type.z8530")) {
if (z8530_port_init() == 0)
return 0;
}
if (sysinfo_value("kbd.type.ns16550")) {
if (ns16550_port_init() == 0)
return 0;
}
return -1;
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/z8530.c
40,6 → 40,7
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <sys/types.h>
#include <ddi.h>
 
82,7 → 83,7
 
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
int z8530_port_init(void)
{
async_set_interrupt_received(z8530_irq_handler);
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.kernel") +
/branches/network/uspace/srv/kbd/generic/kbd.c
136,6 → 136,7
if (type == KE_PRESS && (mods & KM_LCTRL) &&
key == KC_F1) {
active_layout = 0;
layout[active_layout]->reset();
return;
}
 
142,6 → 143,7
if (type == KE_PRESS && (mods & KM_LCTRL) &&
key == KC_F2) {
active_layout = 1;
layout[active_layout]->reset();
return;
}
 
148,6 → 150,7
if (type == KE_PRESS && (mods & KM_LCTRL) &&
key == KC_F3) {
active_layout = 2;
layout[active_layout]->reset();
return;
}
 
223,6 → 226,9
/* Initialize controller driver. */
if (kbd_ctl_init() != 0)
return -1;
 
/* Initialize (reset) layout. */
layout[active_layout]->reset();
/* Initialize key buffer */
keybuffer_init(&keybuffer);
/branches/network/uspace/srv/kbd/Makefile
59,9 → 59,11
port/i8042.c \
ctl/pc.c
endif
 
ifeq ($(UARCH), arm32)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
70,29 → 72,35
ctl/stty.c
endif
endif
 
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
 
ifeq ($(MACHINE), i460GX)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
 
ifeq ($(MACHINE), ski)
GENARCH_SOURCES += \
port/ski.c \
ctl/stty.c
endif
 
ifeq ($(MACHINE), msim)
GENARCH_SOURCES += \
port/msim.c \
ctl/stty.c
endif
 
ifeq ($(MACHINE), lgxemul)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
101,26 → 109,31
ctl/stty.c
endif
endif
 
ifeq ($(MACHINE), bgxemul)
GENARCH_SOURCES += \
port/gxemul.c \
ctl/stty.c
endif
 
ifeq ($(UARCH), ppc32)
GENARCH_SOURCES += \
port/dummy.c \
ctl/stty.c
endif
 
ifeq ($(UARCH), sparc64)
ifeq ($(MACHINE),serengeti)
GENARCH_SOURCES += \
port/sgcn.c \
ctl/stty.c
else
GENARCH_SOURCES += \
port/z8530.c \
ctl/sun.c
endif
ifeq ($(MACHINE),serengeti)
GENARCH_SOURCES += \
port/sgcn.c \
ctl/stty.c
else
GENARCH_SOURCES += \
port/sun.c \
port/z8530.c \
port/ns16550.c \
ctl/sun.c
endif
endif
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
/branches/network/uspace/srv/kbd/layout/us_qwerty.c
36,9 → 36,11
#include <kbd/keycode.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(kbd_event_t *ev);
 
layout_op_t us_qwerty_op = {
layout_reset,
layout_parse_ev
};
 
197,6 → 199,10
return map[key];
}
 
static void layout_reset(void)
{
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
{
wchar_t c;
/branches/network/uspace/srv/kbd/layout/cz.c
34,28 → 34,26
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <bool.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(kbd_event_t *ev);
 
enum m_state {
ms_start,
ms_hacek,
ms_carka
};
 
static enum m_state mstate;
 
layout_op_t cz_op = {
layout_reset,
layout_parse_ev
};
 
static wchar_t map_lcase[] = {
[KC_2] = L'ě',
[KC_3] = L'š',
[KC_4] = L'č',
[KC_5] = L'ř',
[KC_6] = L'ž',
[KC_7] = L'ý',
[KC_8] = L'á',
[KC_9] = L'í',
[KC_0] = L'é',
 
[KC_LBRACKET] = L'ú',
[KC_SEMICOLON] = L'ů',
 
[KC_Q] = 'q',
[KC_W] = 'w',
[KC_E] = 'e',
87,19 → 85,6
};
 
static wchar_t map_ucase[] = {
[KC_2] = L'Ě',
[KC_3] = L'Š',
[KC_4] = L'Č',
[KC_5] = L'Ř',
[KC_6] = L'Ž',
[KC_7] = L'Ý',
[KC_8] = L'Á',
[KC_9] = L'Í',
[KC_0] = L'É',
 
[KC_LBRACKET] = L'Ú',
[KC_SEMICOLON] = L'Ů',
 
[KC_Q] = 'Q',
[KC_W] = 'W',
[KC_E] = 'E',
172,6 → 157,36
[KC_SLASH] = '_',
};
 
static wchar_t map_ns_nocaps[] = {
[KC_2] = L'ě',
[KC_3] = L'š',
[KC_4] = L'č',
[KC_5] = L'ř',
[KC_6] = L'ž',
[KC_7] = L'ý',
[KC_8] = L'á',
[KC_9] = L'í',
[KC_0] = L'é',
 
[KC_LBRACKET] = L'ú',
[KC_SEMICOLON] = L'ů'
};
 
static wchar_t map_ns_caps[] = {
[KC_2] = L'Ě',
[KC_3] = L'Š',
[KC_4] = L'Č',
[KC_5] = L'Ř',
[KC_6] = L'Ž',
[KC_7] = L'Ý',
[KC_8] = L'Á',
[KC_9] = L'Í',
[KC_0] = L'É',
 
[KC_LBRACKET] = L'Ú',
[KC_SEMICOLON] = L'Ů'
};
 
static wchar_t map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
200,6 → 215,56
[KC_NPERIOD] = '.'
};
 
static wchar_t map_hacek_lcase[] = {
[KC_E] = L'ě',
[KC_R] = L'ř',
[KC_T] = L'ť',
[KC_Y] = L'ž',
[KC_U] = L'ů',
 
[KC_S] = L'š',
[KC_D] = L'ď',
 
[KC_C] = L'č',
[KC_N] = L'ň'
};
 
static wchar_t map_hacek_ucase[] = {
[KC_E] = L'Ě',
[KC_R] = L'Ř',
[KC_T] = L'Ť',
[KC_Y] = L'Ž',
[KC_U] = L'Ů',
 
[KC_S] = L'Š',
[KC_D] = L'Ď',
 
[KC_C] = L'Č',
[KC_N] = L'Ň'
};
 
static wchar_t map_carka_lcase[] = {
[KC_E] = L'é',
[KC_U] = L'ú',
[KC_I] = L'í',
[KC_O] = L'ó',
 
[KC_A] = L'á',
 
[KC_Z] = L'ý',
};
 
static wchar_t map_carka_ucase[] = {
[KC_E] = L'É',
[KC_U] = L'Ú',
[KC_I] = L'Í',
[KC_O] = L'Ó',
 
[KC_A] = L'Á',
 
[KC_Z] = L'Ý',
};
 
static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
{
if (key >= map_length)
207,18 → 272,73
return map[key];
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
static wchar_t parse_ms_hacek(kbd_event_t *ev)
{
wchar_t c;
 
mstate = ms_start;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
 
return c;
}
 
static wchar_t parse_ms_carka(kbd_event_t *ev)
{
wchar_t c;
 
mstate = ms_start;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
 
return c;
}
 
static wchar_t parse_ms_start(kbd_event_t *ev)
{
wchar_t c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (ev->key == KC_EQUALS) {
if ((ev->mods & KM_SHIFT) != 0)
mstate = ms_hacek;
else
mstate = ms_carka;
 
return 0;
}
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) == 0) {
if ((ev->mods & KM_CAPS_LOCK) != 0)
c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
else
c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
 
if (c != 0)
return c;
}
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
else
243,6 → 363,41
return c;
}
 
static bool key_is_mod(unsigned key)
{
switch (key) {
case KC_LSHIFT:
case KC_RSHIFT:
case KC_LALT:
case KC_RALT:
case KC_LCTRL:
case KC_RCTRL:
return true;
default:
return false;
}
}
 
static void layout_reset(void)
{
mstate = ms_start;
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
{
if (ev->type != KE_PRESS)
return '\0';
 
if (key_is_mod(ev->key))
return '\0';
 
switch (mstate) {
case ms_start: return parse_ms_start(ev);
case ms_hacek: return parse_ms_hacek(ev);
case ms_carka: return parse_ms_carka(ev);
}
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/layout/us_dvorak.c
36,9 → 36,11
#include <kbd/keycode.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(kbd_event_t *ev);
 
layout_op_t us_dvorak_op = {
layout_reset,
layout_parse_ev
};
 
203,6 → 205,10
return map[key];
}
 
static void layout_reset(void)
{
}
 
static wchar_t layout_parse_ev(kbd_event_t *ev)
{
wchar_t c;
/branches/network/uspace/srv/console/console.c
141,6 → 141,16
async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
}
 
static void screen_yield(void)
{
ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD);
}
 
static void screen_reclaim(void)
{
ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
}
 
static void set_style(int style)
{
async_msg_1(fb_info.phone, FB_SET_STYLE, style);
330,7 → 340,9
async_serialize_start();
curs_hide_sync();
gcons_in_kernel();
screen_yield();
async_serialize_end();
 
if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
prev_console = active_console;
342,8 → 354,10
if (newcons != KERNEL_CONSOLE) {
async_serialize_start();
if (active_console == KERNEL_CONSOLE)
if (active_console == KERNEL_CONSOLE) {
screen_reclaim();
gcons_redraw_console();
}
active_console = newcons;
gcons_change_console(newcons);
512,6 → 526,8
gcons_notify_connect(consnum);
conn->client_phone = IPC_GET_ARG5(*icall);
screenbuffer_clear(&conn->screenbuffer);
if (consnum == active_console)
clrscr();
/* Accept the connection */
ipc_answer_0(iid, EOK);
/branches/network/uspace/srv/rd/rd.c
196,7 → 196,7
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 
retval = ipc_data_write_start(phone, (char *) name, strlen(name) + 1);
retval = ipc_data_write_start(phone, (char *) name, str_size(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
219,7 → 219,8
 
req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
 
retval = ipc_data_write_start(driver_phone, (char *) name, strlen(name) + 1);
retval = ipc_data_write_start(driver_phone, (char *) name,
str_size(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
/branches/network/uspace/srv/loader/main.c
150,11 → 150,11
static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t buf_len, arg_len;
size_t buf_size, arg_size;
char *p;
int n;
if (!ipc_data_write_receive(&callid, &buf_len)) {
if (!ipc_data_write_receive(&callid, &buf_size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
170,7 → 170,7
argv = NULL;
}
arg_buf = malloc(buf_len + 1);
arg_buf = malloc(buf_size + 1);
if (!arg_buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
177,9 → 177,9
return;
}
ipc_data_write_finalize(callid, arg_buf, buf_len);
ipc_data_write_finalize(callid, arg_buf, buf_size);
arg_buf[buf_len] = '\0';
arg_buf[buf_size] = '\0';
/*
* Count number of arguments
186,9 → 186,9
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
arg_len = strlen(p);
p = p + arg_len + 1;
while (p < arg_buf + buf_size) {
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
206,11 → 206,11
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
while (p < arg_buf + buf_size) {
argv[n] = p;
arg_len = strlen(p);
p = p + arg_len + 1;
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
275,7 → 275,7
const char *cp;
/* Set the task name. */
cp = strrchr(pathname, '/');
cp = str_rchr(pathname, '/');
cp = (cp == NULL) ? pathname : (cp + 1);
task_set_name(cp);
/branches/network/uspace/srv/net/net/net_standalone.c
34,7 → 34,7
*
*/
 
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
 
91,7 → 91,7
int read_netif_configuration( char * name, netif_ref netif ){
ERROR_DECLARE;
 
if( strncmp( name, "lo", 2 ) == 0 ){
if( str_lcmp( name, "lo", 2 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
98,7 → 98,7
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ));
}else if( strncmp( name, "ne2k", 4 ) == 0 ){
}else if( str_lcmp( name, "ne2k", 4 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", "eth0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ));
// standalone ethernet
/branches/network/uspace/srv/net/net/net_bundle.c
123,7 → 123,7
int read_netif_configuration( char * name, netif_ref netif ){
ERROR_DECLARE;
 
if( strncmp( name, "lo", 2 ) == 0 ){
if( str_lcmp( name, "lo", 2 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
130,7 → 130,7
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ));
}else if( strncmp( name, "ne2k", 4 ) == 0 ){
}else if( str_lcmp( name, "ne2k", 4 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", "eth0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ));
// ethernet bundled in dp8390
/branches/network/uspace/srv/net/il/arp/arp.c
40,6 → 40,7
#include <mem.h>
#include <rwlock.h>
#include <stdio.h>
#include <string.h>
#include <task.h>
 
#include <ipc/ipc.h>
434,7 → 435,7
if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
return EINVAL;
}
if( ! strncmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
// not already upadted?
if( ! hw_source ){
hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length ));
/branches/network/uspace/srv/net/il/ip/ip.c
36,6 → 36,7
#include <async.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
112,7 → 113,7
}else{
ip_netif->ipv = DEFAULT_IPV;
}
ip_netif->dhcp = ! strncmp( configuration[ 1 ].value, "dhcp", 4 );
ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", 4 );
if( ip_netif->dhcp ){
// TODO dhcp
net_free_settings( configuration, data );
254,7 → 255,10
if( netif->arp ){
address.value = ( char * ) & netif->gateway;
address.length = CONVERT_SIZE( in_addr_t, char, 1 );
ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
sleep( 2 );
ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
}
printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
free( translation );
free( data );
/branches/network/uspace/srv/net/netif/dp8390/dp8390.c
205,6 → 205,58
}
 
/*===========================================================================*
* dp8390_dump *
*===========================================================================*/
void dp8390_dump( dpeth_t * dep )
{
// dpeth_t *dep;
int /*i,*/ isr;
 
// printf("\n");
// for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
// {
#if XXX
if (dep->de_mode == DEM_DISABLED)
printf("dp8390 port %d is disabled\n", i);
else if (dep->de_mode == DEM_SINK)
printf("dp8390 port %d is in sink mode\n", i);
#endif
 
if (dep->de_mode != DEM_ENABLED)
// continue;
return;
 
// printf("dp8390 statistics of port %d:\n", i);
 
printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
 
printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
 
printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
 
printf("collision :%8ld\t", dep->de_stat.ets_collision);
printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
 
printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
 
printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
 
isr= inb_reg0(dep, DP_ISR);
printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
inb_reg0(dep, DP_ISR), dep->de_flags);
// }
}
 
/*===========================================================================*
* do_init *
*===========================================================================*/
int do_init( dpeth_t * dep, int mode ){
588,10 → 640,11
/*===========================================================================*
* dp_check_ints *
*===========================================================================*/
void dp_check_ints(dep)
void dp_check_ints(dep, isr)
dpeth_t *dep;
int isr;
{
int isr, tsr;
int /*isr,*/ tsr;
int size, sendq_tail;
 
if (!(dep->de_flags & DEF_ENABLED))
599,7 → 652,7
 
for(;;)
{
isr = inb_reg0(dep, DP_ISR);
// isr = inb_reg0(dep, DP_ISR);
if (!isr)
break;
outb_reg0(dep, DP_ISR, isr);
720,6 → 773,7
dep->de_flags |= DEF_STOPPED;
break;
}
isr = inb_reg0(dep, DP_ISR);
}
if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
(DEF_READING|DEF_STOPPED))
1504,8 → 1558,8
if (r < 0)
panic("", "dp8390: send failed:", r);
dep->de_read_s = 0;
*/ dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
*/ dep->de_read_s = 0;
dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
}
 
/*===========================================================================*
/branches/network/uspace/srv/net/netif/dp8390/dp8390_drv.h
40,9 → 40,10
 
_PROTOTYPE( int do_init, (dpeth_t *dep, int mode) );
_PROTOTYPE( void do_stop, (dpeth_t *dep) );
_PROTOTYPE( void dp_check_ints, (dpeth_t *dep) );
_PROTOTYPE( void dp_check_ints, (dpeth_t *dep, int isr) );
int do_probe( dpeth_t * dep );
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int );
void dp8390_dump( dpeth_t * dep );
 
#endif
 
/branches/network/uspace/srv/net/netif/dp8390/dp8390_module.c
34,6 → 34,7
*/
 
#include <assert.h>
#include <async.h>
#include <ddi.h>
#include <errno.h>
#include <malloc.h>
70,14 → 71,14
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.value = 1,
.srcarg = 2
},
{ .cmd = CMD_PIO_WRITE_8,
/* { .cmd = CMD_PIO_WRITE_8,
.addr = NULL,
.srcarg = 2
.value = 0
},
{
*/ {
.cmd = CMD_ACCEPT
}
};
141,7 → 142,6
 
void irq_handler( ipc_callid_t iid, ipc_call_t * call )
{
// int irq;
device_ref device;
dpeth_t * dep;
packet_t received;
148,35 → 148,31
device_id_t device_id;
int phone;
 
// async_serialize_start();
device_id = IRQ_GET_DEVICE( call );
// printf( "device %d - irq %x\n", device_id, IPC_GET_ISR( call ));
rwlock_write_lock( & netif_globals.lock );
if( find_device( device_id, & device ) != EOK ){
rwlock_write_unlock( & netif_globals.lock );
// async_serialize_end()
return;
}
dep = ( dpeth_t * ) device->specific;
// printf( "dev %d, irq %x\n\n", device->device_id, IPC_GET_ISR( call ));
if ( dep->de_mode != DEM_ENABLED){
// continue;
rwlock_write_unlock( & netif_globals.lock );
// async_serialize_end()
return;
}
assert( dep->de_flags & DEF_ENABLED);
// irq= dep.de_irq;
// assert(irq >= 0 && irq < NR_IRQ_VECTORS);
// if ( dep->de_int_pending || 1)
// {
dep->de_int_pending= 0;
dp_check_ints( dep );
// do_int(dep);
/* r= sys_irqenable(&dep->de_hook);
if (r != OK)
{
panic("DP8390",
"unable enable interrupts", r);
}
*/// }
dep->de_int_pending= 0;
printf( "I%d -%d\n", device_id, IPC_GET_ISR( call ));
/* putchar( 'I' );
putchar( '0' + device_id );
putchar( '-' );
putchar( '0' + IPC_GET_ISR( call ) / 100 );
putchar( '0' + ( IPC_GET_ISR( call ) % 100 ) / 10 );
putchar( '0' + IPC_GET_ISR( call ) % 10 );
putchar( '\n' );
*/ dp_check_ints( dep, IPC_GET_ISR( call ));
if( dep->received_queue ){
received = dep->received_queue;
phone = device->nil_phone;
187,6 → 183,7
rwlock_write_unlock( & netif_globals.lock );
}
ipc_answer_0( iid, EOK );
// async_serialize_end()
}
 
int netif_probe_auto_message( void ){
236,12 → 233,13
dpeth_t * dep;
packet_t next;
 
ERROR_PROPAGATE( find_device( device_id, & device ));
dep = ( dpeth_t * ) device->specific;
// TODO remove debug dump:
uint8_t * data;
data = packet_get_data( packet );
printf( "Sending packet:\n\tid\t= %d\n\tlength\t= %d\n\tdata\t= %.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX\n\t\t%.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX\n", packet_get_id( packet ), packet_get_data_length( packet ), data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ], data[ 8 ], data[ 9 ], data[ 10 ], data[ 11 ], data[ 12 ], data[ 13 ], data[ 14 ], data[ 15 ], data[ 16 ], data[ 17 ], data[ 18 ], data[ 19 ], data[ 20 ], data[ 21 ], data[ 22 ], data[ 23 ], data[ 24 ], data[ 25 ], data[ 26 ], data[ 27 ], data[ 28 ], data[ 29 ], data[ 30 ], data[ 31 ], data[ 32 ], data[ 33 ], data[ 34 ], data[ 35 ], data[ 36 ], data[ 37 ], data[ 38 ], data[ 39 ], data[ 40 ], data[ 41 ], data[ 42 ], data[ 43 ], data[ 44 ], data[ 45 ], data[ 46 ], data[ 47 ], data[ 48 ], data[ 49 ], data[ 50 ], data[ 51 ], data[ 52 ], data[ 53 ], data[ 54 ], data[ 55 ], data[ 56 ], data[ 57 ], data[ 58 ], data[ 59 ] );
 
ERROR_PROPAGATE( find_device( device_id, & device ));
dep = ( dpeth_t * ) device->specific;
// process packet queue
do{
next = pq_detach( packet );
250,6 → 248,7
}
packet = next;
}while( packet );
dp8390_dump( dep );
return EOK;
}
 
/branches/network/uspace/srv/fb/serial_console.c
274,9 → 274,6
serial_goto(y, x);
 
for (i = 0; i < w; i++) {
unsigned int col = x + i;
unsigned int row = y + j;
 
field = &data[j * w + i];
 
a1 = &field->attrs;
304,12 → 301,9
 
wchar_t c;
int col, row, w, h;
int fgcolor;
int bgcolor;
int flags;
int style;
int i;
 
attrs_t cur_attr;
if (client_connected) {
ipc_answer_0(iid, ELIMIT);
318,6 → 312,9
client_connected = 1;
ipc_answer_0(iid, EOK);
 
cur_attr.t = at_style;
cur_attr.a.s.style = STYLE_NORMAL;
/* Clear the terminal, set scrolling region
to 0 - height rows. */
388,23 → 385,28
retval = 0;
break;
case FB_SET_STYLE:
style = IPC_GET_ARG1(call);
serial_set_style(style);
cur_attr.t = at_style;
cur_attr.a.s.style = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
serial_set_attrs(&cur_attr);
 
retval = 0;
break;
case FB_SET_COLOR:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
flags = IPC_GET_ARG3(call);
cur_attr.t = at_idx;
cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
cur_attr.a.i.flags = IPC_GET_ARG3(call);
serial_set_attrs(&cur_attr);
 
serial_set_idx(fgcolor, bgcolor, flags);
retval = 0;
break;
case FB_SET_RGB_COLOR:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
cur_attr.t = at_rgb;
cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
serial_set_attrs(&cur_attr);
 
serial_set_rgb(fgcolor, bgcolor);
retval = 0;
break;
case FB_SCROLL:
424,6 → 426,18
serial_cursor_disable();
retval = 0;
break;
case FB_SCREEN_YIELD:
serial_sgr(SGR_RESET);
serial_puts("\033[2J");
serial_goto(0, 0);
serial_cursor_enable();
retval = 0;
break;
case FB_SCREEN_RECLAIM:
serial_clrscr();
serial_set_attrs(&cur_attr);
retval = 0;
break;
default:
retval = ENOENT;
}
/branches/network/uspace/srv/fb/fb.c
30,7 → 30,7
 
/**
* @defgroup fb Graphical framebuffer
* @brief HelenOS graphical framebuffer.
* @brief HelenOS graphical framebuffer.
* @ingroup fbs
* @{
*/
68,7 → 68,7
#define DEFAULT_BGCOLOR 0xf0f0f0
#define DEFAULT_FGCOLOR 0x000000
 
#define GLYPH_UNAVAIL '?'
#define GLYPH_UNAVAIL '?'
 
#define MAX_ANIM_LEN 8
#define MAX_ANIMATIONS 4
78,6 → 78,9
/** Function to render a pixel from a RGB value. */
typedef void (*rgb_conv_t)(void *, uint32_t);
 
/** Function to render a bit mask. */
typedef void (*mask_conv_t)(void *, bool);
 
/** Function to draw a glyph. */
typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
93,11 → 96,12
unsigned int pixelbytes;
unsigned int glyphbytes;
 
/** Pre-rendered mask for rendering glyphs. Specific for the visual. */
uint8_t *glyphs;
rgb_conv_t rgb_conv;
mask_conv_t mask_conv;
} screen;
 
/** Backbuffer character cell. */
121,12 → 125,12
/*
* Style and glyphs for text printing
*/
 
/** Current attributes. */
attr_rgb_t attr;
 
uint8_t *bgpixel;
 
/**
* Glyph drawing function for this viewport. Different viewports
* might use different drawing functions depending on whether their
170,23 → 174,23
static bool client_connected = false; /**< Allow only 1 connection */
 
static uint32_t color_table[16] = {
[COLOR_BLACK] = 0x000000,
[COLOR_BLUE] = 0x0000f0,
[COLOR_GREEN] = 0x00f000,
[COLOR_CYAN] = 0x00f0f0,
[COLOR_RED] = 0xf00000,
[COLOR_MAGENTA] = 0xf000f0,
[COLOR_YELLOW] = 0xf0f000,
[COLOR_WHITE] = 0xf0f0f0,
 
[8 + COLOR_BLACK] = 0x000000,
[8 + COLOR_BLUE] = 0x0000ff,
[8 + COLOR_GREEN] = 0x00ff00,
[8 + COLOR_CYAN] = 0x00ffff,
[8 + COLOR_RED] = 0xff0000,
[8 + COLOR_MAGENTA] = 0xff00ff,
[8 + COLOR_YELLOW] = 0xffff00,
[8 + COLOR_WHITE] = 0xffffff,
[COLOR_BLACK] = 0x000000,
[COLOR_BLUE] = 0x0000f0,
[COLOR_GREEN] = 0x00f000,
[COLOR_CYAN] = 0x00f0f0,
[COLOR_RED] = 0xf00000,
[COLOR_MAGENTA] = 0xf000f0,
[COLOR_YELLOW] = 0xf0f000,
[COLOR_WHITE] = 0xf0f0f0,
[8 + COLOR_BLACK] = 0x000000,
[8 + COLOR_BLUE] = 0x0000ff,
[8 + COLOR_GREEN] = 0x00ff00,
[8 + COLOR_CYAN] = 0x00ffff,
[8 + COLOR_RED] = 0xff0000,
[8 + COLOR_MAGENTA] = 0xff00ff,
[8 + COLOR_YELLOW] = 0xffff00,
[8 + COLOR_WHITE] = 0xffffff,
};
 
static int rgb_from_attr(attr_rgb_t *rgb, const attrs_t *a);
226,10 → 230,15
*/
static void rgb_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = rgb & 0xffffff;
*((uint32_t *) dst) = rgb & 0x00ffffff;
}
 
static void mask_0888(void *dst, bool mask)
{
*((uint32_t *) dst) = (mask ? 0x00ffffff : 0);
}
 
 
/** ABGR 8:8:8:8 conversion
*
*/
250,7 → 259,20
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
static void mask_888(void *dst, bool mask)
{
if (mask) {
((uint8_t *) dst)[0] = 0xff;
((uint8_t *) dst)[1] = 0xff;
((uint8_t *) dst)[2] = 0xff;
} else {
((uint8_t *) dst)[0] = 0;
((uint8_t *) dst)[1] = 0;
((uint8_t *) dst)[2] = 0;
}
}
 
 
/** BGR 8:8:8 conversion
*
*/
271,7 → 293,12
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
}
 
static void mask_555(void *dst, bool mask)
{
*((uint16_t *) dst) = (mask ? 0x7fff : 0);
}
 
 
/** RGB 5:6:5 conversion
*
*/
281,7 → 308,12
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
}
 
static void mask_565(void *dst, bool mask)
{
*((uint16_t *) dst) = (mask ? 0xffff : 0);
}
 
 
/** RGB 3:2:3
*
*/
291,34 → 323,44
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
}
 
static void mask_323(void *dst, bool mask)
{
*((uint8_t *) dst) = (mask ? 0xff : 0);
}
 
/** Draw a filled rectangle.
*
* @note Need real implementation that does not access VRAM twice.
*
*/
static void draw_filled_rect(unsigned int x0, unsigned int y0, unsigned int x1,
unsigned int y1, uint32_t color)
{
unsigned int x, y;
unsigned int x;
unsigned int y;
unsigned int copy_bytes;
 
uint8_t *sp, *dp;
uint8_t *sp;
uint8_t *dp;
uint8_t cbuf[4];
 
if (y0 >= y1 || x0 >= x1) return;
if ((y0 >= y1) || (x0 >= x1))
return;
screen.rgb_conv(cbuf, color);
 
sp = &screen.fb_addr[FB_POS(x0, y0)];
dp = sp;
 
/* Draw the first line. */
for (x = x0; x < x1; x++) {
memcpy(dp, cbuf, screen.pixelbytes);
dp += screen.pixelbytes;
}
 
dp = sp + screen.scanline;
copy_bytes = (x1 - x0) * screen.pixelbytes;
 
/* Draw the remaining lines by copying. */
for (y = y0 + 1; y < y1; y++) {
memcpy(dp, sp, copy_bytes);
333,14 → 375,15
*/
static void vport_redraw(viewport_t *vport)
{
unsigned int row, col;
 
unsigned int row;
unsigned int col;
for (row = 0; row < vport->rows; row++) {
for (col = 0; col < vport->cols; col++) {
draw_vp_glyph(vport, false, col, row);
}
}
 
if (COL2X(vport->cols) < vport->width) {
draw_filled_rect(
vport->x + COL2X(vport->cols), vport->y,
347,7 → 390,7
vport->x + vport->width, vport->y + vport->height,
vport->attr.bg_color);
}
 
if (ROW2Y(vport->rows) < vport->height) {
draw_filled_rect(
vport->x, vport->y + ROW2Y(vport->rows),
359,8 → 402,8
static void backbuf_clear(bb_cell_t *backbuf, size_t len, uint32_t fg_color,
uint32_t bg_color)
{
unsigned i;
 
size_t i;
for (i = 0; i < len; i++) {
backbuf[i].glyph = 0;
backbuf[i].fg_color = fg_color;
388,17 → 431,20
*/
static void vport_scroll(viewport_t *vport, int lines)
{
unsigned int row, col;
unsigned int x, y;
unsigned int row;
unsigned int col;
unsigned int x;
unsigned int y;
uint32_t glyph;
uint32_t fg_color;
uint32_t bg_color;
bb_cell_t *bbp, *xbp;
 
bb_cell_t *bbp;
bb_cell_t *xbp;
/*
* Redraw.
*/
 
y = vport->y;
for (row = 0; row < vport->rows; row++) {
x = vport->x;
406,14 → 452,14
if ((row + lines >= 0) && (row + lines < vport->rows)) {
xbp = &vport->backbuf[BB_POS(vport, col, row + lines)];
bbp = &vport->backbuf[BB_POS(vport, col, row)];
 
glyph = xbp->glyph;
fg_color = xbp->fg_color;
bg_color = xbp->bg_color;
 
if (bbp->glyph == glyph &&
bbp->fg_color == xbp->fg_color &&
bbp->bg_color == xbp->bg_color) {
if ((bbp->glyph == glyph)
&& (bbp->fg_color == xbp->fg_color)
&& (bbp->bg_color == xbp->bg_color)) {
x += FONT_WIDTH;
continue;
}
422,7 → 468,7
fg_color = vport->attr.fg_color;
bg_color = vport->attr.bg_color;
}
 
(*vport->dglyph)(x, y, false, screen.glyphs, glyph,
fg_color, bg_color);
x += FONT_WIDTH;
429,11 → 475,11
}
y += FONT_SCANLINES;
}
 
/*
* Scroll backbuffer.
*/
 
if (lines > 0) {
memmove(vport->backbuf, vport->backbuf + vport->cols * lines,
vport->cols * (vport->rows - lines) * sizeof(bb_cell_t));
451,31 → 497,29
*
* Convert glyphs from device independent font
* description to current visual representation.
*
*/
static void render_glyphs(void)
{
unsigned int glyph;
 
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
unsigned int y;
 
for (y = 0; y < FONT_SCANLINES; y++) {
unsigned int x;
 
for (x = 0; x < FONT_WIDTH; x++) {
screen.rgb_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x)))
? 0xffffff : 0x000000);
 
screen.rgb_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x)))
? 0x000000 : 0xffffff);
screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x))) ? true : false);
screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x))) ? false : true);
}
}
}
}
 
 
/** Create new viewport
*
* @param x Origin of the viewport (x).
495,6 → 539,7
if (!viewports[i].initialized)
break;
}
if (i == MAX_VIEWPORTS)
return ELIMIT;
512,7 → 557,7
free(backbuf);
return ENOMEM;
}
 
backbuf_clear(backbuf, cols * rows, DEFAULT_FGCOLOR, DEFAULT_BGCOLOR);
memset(bgpixel, 0, screen.pixelbytes);
528,24 → 573,23
viewports[i].attr.fg_color = DEFAULT_FGCOLOR;
viewports[i].bgpixel = bgpixel;
 
/*
* Conditions necessary to select aligned version:
* Conditions necessary to select aligned version:
* - word size is divisible by pixelbytes
* - cell scanline size is divisible by word size
* - cell scanlines are word-aligned
*
* - word size is divisible by pixelbytes
* - cell scanline size is divisible by word size
* - cell scanlines are word-aligned
*/
if ((word_size % screen.pixelbytes) == 0 &&
(FONT_WIDTH * screen.pixelbytes) % word_size == 0 &&
(x * screen.pixelbytes) % word_size == 0 &&
screen.scanline % word_size == 0) {
 
if (((word_size % screen.pixelbytes) == 0)
&& ((FONT_WIDTH * screen.pixelbytes) % word_size == 0)
&& ((x * screen.pixelbytes) % word_size == 0)
&& (screen.scanline % word_size == 0)) {
viewports[i].dglyph = draw_glyph_aligned;
} else {
viewports[i].dglyph = draw_glyph_fallback;
}
 
viewports[i].cur_col = 0;
viewports[i].cur_row = 0;
viewports[i].cursor_active = false;
574,45 → 618,53
static bool screen_init(void *addr, unsigned int xres, unsigned int yres,
unsigned int scan, unsigned int visual)
{
unsigned int glyphsize;
uint8_t *glyphs;
switch (visual) {
case VISUAL_INDIRECT_8:
screen.rgb_conv = rgb_323;
screen.mask_conv = mask_323;
screen.pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
screen.rgb_conv = rgb_555;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
screen.rgb_conv = rgb_565;
screen.mask_conv = mask_565;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 3;
break;
case VISUAL_BGR_8_8_8:
screen.rgb_conv = bgr_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
screen.rgb_conv = rgb_0888;
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
case VISUAL_BGR_0_8_8_8:
screen.rgb_conv = bgr_0888;
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
default:
return false;
}
 
screen.fb_addr = (unsigned char *) addr;
screen.xres = xres;
screen.yres = yres;
620,15 → 672,15
screen.glyphscanline = FONT_WIDTH * screen.pixelbytes;
screen.glyphbytes = screen.glyphscanline * FONT_SCANLINES;
 
glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;
glyphs = (uint8_t *) malloc(glyphsize);
size_t glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;
uint8_t *glyphs = (uint8_t *) malloc(glyphsize);
if (!glyphs)
return false;
memset(glyphs, 0, glyphsize);
screen.glyphs = glyphs;
 
render_glyphs();
/* Create first viewport */
651,46 → 703,47
* making it very fast. Most notably this version is not applicable at 24 bits
* per pixel.
*
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
*
*/
static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color)
{
unsigned int i, yd;
unsigned long fg_buf, bg_buf;
unsigned long *maskp, *dp;
unsigned int i;
unsigned int yd;
unsigned long fg_buf;
unsigned long bg_buf;
unsigned long mask;
unsigned int ww, d_add;
 
/*
* Prepare a pair of words, one filled with foreground-color
* pattern and the other filled with background-color pattern.
*/
for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) {
screen.rgb_conv(&((uint8_t *)&fg_buf)[i * screen.pixelbytes],
screen.rgb_conv(&((uint8_t *) &fg_buf)[i * screen.pixelbytes],
fg_color);
screen.rgb_conv(&((uint8_t *)&bg_buf)[i * screen.pixelbytes],
screen.rgb_conv(&((uint8_t *) &bg_buf)[i * screen.pixelbytes],
bg_color);
}
 
/* Pointer to the current position in the mask. */
maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)];
 
unsigned long *maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)];
/* Pointer to the current position on the screen. */
dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)];
 
unsigned long *dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)];
/* Width of the character cell in words. */
ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long);
 
unsigned int ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long);
/* Offset to add when moving to another screen scanline. */
d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
 
unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
/*
* Now process the cell scanline, combining foreground
700,7 → 753,7
mask = *maskp++;
*dp++ = (fg_buf & mask) | (bg_buf & ~mask);
}
 
/* Move to the beginning of the next scanline of the cell. */
dp = (unsigned long *) ((uint8_t *) dp + d_add);
}
711,23 → 764,26
* This version does not make use of the pre-rendered mask, it uses
* the font bitmap directly. It works always, but it is slower.
*
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
*
*/
void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color)
{
unsigned int i, j, yd;
uint8_t fg_buf[4], bg_buf[4];
uint8_t *dp, *sp;
unsigned int d_add;
unsigned int i;
unsigned int j;
unsigned int yd;
uint8_t fg_buf[4];
uint8_t bg_buf[4];
uint8_t *sp;
uint8_t b;
 
/* Pre-render 1x the foreground and background color pixels. */
if (cursor) {
screen.rgb_conv(fg_buf, bg_color);
736,26 → 792,26
screen.rgb_conv(fg_buf, fg_color);
screen.rgb_conv(bg_buf, bg_color);
}
 
/* Pointer to the current position on the screen. */
dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)];
 
uint8_t *dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)];
/* Offset to add when moving to another screen scanline. */
d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
 
unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
/* Byte containing bits of the glyph scanline. */
b = fb_font[glyph][yd];
 
for (i = 0; i < FONT_WIDTH; i++) {
/* Choose color based on the current bit. */
sp = (b & 0x80) ? fg_buf : bg_buf;
 
/* Copy the pixel. */
for (j = 0; j < screen.pixelbytes; j++) {
*dp++ = *sp++;
}
 
/* Move to the next bit. */
b = b << 1;
}
765,7 → 821,7
}
}
 
/** Draw glyph at specified position in viewport.
/** Draw glyph at specified position in viewport.
*
* @param vport Viewport identification
* @param cursor Draw glyph with cursor
778,15 → 834,11
{
unsigned int x = vport->x + COL2X(col);
unsigned int y = vport->y + ROW2Y(row);
 
uint32_t glyph;
uint32_t fg_color;
uint32_t bg_color;
glyph = vport->backbuf[BB_POS(vport, col, row)].glyph;
fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color;
bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color;
 
uint32_t glyph = vport->backbuf[BB_POS(vport, col, row)].glyph;
uint32_t fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color;
uint32_t bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color;
(*vport->dglyph)(x, y, cursor, screen.glyphs, glyph,
fg_color, bg_color);
}
839,17 → 891,17
static void draw_char(viewport_t *vport, wchar_t c, unsigned int col, unsigned int row)
{
bb_cell_t *bbp;
 
/* Do not hide cursor if we are going to overwrite it */
if ((vport->cursor_active) && (vport->cursor_shown) &&
((vport->cur_col != col) || (vport->cur_row != row)))
cursor_hide(vport);
 
bbp = &vport->backbuf[BB_POS(vport, col, row)];
bbp->glyph = fb_font_glyph(c);
bbp->fg_color = vport->attr.fg_color;
bbp->bg_color = vport->attr.bg_color;
 
draw_vp_glyph(vport, false, col, row);
vport->cur_col = col;
870,33 → 922,35
*
* @param vport Viewport id
* @param data Text data.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
*
*/
static void draw_text_data(viewport_t *vport, keyfield_t *data, unsigned int x,
unsigned int y, unsigned int w, unsigned int h)
{
unsigned int i, j;
unsigned int i;
unsigned int j;
bb_cell_t *bbp;
attrs_t *a;
attr_rgb_t rgb;
 
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
unsigned int col = x + i;
unsigned int row = y + j;
 
bbp = &vport->backbuf[BB_POS(vport, col, row)];
 
a = &data[j * w + i].attrs;
rgb_from_attr(&rgb, a);
 
bbp->glyph = fb_font_glyph(data[j * w + i].character);
bbp->fg_color = rgb.fg_color;
bbp->bg_color = rgb.bg_color;
 
draw_vp_glyph(vport, false, col, row);
}
}
1192,7 → 1246,7
counts = (counts + 1) % 8;
if (counts)
return;
 
for (i = 0; i < MAX_ANIMATIONS; i++) {
if ((!animations[i].animlen) || (!animations[i].initialized) ||
(!animations[i].enabled))
1659,6 → 1713,10
mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
retval = EOK;
break;
case FB_SCREEN_YIELD:
case FB_SCREEN_RECLAIM:
retval = EOK;
break;
default:
retval = ENOENT;
}
/branches/network/uspace/srv/fb/ega.c
391,7 → 391,10
}
retval = 0;
break;
 
case FB_SCREEN_YIELD:
case FB_SCREEN_RECLAIM:
retval = EOK;
break;
default:
retval = EINVAL;
}
/branches/network/uspace/srv/fs/tmpfs/tmpfs.h
52,6 → 52,7
 
typedef struct tmpfs_dentry {
fs_index_t index; /**< TMPFS node index. */
dev_handle_t dev_handle;/**< Device handle. */
link_t dh_link; /**< Dentries hash table link. */
struct tmpfs_dentry *sibling;
struct tmpfs_dentry *child;
66,6 → 67,8
 
extern libfs_ops_t tmpfs_libfs_ops;
 
extern bool tmpfs_init(void);
 
extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
/branches/network/uspace/srv/fs/tmpfs/tmpfs_dump.c
177,7 → 177,7
goto error;
tag[5] = 0;
if (strcmp(tag, "TMPFS") != 0)
if (str_cmp(tag, "TMPFS") != 0)
goto error;
if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos,
/branches/network/uspace/srv/fs/tmpfs/tmpfs.c
127,7 → 127,12
int main(int argc, char **argv)
{
printf(NAME ": HelenOS TMPFS file system server\n");
 
if (!tmpfs_init()) {
printf(NAME ": failed to initialize TMPFS\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");
140,7 → 145,7
printf(NAME ": Failed to register file system (%d)\n", rc);
return rc;
}
 
printf(NAME ": Accepting connections\n");
async_manager();
/* not reached */
/branches/network/uspace/srv/fs/tmpfs/tmpfs_ops.c
58,14 → 58,11
 
#define NAMES_BUCKETS 4
 
/*
* For now, we don't distinguish between different dev_handles/instances. All
* requests resolve to the only instance, rooted in the following variable.
*/
static tmpfs_dentry_t *root;
/** All root nodes have index 0. */
#define TMPFS_SOME_ROOT 0
/** Global counter for assigning node indices. Shared by all instances. */
fs_index_t tmpfs_next_index = 1;
 
#define TMPFS_DEV 0 /**< Dummy device handle for TMPFS */
 
/*
* Implementation of the libfs interface.
*/
102,7 → 99,7
 
static void *tmpfs_root_get(dev_handle_t dev_handle)
{
return root;
return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);
}
 
static char tmpfs_plb_get_char(unsigned pos)
142,18 → 139,22
/** Hash table of all directory entries. */
hash_table_t dentries;
 
#define DENTRIES_KEY_INDEX 0
#define DENTRIES_KEY_DEV 1
 
/* Implementation of hash table interface for the dentries hash table. */
static hash_index_t dentries_hash(unsigned long *key)
static hash_index_t dentries_hash(unsigned long key[])
{
return *key % DENTRIES_BUCKETS;
return key[DENTRIES_KEY_INDEX] % DENTRIES_BUCKETS;
}
 
static int dentries_compare(unsigned long *key, hash_count_t keys,
static int dentries_compare(unsigned long key[], hash_count_t keys,
link_t *item)
{
tmpfs_dentry_t *dentry = hash_table_get_instance(item, tmpfs_dentry_t,
dh_link);
return dentry->index == *key;
return (dentry->index == key[DENTRIES_KEY_INDEX] &&
dentry->dev_handle == key[DENTRIES_KEY_DEV]);
}
 
static void dentries_remove_callback(link_t *item)
167,8 → 168,6
.remove_callback = dentries_remove_callback
};
 
fs_index_t tmpfs_next_index = 1;
 
typedef struct {
char *name;
tmpfs_dentry_t *parent;
215,6 → 214,7
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
{
dentry->index = 0;
dentry->dev_handle = 0;
dentry->sibling = NULL;
dentry->child = NULL;
dentry->type = TMPFS_NONE;
226,15 → 226,21
&names_ops);
}
 
static bool tmpfs_init(void)
bool tmpfs_init(void)
{
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 2, &dentries_ops))
return false;
root = (tmpfs_dentry_t *) tmpfs_create_node(TMPFS_DEV, L_DIRECTORY);
if (!root) {
hash_table_destroy(&dentries);
return true;
}
 
static bool tmpfs_instance_init(dev_handle_t dev_handle)
{
tmpfs_dentry_t *root;
root = (tmpfs_dentry_t *) tmpfs_create_node(dev_handle, L_DIRECTORY);
if (!root)
return false;
}
root->lnkcnt = 0; /* FS root is not linked */
return true;
}
255,7 → 261,7
link_t *hlp = hash_table_find(&childp->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
return !strcmp(namep->name, component);
return !str_cmp(namep->name, component);
}
 
void *tmpfs_match(void *prnt, const char *component)
272,8 → 278,11
void *
tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
{
unsigned long key = index;
link_t *lnk = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
link_t *lnk = hash_table_find(&dentries, key);
if (!lnk)
return NULL;
return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link);
296,7 → 305,11
free(node);
return NULL;
}
node->index = tmpfs_next_index++;
if (!tmpfs_root_get(dev_handle))
node->index = TMPFS_SOME_ROOT;
else
node->index = tmpfs_next_index++;
node->dev_handle = dev_handle;
if (lflag & L_DIRECTORY)
node->type = TMPFS_DIRECTORY;
else
303,8 → 316,11
node->type = TMPFS_FILE;
 
/* Insert the new node into the dentry hash table. */
unsigned long key = node->index;
hash_table_insert(&dentries, &key, &node->dh_link);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = node->index,
[DENTRIES_KEY_DEV] = node->dev_handle
};
hash_table_insert(&dentries, key, &node->dh_link);
return (void *) node;
}
 
319,13 → 335,13
if (!namep)
return ENOMEM;
tmpfs_name_initialize(namep);
size_t len = strlen(nm);
namep->name = malloc(len + 1);
size_t size = str_size(nm);
namep->name = malloc(size + 1);
if (!namep->name) {
free(namep);
return ENOMEM;
}
strcpy(namep->name, nm);
str_cpy(namep->name, size + 1, nm);
namep->parent = parentp;
childp->lnkcnt++;
384,8 → 400,11
assert(!dentry->child);
assert(!dentry->sibling);
 
unsigned long key = dentry->index;
hash_table_remove(&dentries, &key, 1);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = dentry->index,
[DENTRIES_KEY_DEV] = dentry->dev_handle
};
hash_table_remove(&dentries, key, 2);
 
hash_table_destroy(&dentry->names);
 
399,13 → 418,36
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 
/* Initialize TMPFS. */
if (!root && !tmpfs_init()) {
/* 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;
}
opts[size] = '\0';
 
if (dev_handle >= 0) {
/* Initialize TMPFS instance. */
if (!tmpfs_instance_init(dev_handle)) {
ipc_answer_0(rid, ENOMEM);
return;
}
 
tmpfs_dentry_t *root = tmpfs_root_get(dev_handle);
if (str_cmp(opts, "restore") == 0) {
if (tmpfs_restore(dev_handle))
ipc_answer_3(rid, EOK, root->index, root->size,
root->lnkcnt);
441,8 → 483,11
* Lookup the respective dentry.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle,
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
454,8 → 499,8
* Receive the read request.
*/
ipc_callid_t callid;
size_t len;
if (!ipc_data_read_receive(&callid, &len)) {
size_t size;
if (!ipc_data_read_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
463,7 → 508,7
 
size_t bytes;
if (dentry->type == TMPFS_FILE) {
bytes = max(0, min(dentry->size - pos, len));
bytes = max(0, min(dentry->size - pos, size));
(void) ipc_data_read_finalize(callid, dentry->data + pos,
bytes);
} else {
494,7 → 539,7
link);
 
(void) ipc_data_read_finalize(callid, namep->name,
strlen(namep->name) + 1);
str_size(namep->name) + 1);
bytes = 1;
}
 
514,8 → 559,11
* Lookup the respective dentry.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
527,8 → 575,8
* Receive the write request.
*/
ipc_callid_t callid;
size_t len;
if (!ipc_data_write_receive(&callid, &len)) {
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
537,13 → 585,13
/*
* Check whether the file needs to grow.
*/
if (pos + len <= dentry->size) {
if (pos + size <= dentry->size) {
/* The file size is not changing. */
(void) ipc_data_write_finalize(callid, dentry->data + pos, len);
ipc_answer_2(rid, EOK, len, dentry->size);
(void) ipc_data_write_finalize(callid, dentry->data + pos, size);
ipc_answer_2(rid, EOK, size, dentry->size);
return;
}
size_t delta = (pos + len) - dentry->size;
size_t delta = (pos + size) - dentry->size;
/*
* At this point, we are deliberately extremely straightforward and
* simply realloc the contents of the file on every write that grows the
561,8 → 609,8
memset(newdata + dentry->size, 0, delta);
dentry->size += delta;
dentry->data = newdata;
(void) ipc_data_write_finalize(callid, dentry->data + pos, len);
ipc_answer_2(rid, EOK, len, dentry->size);
(void) ipc_data_write_finalize(callid, dentry->data + pos, size);
ipc_answer_2(rid, EOK, size, dentry->size);
}
 
void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
575,8 → 623,11
* Lookup the respective dentry.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
610,8 → 661,11
int rc;
 
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[DENTRIES_KEY_INDEX] = index,
[DENTRIES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&dentries, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
/branches/network/uspace/srv/fs/fat/fat_dentry.c
62,15 → 62,18
int fat_dentry_namecmp(char *name, const char *component)
{
int rc;
size_t size;
 
if (!(rc = stricmp(name, component)))
return rc;
if (!strchr(name, '.')) {
if (!str_chr(name, '.')) {
/*
* There is no '.' in the name, so we know that there is enough
* space for appending an extra '.' to name.
*/
name[strlen(name)] = '.';
name[strlen(name) + 1] = '\0';
size = str_size(name);
name[size] = '.';
name[size + 1] = '\0';
rc = stricmp(name, component);
}
return rc;
/branches/network/uspace/srv/fs/fat/fat_ops.c
487,10 → 487,10
b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE);
d = (fat_dentry_t *)b->data;
if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
strcmp(d->name, FAT_NAME_DOT) == 0) {
str_cmp(d->name, FAT_NAME_DOT) == 0) {
memset(d, 0, sizeof(fat_dentry_t));
strcpy(d->name, FAT_NAME_DOT);
strcpy(d->ext, FAT_EXT_PAD);
str_cpy(d->name, 8, FAT_NAME_DOT);
str_cpy(d->ext, 3, FAT_EXT_PAD);
d->attr = FAT_ATTR_SUBDIR;
d->firstc = host2uint16_t_le(childp->firstc);
/* TODO: initialize also the date/time members. */
497,10 → 497,10
}
d++;
if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
strcmp(d->name, FAT_NAME_DOT_DOT) == 0) {
str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
memset(d, 0, sizeof(fat_dentry_t));
strcpy(d->name, FAT_NAME_DOT_DOT);
strcpy(d->ext, FAT_EXT_PAD);
str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
str_cpy(d->ext, 3, FAT_EXT_PAD);
d->attr = FAT_ATTR_SUBDIR;
d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
host2uint16_t_le(FAT_CLST_RES0) :
755,6 → 755,28
uint16_t rde;
int rc;
 
/* 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;
}
opts[size] = '\0';
 
/* initialize libblock */
rc = block_init(dev_handle, BS_SIZE);
if (rc != EOK) {
937,7 → 959,7
ipc_answer_1(rid, ENOENT, 0);
return;
hit:
(void) ipc_data_read_finalize(callid, name, strlen(name) + 1);
(void) ipc_data_read_finalize(callid, name, str_size(name) + 1);
bytes = (pos - spos) + 1;
}
 
/branches/network/uspace/srv/pci/libpci/names.c
103,7 → 103,7
u32 id34 = id_pair(id3, id4);
unsigned int h = id_hash(cat, id12, id34);
struct id_entry *n = a->id_hash[h];
int len = strlen((char *) text);
int len = str_size((char *) text);
 
while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat))
n = n->next;
/branches/network/uspace/srv/devmap/devmap.c
563,7 → 563,7
ipc_answer_0(iid, EOK);
size_t name_size = strlen(device->name);
size_t name_size = str_size(device->name);
/* FIXME:
* We have no channel from DEVMAP to client, therefore
/branches/network/uspace/srv/vfs/vfs_ops.c
60,6 → 60,7
link_t link;
char *fs_name; /**< File system name */
char *mp; /**< Mount point */
char *opts; /**< Mount options. */
ipc_callid_t callid; /**< Call ID waiting for the mount */
ipc_callid_t rid; /**< Request ID */
dev_handle_t dev_handle; /**< Device handle */
80,18 → 81,21
};
 
static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle,
fs_handle_t fs_handle, char *mp)
fs_handle_t fs_handle, char *mp, char *opts)
{
/* Resolve the path to the mountpoint. */
vfs_lookup_res_t mp_res;
vfs_node_t *mp_node = NULL;
int rc;
ipcarg_t rc;
int phone;
aid_t msg;
ipc_call_t answer;
 
/* Resolve the path to the mountpoint. */
futex_down(&rootfs_futex);
if (rootfs.fs_handle) {
/* We already have the root FS. */
rwlock_write_lock(&namespace_rwlock);
if ((strlen(mp) == 1) && (mp[0] == '/')) {
if (str_cmp(mp, "/") == 0) {
/* Trying to mount root FS over root FS */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
124,12 → 128,12
rwlock_write_unlock(&namespace_rwlock);
} else {
/* We still don't have the root file system mounted. */
if ((strlen(mp) == 1) && (mp[0] == '/')) {
if (str_cmp(mp, "/") == 0) {
vfs_lookup_res_t mr_res;
vfs_node_t *mr_node;
ipcarg_t rindex;
ipcarg_t rsize;
ipcarg_t rlnkcnt;
fs_index_t rindex;
size_t rsize;
unsigned rlnkcnt;
/*
* For this simple, but important case,
138,8 → 142,19
/* Tell the mountee that it is being mounted. */
phone = vfs_grab_phone(fs_handle);
rc = async_req_1_3(phone, VFS_MOUNTED,
(ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt);
msg = async_send_1(phone, VFS_MOUNTED,
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts,
str_size(opts));
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(phone);
futex_up(&rootfs_futex);
ipc_answer_0(rid, rc);
return;
}
async_wait_for(msg, &rc);
vfs_release_phone(phone);
if (rc != EOK) {
147,12 → 162,16
ipc_answer_0(rid, rc);
return;
}
 
rindex = (fs_index_t) IPC_GET_ARG1(answer);
rsize = (size_t) IPC_GET_ARG2(answer);
rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
mr_res.triplet.fs_handle = fs_handle;
mr_res.triplet.dev_handle = dev_handle;
mr_res.triplet.index = (fs_index_t) rindex;
mr_res.size = (size_t) rsize;
mr_res.lnkcnt = (unsigned) rlnkcnt;
mr_res.triplet.index = rindex;
mr_res.size = rsize;
mr_res.lnkcnt = rlnkcnt;
mr_res.type = VFS_NODE_DIRECTORY;
rootfs.fs_handle = fs_handle;
183,11 → 202,23
*/
phone = vfs_grab_phone(mp_res.triplet.fs_handle);
rc = async_req_4_0(phone, VFS_MOUNT,
msg = async_send_4(phone, VFS_MOUNT,
(ipcarg_t) mp_res.triplet.dev_handle,
(ipcarg_t) mp_res.triplet.index,
(ipcarg_t) fs_handle,
(ipcarg_t) dev_handle);
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(phone);
/* Mount failed, drop reference to mp_node. */
if (mp_node)
vfs_node_put(mp_node);
ipc_answer_0(rid, rc);
return;
}
async_wait_for(msg, &rc);
vfs_release_phone(phone);
if (rc != EOK) {
216,10 → 247,12
ipc_answer_0(pr->callid, EOK);
/* Do the mount */
vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp);
vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp,
pr->opts);
free(pr->fs_name);
free(pr->mp);
free(pr->opts);
list_remove(cur);
free(pr);
goto loop;
272,12 → 305,47
/* Deliver the mount point. */
ipcarg_t retval = ipc_data_write_finalize(callid, mp, size);
if (retval != EOK) {
ipc_answer_0(rid, EREFUSED);
ipc_answer_0(rid, retval);
free(mp);
return;
}
mp[size] = '\0';
/* Now we expect to receive the mount options. */
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
return;
}
 
/* Check the offered options size. */
if (size < 0 || size > MAX_MNTOPTS_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
return;
}
 
/* Allocate buffer for the mount options. */
char *opts = (char *) malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(mp);
return;
}
 
/* Deliver the mount options. */
retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(mp);
free(opts);
return;
}
opts[size] = '\0';
/*
* Now, we expect the client to send us data with the name of the file
* system.
286,6 → 354,7
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
free(opts);
return;
}
297,6 → 366,7
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
free(opts);
return;
}
306,8 → 376,9
char *fs_name = (char *) malloc(size + 1);
if (fs_name == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, EREFUSED);
ipc_answer_0(rid, ENOMEM);
free(mp);
free(opts);
return;
}
314,14 → 385,30
/* Deliver the file system name. */
retval = ipc_data_write_finalize(callid, fs_name, size);
if (retval != EOK) {
ipc_answer_0(rid, EREFUSED);
ipc_answer_0(rid, retval);
free(mp);
free(opts);
free(fs_name);
return;
}
fs_name[size] = '\0';
 
/*
* Wait for IPC_M_PING so that we can return an error if we don't know
* fs_name.
*/
ipc_call_t data;
callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_PING) {
ipc_answer_0(callid, ENOTSUP);
ipc_answer_0(rid, ENOTSUP);
free(mp);
free(opts);
free(fs_name);
return;
}
 
/*
* Check if we know a file system with the same name as is in fs_name.
* This will also give us its file system handle.
*/
328,18 → 415,22
fs_handle_t fs_handle = fs_name_to_handle(fs_name, true);
if (!fs_handle) {
if (flags & IPC_FLAG_BLOCKING) {
pending_req_t *pr;
 
/* Blocking mount, add to pending list */
pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t));
pr = (pending_req_t *) malloc(sizeof(pending_req_t));
if (!pr) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(mp);
free(fs_name);
free(opts);
return;
}
pr->fs_name = fs_name;
pr->mp = mp;
pr->opts = opts;
pr->callid = callid;
pr->rid = rid;
pr->dev_handle = dev_handle;
352,6 → 443,7
ipc_answer_0(rid, ENOENT);
free(mp);
free(fs_name);
free(opts);
return;
}
359,9 → 451,10
ipc_answer_0(callid, EOK);
/* Do the mount */
vfs_mount_internal(rid, dev_handle, fs_handle, mp);
vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts);
free(mp);
free(fs_name);
free(opts);
}
 
void vfs_open(ipc_callid_t rid, ipc_call_t *request)
804,37 → 897,37
 
void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
{
size_t len;
size_t olen, nlen;
ipc_callid_t callid;
int rc;
 
/* Retrieve the old path. */
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &olen)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *old = malloc(len + 1);
char *old = malloc(olen + 1);
if (!old) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
if ((rc = ipc_data_write_finalize(callid, old, len))) {
if ((rc = ipc_data_write_finalize(callid, old, olen))) {
ipc_answer_0(rid, rc);
free(old);
return;
}
old[len] = '\0';
old[olen] = '\0';
/* Retrieve the new path. */
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &nlen)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(old);
return;
}
char *new = malloc(len + 1);
char *new = malloc(nlen + 1);
if (!new) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
841,16 → 934,16
free(old);
return;
}
if ((rc = ipc_data_write_finalize(callid, new, len))) {
if ((rc = ipc_data_write_finalize(callid, new, nlen))) {
ipc_answer_0(rid, rc);
free(old);
free(new);
return;
}
new[len] = '\0';
new[nlen] = '\0';
 
char *oldc = canonify(old, &len);
char *newc = canonify(new, NULL);
char *oldc = canonify(old, &olen);
char *newc = canonify(new, &nlen);
if (!oldc || !newc) {
ipc_answer_0(rid, EINVAL);
free(old);
857,7 → 950,9
free(new);
return;
}
if (!strncmp(newc, oldc, len)) {
oldc[olen] = '\0';
newc[nlen] = '\0';
if (!str_lcmp(newc, oldc, str_length(oldc))) {
/* oldc is a prefix of newc */
ipc_answer_0(rid, EINVAL);
free(old);
/branches/network/uspace/srv/vfs/vfs_register.c
376,8 → 376,7
link_t *cur;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
if (strncmp(fs->vfs_info.name, name,
sizeof(fs->vfs_info.name)) == 0) {
if (str_cmp(fs->vfs_info.name, name) == 0) {
handle = fs->fs_handle;
break;
}
/branches/network/uspace/srv/vfs/vfs.h
254,6 → 254,8
extern uint8_t *plb; /**< Path Lookup Buffer */
extern link_t plb_head; /**< List of active PLB entries. */
 
#define MAX_MNTOPTS_LEN 256
 
/** Holding this rwlock prevents changes in file system namespace. */
extern rwlock_t namespace_rwlock;