Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4717 → Rev 4718

/branches/network/uspace/srv/kbd/ctl/pl050.c
0,0 → 1,262
/*
* Copyright (c) 2009 Vineeth Pillai
* 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_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief PL050 keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stdio.h>
 
#define PL050_CAPS_SCAN_CODE 0x58
#define PL050_NUM_SCAN_CODE 0x77
#define PL050_SCROLL_SCAN_CODE 0x7E
 
static bool is_lock_key(int);
enum dec_state {
ds_s,
ds_e
};
 
static enum dec_state ds;
 
static int scanmap_simple[] = {
 
[0x0e] = KC_BACKTICK,
 
[0x16] = KC_1,
[0x1e] = KC_2,
[0x26] = KC_3,
[0x25] = KC_4,
[0x2e] = KC_5,
[0x36] = KC_6,
[0x3d] = KC_7,
[0x3e] = KC_8,
[0x46] = KC_9,
[0x45] = KC_0,
 
[0x4e] = KC_MINUS,
[0x55] = KC_EQUALS,
[0x66] = KC_BACKSPACE,
 
[0x0d] = KC_TAB,
 
[0x15] = KC_Q,
[0x1d] = KC_W,
[0x24] = KC_E,
[0x2d] = KC_R,
[0x2c] = KC_T,
[0x35] = KC_Y,
[0x3c] = KC_U,
[0x43] = KC_I,
[0x44] = KC_O,
[0x4d] = KC_P,
 
[0x54] = KC_LBRACKET,
[0x5b] = KC_RBRACKET,
 
[0x58] = KC_CAPS_LOCK,
 
[0x1c] = KC_A,
[0x1b] = KC_S,
[0x23] = KC_D,
[0x2b] = KC_F,
[0x34] = KC_G,
[0x33] = KC_H,
[0x3b] = KC_J,
[0x42] = KC_K,
[0x4b] = KC_L,
 
[0x4c] = KC_SEMICOLON,
[0x52] = KC_QUOTE,
[0x5d] = KC_BACKSLASH,
 
[0x12] = KC_LSHIFT,
 
[0x1a] = KC_Z,
[0x22] = KC_X,
[0x21] = KC_C,
[0x2a] = KC_V,
[0x32] = KC_B,
[0x31] = KC_N,
[0x3a] = KC_M,
 
[0x41] = KC_COMMA,
[0x49] = KC_PERIOD,
[0x4a] = KC_SLASH,
 
[0x59] = KC_RSHIFT,
 
[0x14] = KC_LCTRL,
[0x11] = KC_LALT,
[0x29] = KC_SPACE,
 
[0x76] = KC_ESCAPE,
 
[0x05] = KC_F1,
[0x06] = KC_F2,
[0x04] = KC_F3,
[0x0c] = KC_F4,
[0x03] = KC_F5,
[0x0b] = KC_F6,
[0x02] = KC_F7,
 
[0x0a] = KC_F8,
[0x01] = KC_F9,
[0x09] = KC_F10,
 
[0x78] = KC_F11,
[0x07] = KC_F12,
 
[0x60] = KC_SCROLL_LOCK,
 
[0x5a] = KC_ENTER,
 
[0x77] = KC_NUM_LOCK,
[0x7c] = KC_NTIMES,
[0x7b] = KC_NMINUS,
[0x79] = KC_NPLUS,
[0x6c] = KC_N7,
[0x75] = KC_N8,
[0x7d] = KC_N9,
[0x6b] = KC_N4,
[0x73] = KC_N5,
[0x74] = KC_N6,
[0x69] = KC_N1,
[0x72] = KC_N2,
[0x7a] = KC_N3,
[0x70] = KC_N0,
[0x71] = KC_NPERIOD
};
 
static int scanmap_e0[] = {
[0x65] = KC_RALT,
[0x59] = KC_RSHIFT,
 
[0x64] = KC_PRTSCR,
 
[0x70] = KC_INSERT,
[0x6c] = KC_HOME,
[0x7d] = KC_PAGE_UP,
 
[0x71] = KC_DELETE,
[0x69] = KC_END,
[0x7a] = KC_PAGE_DOWN,
 
[0x75] = KC_UP,
[0x6b] = KC_LEFT,
[0x72] = KC_DOWN,
[0x74] = KC_RIGHT,
 
[0x4a] = KC_NSLASH,
[0x5a] = KC_NENTER
};
 
int kbd_ctl_init(void)
{
ds = ds_s;
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
static int key_release_flag = 0;
static int is_locked = 0;
console_ev_type_t type;
unsigned int key;
int *map;
size_t map_length;
 
if (scancode == 0xe0) {
ds = ds_e;
return;
}
 
switch (ds) {
case ds_s:
map = scanmap_simple;
map_length = sizeof(scanmap_simple) / sizeof(int);
break;
case ds_e:
map = scanmap_e0;
map_length = sizeof(scanmap_e0) / sizeof(int);
break;
default:
map = NULL;
map_length = 0;
}
 
ds = ds_s;
if (scancode == 0xf0) {
key_release_flag = 1;
return;
} else {
if (key_release_flag) {
type = KEY_RELEASE;
key_release_flag = 0;
if (is_lock_key(scancode)) {
if (!is_locked) {
is_locked = 1;
} else {
is_locked = 0;
return;
}
}
} else {
if (is_lock_key(scancode) && is_locked)
return;
type = KEY_PRESS;
}
}
 
if (scancode < 0)
return;
 
key = map[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
static bool is_lock_key(int sc)
{
return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
(sc == PL050_SCROLL_SCAN_CODE));
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/ctl/pc.c
207,6 → 207,9
map = scanmap_e0;
map_length = sizeof(scanmap_e0) / sizeof(int);
break;
default:
map = NULL;
map_length = 0;
}
 
ds = ds_s;
218,7 → 221,7
type = KEY_PRESS;
}
 
if (scancode < 0 || scancode >= map_length)
if ((scancode < 0) || ((size_t) scancode >= map_length))
return;
 
key = map[scancode];
/branches/network/uspace/srv/kbd/port/pl050.c
0,0 → 1,114
/*
* Copyright (c) 2009 Vineeth Pillai
* 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 pl050 port driver.
*/
 
#include <ddi.h>
#include <libarch/ddi.h>
#include <ipc/ipc.h>
#include <async.h>
#include <unistd.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
#include <stdio.h>
 
#define PL050_STAT_RXFULL (1 << 4)
static irq_cmd_t pl050_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = NULL,
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = PL050_STAT_RXFULL,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t pl050_kbd = {
sizeof(pl050_cmds) / sizeof(irq_cmd_t),
pl050_cmds
};
 
static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
 
pl050_kbd.cmds[0].addr = (void *) sysinfo_value("kbd.address.status");
pl050_kbd.cmds[3].addr = (void *) sysinfo_value("kbd.address.data");
 
async_set_interrupt_received(pl050_irq_handler);
 
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &pl050_kbd);
 
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
return;
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/i8042.c
135,8 → 135,8
(void) pio_read_8(&i8042->data);
/* Enable kbd */
i8042_kbd.cmds[0].addr = &((i8042_t *) i8042_kernel)->status;
i8042_kbd.cmds[3].addr = &((i8042_t *) i8042_kernel)->data;
i8042_kbd.cmds[0].addr = (void *) &((i8042_t *) i8042_kernel)->status;
i8042_kbd.cmds[3].addr = (void *) &((i8042_t *) i8042_kernel)->data;
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &i8042_kbd);
 
int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
/branches/network/uspace/srv/kbd/genarch/gsp.c
244,7 → 244,7
key[0] = t->old_state;
key[1] = t->input;
 
hash_table_insert(&p->trans, &key, &t->link);
hash_table_insert(&p->trans, key, &t->link);
}
 
/** Allocate transition structure. */
276,7 → 276,8
gsp_trans_t *t;
 
t = hash_table_get_instance(item, gsp_trans_t, link);
return (key[0] == t->old_state && key[1] == t->input);
return ((key[0] == (unsigned long) t->old_state)
&& (key[1] == (unsigned long) t->input));
}
 
static void trans_op_remove_callback(link_t *item)
/branches/network/uspace/srv/kbd/Makefile
61,6 → 61,7
endif
 
ifeq ($(UARCH), arm32)
ifeq ($(MACHINE), testarm)
GENARCH_SOURCES += \
port/gxemul.c
72,6 → 73,12
ctl/stty.c
endif
endif
ifeq ($(MACHINE), integratorcp)
GENARCH_SOURCES += \
port/pl050.c \
ctl/pl050.c
endif
endif
 
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
/branches/network/uspace/srv/kbd/layout/us_qwerty.c
27,7 → 27,7
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @brief US QWERTY layout.
* @{
*/
 
/branches/network/uspace/srv/kbd/layout/cz.c
27,7 → 27,7
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @brief Czech QWERTZ layout.
* @{
*/
 
399,6 → 399,8
case ms_carka:
return parse_ms_carka(ev);
}
return 0;
}
 
/**
/branches/network/uspace/srv/ns/ns.c
108,13 → 108,6
task_id_t id;
ipcarg_t retval;
if (callid & IPC_CALLID_NOTIFICATION) {
id = (task_id_t)
MERGE_LOUP32(IPC_GET_ARG2(call), IPC_GET_ARG3(call));
wait_notification((wait_type_t) IPC_GET_ARG1(call), id);
continue;
}
switch (IPC_GET_METHOD(call)) {
case IPC_M_SHARE_IN:
switch (IPC_GET_ARG3(call)) {
133,7 → 126,7
}
continue;
case IPC_M_PHONE_HUNGUP:
retval = EOK;
retval = ns_task_disconnect(&call);
break;
case IPC_M_CONNECT_TO_ME:
/*
170,6 → 163,12
MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
wait_for_task(id, &call, callid);
continue;
case NS_ID_INTRO:
retval = ns_task_id_intro(&call);
break;
case NS_RETVAL:
retval = ns_task_retval(&call);
break;
default:
retval = ENOENT;
break;
/branches/network/uspace/srv/ns/task.c
1,5 → 1,6
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
41,20 → 42,13
#include "ns.h"
 
#define TASK_HASH_TABLE_CHAINS 256
#define P2I_HASH_TABLE_CHAINS 256
 
static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id);
 
/* TODO:
*
* The current implementation of waiting on a task is not perfect. If somebody
* wants to wait on a task which has already finished before the NS asked
* the kernel to receive notifications, it would block indefinitively.
*
* A solution to this is to fail immediately on a task for which no creation
* notification was received yet. However, there is a danger of a race condition
* in this solution -- the caller has to make sure that it is not trying to wait
* before the NS has a change to receive the task creation notification. This
* can be assured by waiting for this event in task_spawn().
*
* Finally, as there is currently no convention that each task has to be waited
* As there is currently no convention that each task has to be waited
* for, the NS can leak memory because of the zombie tasks.
*
*/
62,8 → 56,10
/** Task hash table item. */
typedef struct {
link_t link;
task_id_t id; /**< Task ID. */
bool destroyed;
task_id_t id; /**< Task ID. */
bool finished; /**< Task is done. */
bool have_rval; /**< Task returned a value. */
int retval; /**< The return value. */
} hashed_task_t;
 
/** Compute hash index into task hash table.
83,7 → 79,7
/** Compare a key with hashed item.
*
* @param key Array of keys.
* @param keys Must be lesser or equal to 2.
* @param keys Must be less than or equal to 2.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
125,6 → 121,65
/** Task hash table structure. */
static hash_table_t task_hash_table;
 
typedef struct {
link_t link;
ipcarg_t phash; /**< Task ID. */
task_id_t id; /**< Task ID. */
} p2i_entry_t;
 
/** Compute hash index into task hash table.
*
* @param key Array of keys.
* @return Hash index corresponding to key[0].
*
*/
static hash_index_t p2i_hash(unsigned long *key)
{
assert(key);
return (*key % TASK_HASH_TABLE_CHAINS);
}
 
/** Compare a key with hashed item.
*
* @param key Array of keys.
* @param keys Must be less than or equal to 1.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
*
*/
static int p2i_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
assert(key);
assert(keys == 1);
assert(item);
 
p2i_entry_t *e = hash_table_get_instance(item, p2i_entry_t, link);
 
return (key[0] == e->phash);
}
 
/** Perform actions after removal of item from the hash table.
*
* @param item Item that was removed from the hash table.
*
*/
static void p2i_remove(link_t *item)
{
assert(item);
free(hash_table_get_instance(item, p2i_entry_t, link));
}
 
/** Operations for task hash table. */
static hash_table_operations_t p2i_ops = {
.hash = p2i_hash,
.compare = p2i_compare,
.remove_callback = p2i_remove
};
 
/** Map phone hash to task ID */
static hash_table_t phone_to_id;
 
/** Pending task wait structure. */
typedef struct {
link_t link;
141,10 → 196,13
printf(NAME ": No memory available for tasks\n");
return ENOMEM;
}
 
if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS,
1, &p2i_ops)) {
printf(NAME ": No memory available for tasks\n");
return ENOMEM;
}
if (event_subscribe(EVENT_WAIT, 0) != EOK)
printf(NAME ": Error registering wait notifications\n");
list_initialize(&pending_wait);
return EOK;
154,6 → 212,7
void process_pending_wait(void)
{
link_t *cur;
task_exit_t texit;
loop:
for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) {
169,12 → 228,16
continue;
hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link);
if (!ht->destroyed)
if (!ht->finished)
continue;
if (!(pr->callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(pr->callid, EOK);
if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
texit = ht->have_rval ? TASK_EXIT_NORMAL :
TASK_EXIT_UNEXPECTED;
ipc_answer_2(pr->callid, EOK, texit,
ht->retval);
}
 
hash_table_remove(&task_hash_table, keys, 2);
list_remove(cur);
free(pr);
182,66 → 245,27
}
}
 
static void fail_pending_wait(task_id_t id, int rc)
void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
{
link_t *cur;
loop:
for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) {
pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
if (pr->id == id) {
if (!(pr->callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(pr->callid, rc);
list_remove(cur);
free(pr);
goto loop;
}
}
}
ipcarg_t retval;
task_exit_t texit;
 
void wait_notification(wait_type_t et, task_id_t id)
{
unsigned long keys[2] = {
LOWER32(id),
UPPER32(id)
};
link_t *link = hash_table_find(&task_hash_table, keys);
if (link == NULL) {
hashed_task_t *ht =
(hashed_task_t *) malloc(sizeof(hashed_task_t));
if (ht == NULL) {
fail_pending_wait(id, ENOMEM);
return;
}
link_initialize(&ht->link);
ht->id = id;
ht->destroyed = (et == TASK_CREATE) ? false : true;
hash_table_insert(&task_hash_table, keys, &ht->link);
} else {
hashed_task_t *ht =
hash_table_get_instance(link, hashed_task_t, link);
ht->destroyed = (et == TASK_CREATE) ? false : true;
}
}
 
void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
{
ipcarg_t retval;
unsigned long keys[2] = {
LOWER32(id),
UPPER32(id)
};
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht = (link != NULL) ?
hash_table_get_instance(link, hashed_task_t, link) : NULL;
if ((ht == NULL) || (!ht->destroyed)) {
 
if (ht == NULL) {
/* No such task exists. */
retval = ENOENT;
goto out;
}
 
if (!ht->finished) {
/* Add to pending list */
pending_wait_t *pr =
(pending_wait_t *) malloc(sizeof(pending_wait_t));
260,10 → 284,131
retval = EOK;
out:
if (!(callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(callid, retval);
if (!(callid & IPC_CALLID_NOTIFICATION)) {
texit = ht->have_rval ? TASK_EXIT_NORMAL : TASK_EXIT_UNEXPECTED;
ipc_answer_2(callid, retval, texit, ht->retval);
}
}
 
int ns_task_id_intro(ipc_call_t *call)
{
task_id_t id;
unsigned long keys[2];
link_t *link;
p2i_entry_t *e;
hashed_task_t *ht;
 
id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
 
keys[0] = call->in_phone_hash;
 
link = hash_table_find(&phone_to_id, keys);
if (link != NULL)
return EEXISTS;
 
e = (p2i_entry_t *) malloc(sizeof(p2i_entry_t));
if (e == NULL)
return ENOMEM;
 
ht = (hashed_task_t *) malloc(sizeof(hashed_task_t));
if (ht == NULL)
return ENOMEM;
 
/* Insert to phone-to-id map. */
 
link_initialize(&e->link);
e->phash = call->in_phone_hash;
e->id = id;
hash_table_insert(&phone_to_id, keys, &e->link);
 
/* Insert to main table. */
 
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
 
link_initialize(&ht->link);
ht->id = id;
ht->finished = false;
ht->have_rval = false;
ht->retval = -1;
hash_table_insert(&task_hash_table, keys, &ht->link);
 
return EOK;
}
 
int ns_task_retval(ipc_call_t *call)
{
task_id_t id;
unsigned long keys[2];
int rc;
 
rc = get_id_by_phone(call->in_phone_hash, &id);
if (rc != EOK)
return rc;
 
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht = (link != NULL) ?
hash_table_get_instance(link, hashed_task_t, link) : NULL;
if ((ht == NULL) || ht->finished)
return EINVAL;
 
ht->finished = true;
ht->have_rval = true;
ht->retval = IPC_GET_ARG1(*call);
 
return EOK;
}
 
int ns_task_disconnect(ipc_call_t *call)
{
unsigned long keys[2];
task_id_t id;
int rc;
 
rc = get_id_by_phone(call->in_phone_hash, &id);
if (rc != EOK)
return rc;
 
/* Delete from phone-to-id map. */
keys[0] = call->in_phone_hash;
hash_table_remove(&phone_to_id, keys, 1);
 
/* Mark task as finished. */
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
 
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht =
hash_table_get_instance(link, hashed_task_t, link);
if (ht == NULL)
return EOK;
 
ht->finished = true;
 
return EOK;
}
 
static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id)
{
unsigned long keys[1];
link_t *link;
p2i_entry_t *e;
 
keys[0] = phone_hash;
link = hash_table_find(&phone_to_id, keys);
if (link == NULL)
return ENOENT;
 
e = hash_table_get_instance(link, p2i_entry_t, link);
*id = e->id;
 
return EOK;
}
 
/**
* @}
*/
/branches/network/uspace/srv/ns/task.h
42,6 → 42,11
extern void wait_notification(wait_type_t et, task_id_t id);
extern void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid);
 
extern int ns_task_id_intro(ipc_call_t *call);
extern int ns_task_disconnect(ipc_call_t *call);
extern int ns_task_retval(ipc_call_t *call);
 
 
#endif
 
/**
/branches/network/uspace/srv/console/screenbuffer.h
135,6 → 135,8
return (a1.a.r.fg_color == a2.a.r.fg_color)
&& (a1.a.r.bg_color == a2.a.r.bg_color);
}
return 0;
}
 
 
/branches/network/uspace/srv/console/console.c
69,6 → 69,7
int phone; /**< Framebuffer phone */
ipcarg_t cols; /**< Framebuffer columns */
ipcarg_t rows; /**< Framebuffer rows */
int color_cap; /**< Color capabilities (FB_CCAP_xxx) */
} fb_info;
 
typedef struct {
172,6 → 173,19
}
}
 
static int ccap_fb_to_con(int ccap_fb, int *ccap_con)
{
switch (ccap_fb) {
case FB_CCAP_NONE: *ccap_con = CONSOLE_CCAP_NONE; break;
case FB_CCAP_STYLE: *ccap_con = CONSOLE_CCAP_STYLE; break;
case FB_CCAP_INDEXED: *ccap_con = CONSOLE_CCAP_INDEXED; break;
case FB_CCAP_RGB: *ccap_con = CONSOLE_CCAP_RGB; break;
default: return EINVAL;
}
 
return EOK;
}
 
/** Send an area of screenbuffer to the FB driver. */
static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
{
526,6 → 540,9
ipcarg_t arg1;
ipcarg_t arg2;
ipcarg_t arg3;
 
int cons_ccap;
int rc;
async_serialize_start();
if (cons->refcount == 0)
551,17 → 568,17
if (cons->refcount == 0)
gcons_notify_disconnect(cons->index);
return;
case VFS_READ:
case VFS_OUT_READ:
async_serialize_end();
cons_read(cons, callid, &call);
async_serialize_start();
continue;
case VFS_WRITE:
case VFS_OUT_WRITE:
async_serialize_end();
cons_write(cons, callid, &call);
async_serialize_start();
continue;
case VFS_SYNC:
case VFS_OUT_SYNC:
fb_pending_flush();
if (cons == active_console) {
async_req_0_0(fb_info.phone, FB_FLUSH);
588,6 → 605,14
arg1 = fb_info.cols;
arg2 = fb_info.rows;
break;
case CONSOLE_GET_COLOR_CAP:
rc = ccap_fb_to_con(fb_info.color_cap, &cons_ccap);
if (rc != EOK) {
ipc_answer_0(callid, rc);
continue;
}
arg1 = cons_ccap;
break;
case CONSOLE_SET_STYLE:
fb_pending_flush();
arg1 = IPC_GET_ARG1(call);
639,6 → 664,8
 
static bool console_init(void)
{
ipcarg_t color_cap;
 
/* Connect to keyboard driver */
kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
if (kbd_phone < 0) {
674,6 → 701,8
/* Synchronize, the gcons could put something in queue */
async_req_0_0(fb_info.phone, FB_FLUSH);
async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &color_cap);
fb_info.color_cap = color_cap;
/* Set up shared memory buffer. */
size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
/branches/network/uspace/srv/bd/file_bd/file_bd.c
49,6 → 49,7
#include <sys/types.h>
#include <errno.h>
#include <bool.h>
#include <task.h>
 
#define NAME "file_bd"
 
86,6 → 87,7
}
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
/branches/network/uspace/srv/bd/gxe_bd/gxe_bd.c
46,6 → 46,7
#include <devmap.h>
#include <sys/types.h>
#include <errno.h>
#include <task.h>
 
#define NAME "gxe_bd"
 
110,6 → 111,7
return -1;
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
/branches/network/uspace/srv/bd/ata_bd/ata_bd.c
54,6 → 54,7
#include <sys/types.h>
#include <errno.h>
#include <bool.h>
#include <task.h>
 
#include "ata_bd.h"
 
95,7 → 96,9
return -1;
 
/* Put drives to reset, disable interrupts. */
printf("Reset drives...\n");
printf("Reset drives... ");
fflush(stdout);
 
pio_write_8(&ctl->device_control, DCR_SRST);
/* FIXME: Find out how to do this properly. */
async_usleep(100);
106,8 → 109,6
} while ((status & SR_BSY) != 0);
printf("Done\n");
 
printf("Status = 0x%x\n", pio_read_8(&cmd->status));
 
(void) drive_identify(0, &disk[0]);
(void) drive_identify(1, &disk[1]);
 
135,6 → 136,7
}
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
147,13 → 149,14
uint8_t status;
size_t i;
 
printf("Identify drive %d\n", disk_id);
printf("Identify drive %d... ", disk_id);
fflush(stdout);
 
pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0));
async_usleep(100);
pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
 
status = pio_read_8(&cmd->status);
printf("Status = 0x%x\n", status);
 
d->present = false;
 
/branches/network/uspace/srv/loader/main.c
52,6 → 52,8
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/loader.h>
#include <ipc/ns.h>
#include <macros.h>
#include <loader/pcb.h>
#include <errno.h>
#include <async.h>
437,16 → 439,24
int main(int argc, char *argv[])
{
ipcarg_t phonead;
task_id_t id;
int rc;
 
connected = false;
 
/* Introduce this task to the NS (give it our task ID). */
id = task_get_id();
rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
if (rc != EOK)
return -1;
 
/* Set a handler of incomming connections. */
async_set_client_connection(ldr_connection);
/* Register at naming service. */
if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
return -1;
return -2;
 
async_manager();
/* Never reached */
/branches/network/uspace/srv/fb/serial_console.c
388,6 → 388,10
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, scr_width, scr_height);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, color ? FB_CCAP_INDEXED :
FB_CCAP_STYLE);
continue;
case FB_CLEAR:
serial_clrscr();
retval = 0;
/branches/network/uspace/srv/fb/fb.c
56,6 → 56,8
#include <async.h>
#include <fibril.h>
#include <bool.h>
#include <stdio.h>
#include <byteorder.h>
 
#include "font-8x16.h"
#include "fb.h"
211,9 → 213,9
unsigned int row);
 
 
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
#define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
#define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
 
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
225,36 → 227,58
#define BB_POS(vport, col, row) ((row) * vport->cols + (col))
#define GLYPH_POS(glyph, y, cursor) (((glyph) + (cursor) * FONT_GLYPHS) * screen.glyphbytes + (y) * screen.glyphscanline)
 
 
/** ARGB 8:8:8:8 conversion
/*
* RGB conversion and mask functions.
*
* These functions write an RGB value to some memory in some predefined format.
* The naming convention corresponds to the format created by these functions.
* The functions use the so called network order (i.e. big endian) with respect
* to their names.
*/
 
static void rgb_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = rgb & 0x00ffffff;
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(RED(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (BLUE(rgb, 8)));
}
 
static void bgr_0888(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((0 << 24) |
(BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | (RED(rgb, 8)));
}
 
static void mask_0888(void *dst, bool mask)
{
*((uint32_t *) dst) = (mask ? 0x00ffffff : 0);
bgr_0888(dst, mask ? 0xffffff : 0);
}
 
static void rgb_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst) = host2uint32_t_be((RED(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8) | 0);
}
 
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
static void bgr_8880(void *dst, uint32_t rgb)
{
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
*((uint32_t *) dst) = host2uint32_t_be((BLUE(rgb, 8) << 24) |
(GREEN(rgb, 8) << 16) | (RED(rgb, 8) << 8) | 0);
}
 
static void mask_8880(void *dst, bool mask)
{
bgr_8880(dst, mask ? 0xffffff : 0);
}
 
/** RGB 8:8:8 conversion
*
*/
static void rgb_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
static void bgr_888(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
262,63 → 286,44
 
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_888(dst, mask ? 0xffffff : 0);
}
 
static void rgb_555_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
static void rgb_555_le(void *dst, uint32_t rgb)
{
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 10 |
GREEN(rgb, 5) << 5 | BLUE(rgb, 5));
}
 
 
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
static void rgb_565_be(void *dst, uint32_t rgb)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
*((uint16_t *) dst) = host2uint16_t_be(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
static void mask_555(void *dst, bool mask)
static void rgb_565_le(void *dst, uint32_t rgb)
{
*((uint16_t *) dst) = (mask ? 0x7fff : 0);
*((uint16_t *) dst) = host2uint16_t_le(RED(rgb, 5) << 11 |
GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
}
 
 
/** RGB 5:6:5 conversion
*
*/
static void rgb_565(void *dst, uint32_t rgb)
static void mask_555(void *dst, bool mask)
{
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
rgb_555_be(dst, mask ? 0xffffff : 0);
}
 
static void mask_565(void *dst, bool mask)
{
*((uint16_t *) dst) = (mask ? 0xffff : 0);
rgb_565_be(dst, mask ? 0xffffff : 0);
}
 
 
/** RGB 3:2:3
*
*/
static void rgb_323(void *dst, uint32_t rgb)
static void bgr_323(void *dst, uint32_t rgb)
{
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
326,7 → 331,7
 
static void mask_323(void *dst, bool mask)
{
*((uint8_t *) dst) = (mask ? 0xff : 0);
bgr_323(dst, mask ? 0x0 : ~0x0);
}
 
/** Draw a filled rectangle.
620,24 → 625,32
static bool screen_init(void *addr, unsigned int xres, unsigned int yres,
unsigned int scan, unsigned int visual)
{
switch (visual) {
case VISUAL_INDIRECT_8:
screen.rgb_conv = rgb_323;
screen.rgb_conv = bgr_323;
screen.mask_conv = mask_323;
screen.pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
screen.rgb_conv = rgb_555;
case VISUAL_RGB_5_5_5_LE:
screen.rgb_conv = rgb_555_le;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
screen.rgb_conv = rgb_565;
case VISUAL_RGB_5_5_5_BE:
screen.rgb_conv = rgb_555_be;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_LE:
screen.rgb_conv = rgb_565_le;
screen.mask_conv = mask_565;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5_BE:
screen.rgb_conv = rgb_565_be;
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;
649,8 → 662,8
screen.pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.rgb_conv = rgb_8880;
screen.mask_conv = mask_8880;
screen.pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
663,6 → 676,11
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
screen.rgb_conv = bgr_8880;
screen.mask_conv = mask_8880;
screen.pixelbytes = 4;
break;
default:
return false;
}
1067,10 → 1085,11
if (IPC_GET_ARG1(*call) == shm_id) {
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
shm_size = IPC_GET_ARG2(*call);
if (!ipc_answer_1(callid, EOK, (sysarg_t) dest))
shm = dest;
else
if (ipc_answer_1(callid, EOK, (sysarg_t) dest)) {
shm_id = 0;
return false;
}
shm = dest;
if (shm[0] != 'P')
return false;
1645,6 → 1664,9
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, vport->cols, vport->rows);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, FB_CCAP_RGB);
continue;
case FB_SCROLL:
scroll = IPC_GET_ARG1(call);
if ((scroll > (int) vport->rows) || (scroll < (-(int) vport->rows))) {
1739,17 → 1761,17
unsigned int fb_height = sysinfo_value("fb.height");
unsigned int fb_scanline = sysinfo_value("fb.scanline");
unsigned int fb_visual = sysinfo_value("fb.visual");
 
unsigned int fbsize = fb_scanline * fb_height;
void *fb_addr = as_get_mappable_page(fbsize);
 
if (physmem_map(fb_ph_addr + fb_offset, fb_addr,
ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
 
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual))
return 0;
 
return -1;
}
 
/branches/network/uspace/srv/fb/ppm.c
89,7 → 89,7
{
unsigned int width, height;
unsigned int maxcolor;
unsigned i;
unsigned int i;
unsigned int color;
unsigned int coef;
/branches/network/uspace/srv/fb/ega.c
319,6 → 319,9
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, scr_width, scr_height);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, FB_CCAP_INDEXED);
continue;
case FB_CLEAR:
clrscr();
retval = 0;
/branches/network/uspace/srv/fs/devfs/devfs.c
67,37 → 67,37
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_MOUNTED:
case VFS_OUT_MOUNTED:
devfs_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
devfs_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
devfs_lookup(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_OUT_OPEN_NODE:
devfs_open_node(callid, &call);
break;
case VFS_DEVICE:
devfs_device(callid, &call);
case VFS_OUT_STAT:
devfs_stat(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
devfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
devfs_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
devfs_truncate(callid, &call);
break;
case VFS_CLOSE:
case VFS_OUT_CLOSE:
devfs_close(callid, &call);
break;
case VFS_SYNC:
case VFS_OUT_SYNC:
devfs_sync(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_DESTROY:
devfs_destroy(callid, &call);
break;
default:
/branches/network/uspace/srv/fs/devfs/devfs_ops.c
43,6 → 43,7
#include <libfs.h>
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <sys/stat.h>
#include "devfs.h"
#include "devfs_ops.h"
 
163,12 → 164,12
if (first >= last) {
/* Root entry */
if (lflag & L_DIRECTORY)
if (!(lflag & L_FILE))
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) {
if (!(lflag & L_DIRECTORY)) {
size_t len;
if (last >= first)
len = last - first + 1;
277,10 → 278,30
ipc_answer_3(rid, EOK, 0, 1, L_FILE);
}
 
void devfs_device(ipc_callid_t rid, ipc_call_t *request)
void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size) ||
size != sizeof(struct stat)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
struct stat stat;
memset(&stat, 0, sizeof(struct stat));
 
stat.fs_handle = devfs_reg.fs_handle;
stat.dev_handle = dev_handle;
stat.index = index;
stat.lnkcnt = 1;
stat.is_file = (index != 0);
stat.size = 0;
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
288,16 → 309,13
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
if (lnk != NULL)
stat.devfs_stat.device = (dev_handle_t)index;
fibril_mutex_unlock(&devices_mutex);
ipc_answer_1(rid, EOK, (ipcarg_t) index);
} else
ipc_answer_0(rid, ENOTSUP);
}
 
ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
ipc_answer_0(rid, EOK);
}
 
void devfs_read(ipc_callid_t rid, ipc_call_t *request)
/branches/network/uspace/srv/fs/devfs/devfs_ops.h
42,7 → 42,7
extern void devfs_mount(ipc_callid_t, ipc_call_t *);
extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
extern void devfs_device(ipc_callid_t, ipc_call_t *);
extern void devfs_stat(ipc_callid_t, ipc_call_t *);
extern void devfs_sync(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 *);
/branches/network/uspace/srv/fs/tmpfs/tmpfs.h
86,10 → 86,10
extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
extern void tmpfs_device(ipc_callid_t, ipc_call_t *);
extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
 
extern bool tmpfs_restore(dev_handle_t);
/branches/network/uspace/srv/fs/tmpfs/tmpfs_dump.c
67,8 → 67,8
tmpfs_node_t *nodep;
uint32_t size;
if (block_read(dev, bufpos, buflen, pos, &entry, sizeof(entry),
TMPFS_BLOCK_SIZE) != EOK)
if (block_seqread(dev, bufpos, buflen, pos, &entry,
sizeof(entry), TMPFS_BLOCK_SIZE) != EOK)
return false;
entry.len = uint32_t_le2host(entry.len);
87,7 → 87,7
return false;
}
if (block_read(dev, bufpos, buflen, pos, fname,
if (block_seqread(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
ops->destroy(fn);
free(fname);
103,7 → 103,7
}
free(fname);
if (block_read(dev, bufpos, buflen, pos, &size,
if (block_seqread(dev, bufpos, buflen, pos, &size,
sizeof(size), TMPFS_BLOCK_SIZE) != EOK)
return false;
115,7 → 115,7
return false;
nodep->size = size;
if (block_read(dev, bufpos, buflen, pos, nodep->data,
if (block_seqread(dev, bufpos, buflen, pos, nodep->data,
size, TMPFS_BLOCK_SIZE) != EOK)
return false;
131,7 → 131,7
return false;
}
if (block_read(dev, bufpos, buflen, pos, fname,
if (block_seqread(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
ops->destroy(fn);
free(fname);
174,7 → 174,7
off_t pos = 0;
char tag[6];
if (block_read(dev, &bufpos, &buflen, &pos, tag, 5,
if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5,
TMPFS_BLOCK_SIZE) != EOK)
goto error;
/branches/network/uspace/srv/fs/tmpfs/tmpfs.c
98,37 → 98,37
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_MOUNTED:
case VFS_OUT_MOUNTED:
tmpfs_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
tmpfs_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
tmpfs_lookup(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
tmpfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
tmpfs_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
tmpfs_truncate(callid, &call);
break;
case VFS_CLOSE:
case VFS_OUT_CLOSE:
tmpfs_close(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_DESTROY:
tmpfs_destroy(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_OUT_OPEN_NODE:
tmpfs_open_node(callid, &call);
break;
case VFS_DEVICE:
tmpfs_device(callid, &call);
case VFS_OUT_STAT:
tmpfs_stat(callid, &call);
break;
case VFS_SYNC:
case VFS_OUT_SYNC:
tmpfs_sync(callid, &call);
break;
default:
152,7 → 152,7
printf(NAME ": Unable to connect to VFS\n");
return -1;
}
 
int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
tmpfs_connection);
if (rc != EOK) {
/branches/network/uspace/srv/fs/tmpfs/tmpfs_ops.c
628,9 → 628,9
libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_device(ipc_callid_t rid, ipc_call_t *request)
void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
/branches/network/uspace/srv/fs/fat/fat.h
207,10 → 207,11
extern void fat_read(ipc_callid_t, ipc_call_t *);
extern void fat_write(ipc_callid_t, ipc_call_t *);
extern void fat_truncate(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_close(ipc_callid_t, ipc_call_t *);
extern void fat_destroy(ipc_callid_t, ipc_call_t *);
extern void fat_open_node(ipc_callid_t, ipc_call_t *);
extern void fat_device(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_sync(ipc_callid_t, ipc_call_t *);
 
extern fat_idx_t *fat_idx_get_new(dev_handle_t);
/branches/network/uspace/srv/fs/fat/fat.c
91,37 → 91,37
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_MOUNTED:
case VFS_OUT_MOUNTED:
fat_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
fat_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
fat_lookup(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
fat_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
fat_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
fat_truncate(callid, &call);
break;
case VFS_CLOSE:
case VFS_OUT_STAT:
fat_stat(callid, &call);
break;
case VFS_OUT_CLOSE:
fat_close(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_DESTROY:
fat_destroy(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_OUT_OPEN_NODE:
fat_open_node(callid, &call);
break;
case VFS_DEVICE:
fat_device(callid, &call);
break;
case VFS_SYNC:
case VFS_OUT_SYNC:
fat_sync(callid, &call);
break;
default:
/branches/network/uspace/srv/fs/fat/fat_ops.c
402,7 → 402,7
fat_dentry_t *d;
fat_bs_t *bs;
block_t *b;
int i, j;
unsigned i, j;
uint16_t bps;
unsigned dps;
unsigned blocks;
1202,9 → 1202,9
libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_device(ipc_callid_t rid, ipc_call_t *request)
void fat_stat(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_sync(ipc_callid_t rid, ipc_call_t *request)
/branches/network/uspace/srv/pci/update-ids
1,6 → 1,6
#! /bin/bash
 
wget http://pciids.sourceforge.net/v2.2/pci.ids
wget -O pci.ids http://pciids.sourceforge.net/v2.2/pci.ids
 
cat > pci_ids.h <<EOF
/* DO NOT EDIT, THIS FILE IS AUTOMATICALLY GENERATED */
7,7 → 7,8
char *pci_ids[] = {
EOF
 
cat pci.ids | grep -v '^#.*' | grep -v '^$' | tr \" \' | sed -n 's/\(.*\)/"\1",/p' >> pci_ids.h
cat pci.ids | grep -v '^#.*' | grep -v '^$' | tr \" \' | \
sed -n 's/\(.*\)/"\1",/p' | sed 's/?/\\?/g' >> pci_ids.h
 
cat >> pci_ids.h <<EOF
""
/branches/network/uspace/srv/pci/libpci/i386-ports.c
79,14 → 79,14
d.func = 0;
for (d.dev = 0; d.dev < 32; d.dev++) {
u16 class, vendor;
if (m->read(&d, PCI_CLASS_DEVICE, (byte *) & class,
if ((m->read(&d, PCI_CLASS_DEVICE, (byte *) & class,
sizeof(class))
&& (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST)
|| class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA))
|| m->read(&d, PCI_VENDOR_ID, (byte *) & vendor,
|| class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)))
|| (m->read(&d, PCI_VENDOR_ID, (byte *) & vendor,
sizeof(vendor))
&& (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL)
|| vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) {
|| vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ)))) {
a->debug("...outside the Asylum at 0/%02x/0",
d.dev);
return 1;
/branches/network/uspace/srv/pci/libpci/pci_ids.h
386,7 → 386,7
" 1043 c01b A9600XT/TD (Secondary)",
" 174b 7c28 Sapphire Radeon 9600XT (Secondary)",
" 1787 4003 Radeon 9600 XT (Secondary)",
" 4173 RV350 ?? [Radeon 9550] (Secondary)",
" 4173 RV350 \?\? [Radeon 9550] (Secondary)",
" 4237 Radeon 7000 IGP",
" 4242 R200 BB [Radeon All in Wonder 8500DV]",
" 1002 02aa Radeon 8500 AIW DV Edition",
668,7 → 668,7
" 1002 002a Rage 128 Pro AIW AGP",
" 1002 0048 Rage Fury Pro",
" 1002 2000 Rage Fury MAXX AGP 4x (TMDS) (VGA device)",
" 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)",
" 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device\?!)",
" 5047 Rage 128 PG/PRO",
" 5048 Rage 128 PH/PRO AGP 2x",
" 5049 Rage 128 PI/PRO AGP 4x",
1635,7 → 1635,7
" 1028 0106 PowerEdge 4600",
" 1028 0121 PowerEdge 2650",
"102b Matrox Graphics, Inc.",
" 0010 MGA-I [Impression?]",
" 0010 MGA-I [Impression\?]",
" 0100 MGA 1064SG [Mystique]",
" 0518 MGA-II [Athena]",
" 0519 MGA 2064W [Millennium]",
2437,7 → 2437,7
" 9922 W99200F/W9922PF MPEG-1/2 Video Encoder",
" 9970 W9970CF",
"1051 Anigma, Inc.",
"1052 ?Young Micro Systems",
"1052 \?Young Micro Systems",
"1053 Young Micro Systems",
"1054 Hitachi, Ltd",
"1055 Efar Microsystems",
3048,7 → 3048,7
" 0369 Bt878 Video Capture",
" 1002 0001 TV-Wonder",
" 1002 0003 TV-Wonder/VE",
" 036c Bt879(??) Video Capture",
" 036c Bt879(\?\?) Video Capture",
" 13e9 0070 Win/TV (Video Section)",
" 036e Bt878 Video Capture",
" 0070 13eb WinTV Series",
4123,7 → 4123,7
" 01de Quadro FX 350",
" 10de 01dc Quadro FX Go350M",
" 01df GeForce 7300 GS",
" 01e0 nForce2 AGP (different version?)",
" 01e0 nForce2 AGP (different version\?)",
" 147b 1c09 NV7 Motherboard",
" 01e8 nForce2 AGP",
" 01ea nForce2 Memory Controller 0",
5096,7 → 5096,7
" 1113 1211 EN-1207D Fast Ethernet Adapter",
" 1216 EN-1216 Ethernet Adapter",
" 1113 2242 EN2242 10/100 Ethernet Mini-PCI Card",
" 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]",
" 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX \?]",
" 1217 EN-1217 Ethernet Adapter",
" 5105 10Mbps Network card",
" 9211 EN-1207D Fast Ethernet Adapter",
6556,7 → 6556,7
"123e Simutech, Inc.",
"123f C-Cube Microsystems",
" 00e4 MPEG",
" 8120 E4?",
" 8120 E4\?",
" 11bd 0006 DV500 E4",
" 11bd 000a DV500 E4",
" 11bd 000f DV500 E4",
6632,7 → 6632,7
" 0640 Aries 16000P",
"125d ESS Technology",
" 0000 ES336H Fax Modem (Early Model)",
" 1948 Solo?",
" 1948 Solo\?",
" 1968 ES1968 Maestro 2",
" 1028 0085 ES1968 Maestro-2 PCI",
" 1033 8051 ES1968 Maestro-2 Audiodrive",
6922,7 → 6922,7
" 122d 4056 MSP3880SP-U",
" 122d 4057 MSP3880SP-A",
" 4311 Riptide HSF 56k PCI Modem",
" 127a 4311 Ring Modular? Riptide HSF RT HP Dom",
" 127a 4311 Ring Modular\? Riptide HSF RT HP Dom",
" 13e0 0210 HP-GVC",
" 4320 Riptide PCI Audio Controller",
" 1235 4320 Riptide PCI Audio Controller",
8382,7 → 8382,7
" 4325 BCM43xG 802.11b/g",
" 1414 0003 Wireless Notebook Adapter MN-720",
" 1414 0004 Wireless PCI Adapter MN-730",
" 4326 BCM4307 Chipcommon I/O Controller?",
" 4326 BCM4307 Chipcommon I/O Controller\?",
" 4401 BCM4401 100Base-T",
" 1043 80a8 A7V8X motherboard",
" 4402 BCM4402 Integrated 10/100BaseT",
8691,7 → 8691,7
"1504 KAISER Electronics",
"1505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH",
"1506 CHAMELEON Systems Inc",
"1507 Motorola ?? / HTEC",
"1507 Motorola \?\? / HTEC",
" 0001 MPC105 [Eagle]",
" 0002 MPC106 [Grackle]",
" 0003 MPC8240 [Kahlua]",
9467,7 → 9467,7
"270b Xantel Corporation",
"270f Chaintech Computer Co. Ltd",
"2711 AVID Technology Inc.",
"2a15 3D Vision(???)",
"2a15 3D Vision(\?\?\?)",
"3000 Hansol Electronics Inc.",
"3142 Post Impression Systems.",
"3388 Hint Corp",
/branches/network/uspace/srv/pci/libpci/names.c
150,7 → 150,7
int cat = -1;
int nest;
static const char parse_error[] = "Parse error";
int i;
size_t i;
 
*lino = 0;
for (i = 0; i < sizeof(pci_ids) / sizeof(char *); i++) {
330,7 → 330,7
iv = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", iv);
else if (v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0))
else if ((v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0)) != 0)
return (char *) v->name;
else
res = snprintf(buf, size, "Unknown vendor %04x", iv);
340,7 → 340,7
id = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", id);
else if (d = id_lookup(a, ID_DEVICE, iv, id, 0, 0))
else if ((d = id_lookup(a, ID_DEVICE, iv, id, 0, 0)) != 0)
return (char *) d->name;
else if (synth)
res = snprintf(buf, size, "Unknown device %04x", id);
370,7 → 370,7
isv = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", isv);
else if (v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0))
else if ((v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0)) != 0)
return (char *) v->name;
else if (synth)
res = snprintf(buf, size, "Unknown vendor %04x", isv);
384,7 → 384,7
isd = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", isd);
else if (d = id_lookup_subsys(a, iv, id, isv, isd))
else if ((d = id_lookup_subsys(a, iv, id, isv, isd)) != 0)
return (char *) d->name;
else if (synth)
res = snprintf(buf, size, "Unknown device %04x", isd);
415,9 → 415,9
icls = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%04x", icls);
else if (cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0))
else if ((cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0)) != 0)
return (char *) cls->name;
else if (cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0))
else if ((cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0)) != 0)
res = snprintf(buf, size, "%s [%04x]", cls->name, icls);
else if (synth)
res = snprintf(buf, size, "Class %04x", icls);
429,7 → 429,7
ipif = va_arg(args, int);
if (num)
res = snprintf(buf, size, "%02x", ipif);
else if (pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0))
else if ((pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0)) != 0)
return (char *) pif->name;
else if (icls == 0x0101 && !(ipif & 0x70)) {
/* IDE controllers have complex prog-if semantics */
/branches/network/uspace/srv/pci/libpci/generic.c
29,7 → 29,7
for (dev = 0; dev < 32; dev++) {
t->dev = dev;
multi = 0;
for (t->func = 0; !t->func || multi && t->func < 8;
for (t->func = 0; !t->func || (multi && t->func < 8);
t->func++) {
u32 vd = pci_read_long(t, PCI_VENDOR_ID);
struct pci_dev *d;
/branches/network/uspace/srv/devmap/devmap.c
46,7 → 46,8
#include <string.h>
#include <ipc/devmap.h>
 
#define NAME "devmap"
#define NAME "devmap"
#define NULL_DEVICES 256
 
/** Representation of device driver.
*
97,8 → 98,10
static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv);
static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex);
static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex);
static FIBRIL_MUTEX_INITIALIZE(null_devices_mutex);
 
static dev_handle_t last_handle = 0;
static devmap_device_t *null_devices[NULL_DEVICES];
 
static dev_handle_t devmap_create_handle(void)
{
543,12 → 546,12
ipc_answer_0(iid, EOK);
size_t name_size = str_size(device->name);
/* FIXME:
* We have no channel from DEVMAP to client, therefore
* sending must be initiated by client.
*
* size_t name_size = str_size(device->name);
*
* int rc = ipc_data_write_send(phone, device->name, name_size);
* if (rc != EOK) {
* async_wait_for(req, NULL);
618,21 → 621,43
ipc_answer_1(iid, EOK, pos);
}
 
/** Initialize device mapper.
*
*
*/
static bool devmap_init(void)
static void devmap_null_create(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&null_devices_mutex);
unsigned int i;
bool fnd = false;
for (i = 0; i < NULL_DEVICES; i++) {
if (null_devices[i] == NULL) {
fnd = true;
break;
}
}
if (!fnd) {
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, ENOMEM);
return;
}
/* Create NULL device entry */
devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
if (device == NULL)
return false;
if (device == NULL) {
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, ENOMEM);
return;
}
device->name = str_dup("null");
char null[DEVMAP_NAME_MAXLEN];
snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i);
device->name = str_dup(null);
if (device->name == NULL) {
fibril_mutex_unlock(&null_devices_mutex);
free(device);
return false;
ipc_answer_0(iid, ENOMEM);
return;
}
list_initialize(&(device->devices));
644,11 → 669,50
device->handle = devmap_create_handle();
device->driver = NULL;
/* Insert device into list of all devices */
/* Insert device into list of all devices
and into null devices array */
list_append(&device->devices, &devices_list);
null_devices[i] = device;
fibril_mutex_unlock(&devices_list_mutex);
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_1(iid, EOK, (ipcarg_t) i);
}
 
static void devmap_null_destroy(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&null_devices_mutex);
ipcarg_t i = IPC_GET_ARG1(*icall);
if (null_devices[i] == NULL) {
ipc_answer_0(iid, ENOENT);
return;
}
devmap_device_unregister_core(null_devices[i]);
null_devices[i] = NULL;
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, EOK);
}
 
/** Initialize device mapper.
*
*
*/
static bool devmap_init(void)
{
fibril_mutex_lock(&null_devices_mutex);
unsigned int i;
for (i = 0; i < NULL_DEVICES; i++)
null_devices[i] = NULL;
fibril_mutex_unlock(&null_devices_mutex);
return true;
}
 
701,7 → 765,7
}
}
if (NULL != driver) {
if (driver != NULL) {
/*
* Unregister the device driver and all its devices.
*/
733,6 → 797,12
case DEVMAP_DEVICE_GET_NAME:
devmap_get_name(callid, &call);
break;
case DEVMAP_DEVICE_NULL_CREATE:
devmap_null_create(callid, &call);
break;
case DEVMAP_DEVICE_NULL_DESTROY:
devmap_null_destroy(callid, &call);
break;
case DEVMAP_DEVICE_GET_COUNT:
devmap_get_count(callid, &call);
break;
783,7 → 853,7
/* Set a handler of incomming connections */
async_set_client_connection(devmap_connection);
 
/* Register device mapper at naming service */
ipcarg_t phonead;
if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
/branches/network/uspace/srv/vfs/vfs.c
79,52 → 79,52
case IPC_M_PHONE_HUNGUP:
keep_on_going = false;
break;
case VFS_REGISTER:
case VFS_IN_REGISTER:
vfs_register(callid, &call);
keep_on_going = false;
break;
case VFS_MOUNT:
case VFS_IN_MOUNT:
vfs_mount(callid, &call);
break;
case VFS_OPEN:
case VFS_IN_OPEN:
vfs_open(callid, &call);
break;
case VFS_OPEN_NODE:
case VFS_IN_OPEN_NODE:
vfs_open_node(callid, &call);
break;
case VFS_CLOSE:
case VFS_IN_CLOSE:
vfs_close(callid, &call);
break;
case VFS_READ:
case VFS_IN_READ:
vfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_IN_WRITE:
vfs_write(callid, &call);
break;
case VFS_SEEK:
case VFS_IN_SEEK:
vfs_seek(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_IN_TRUNCATE:
vfs_truncate(callid, &call);
break;
case VFS_MKDIR:
case VFS_IN_FSTAT:
vfs_fstat(callid, &call);
break;
case VFS_IN_STAT:
vfs_stat(callid, &call);
break;
case VFS_IN_MKDIR:
vfs_mkdir(callid, &call);
break;
case VFS_UNLINK:
case VFS_IN_UNLINK:
vfs_unlink(callid, &call);
break;
case VFS_RENAME:
case VFS_IN_RENAME:
vfs_rename(callid, &call);
break;
case VFS_DEVICE:
vfs_device(callid, &call);
break;
case VFS_SYNC:
case VFS_IN_SYNC:
vfs_sync(callid, &call);
break;
case VFS_NODE:
vfs_node(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
/branches/network/uspace/srv/vfs/vfs_ops.c
108,7 → 108,7
/*
* Now we hold a reference to mp_node.
* It will be dropped upon the corresponding VFS_UNMOUNT.
* It will be dropped upon the corresponding VFS_IN_UNMOUNT.
* This prevents the mount point from being deleted.
*/
} else {
121,7 → 121,7
/* Tell the mountee that it is being mounted. */
phone = vfs_grab_phone(fs_handle);
msg = async_send_1(phone, VFS_MOUNTED,
msg = async_send_1(phone, VFS_OUT_MOUNTED,
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts,
183,7 → 183,7
assert(mountee_phone >= 0);
 
phone = vfs_grab_phone(mp_res.triplet.fs_handle);
msg = async_send_4(phone, VFS_MOUNT,
msg = async_send_4(phone, VFS_OUT_MOUNT,
(ipcarg_t) mp_res.triplet.dev_handle,
(ipcarg_t) mp_res.triplet.index,
(ipcarg_t) fs_handle,
306,7 → 306,7
}
 
/* Check the offered options size. */
if (size < 0 || size > MAX_MNTOPTS_LEN) {
if (size > MAX_MNTOPTS_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
437,8 → 437,8
/*
* The POSIX interface is open(path, oflag, mode).
* We can receive oflags and mode along with the VFS_OPEN call; the path
* will need to arrive in another call.
* We can receive oflags and mode along with the VFS_IN_OPEN call;
* the path will need to arrive in another call.
*
* We also receive one private, non-POSIX set of flags called lflag
* used to pass information to vfs_lookup_internal().
447,6 → 447,9
int oflag = IPC_GET_ARG2(*request);
int mode = IPC_GET_ARG3(*request);
size_t len;
 
/* Ignore mode for now. */
(void) mode;
/*
* Make sure that we are called with exactly one of L_FILE and
555,7 → 558,7
* file is being opened and that a file structure is pointing to it.
* It is necessary so that the file will not disappear when
* vfs_node_put() is called. The reference will be dropped by the
* respective VFS_CLOSE.
* respective VFS_IN_CLOSE.
*/
vfs_node_addref(node);
vfs_node_put(node);
632,7 → 635,7
* file is being opened and that a file structure is pointing to it.
* It is necessary so that the file will not disappear when
* vfs_node_put() is called. The reference will be dropped by the
* respective VFS_CLOSE.
* respective VFS_IN_CLOSE.
*/
vfs_node_addref(node);
vfs_node_put(node);
641,55 → 644,6
ipc_answer_1(rid, EOK, fd);
}
 
void vfs_node(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
ipc_answer_3(rid, EOK, file->node->fs_handle, file->node->dev_handle,
file->node->index);
}
 
void vfs_device(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
/*
* Lock the open file structure so that no other thread can manipulate
* the same open file at a time.
*/
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_DEVICE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
file->node->dev_handle, file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
 
vfs_release_phone(fs_phone);
fibril_mutex_unlock(&file->lock);
ipc_answer_1(rid, EOK, IPC_GET_ARG1(answer));
}
 
void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
708,11 → 662,11
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_SYMC request at the destination FS server. */
/* Make a VFS_OUT_SYMC request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
file->node->dev_handle, file->node->index, &answer);
msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
742,11 → 696,11
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_CLOSE request at the destination FS server. */
/* Make a VFS_OUT_CLOSE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
file->node->dev_handle, file->node->index, &answer);
msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
832,7 → 786,7
ipc_call_t answer;
if (!read && file->append)
file->pos = file->node->size;
msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
file->node->dev_handle, file->node->index, file->pos, &answer);
/*
946,7 → 900,7
int fs_phone;
fs_phone = vfs_grab_phone(fs_handle);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle,
rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
(ipcarg_t)index, (ipcarg_t)size);
vfs_release_phone(fs_phone);
return (int)rc;
976,6 → 930,106
ipc_answer_0(rid, (ipcarg_t)rc);
}
 
void vfs_fstat(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
size_t size = IPC_GET_ARG2(*request);
ipcarg_t rc;
 
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
 
ipc_callid_t callid;
if (!ipc_data_read_receive(&callid, NULL)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
fibril_mutex_lock(&file->lock);
 
int fs_phone = vfs_grab_phone(file->node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle,
file->node->index, true, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
vfs_release_phone(fs_phone);
 
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, rc);
}
 
void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
size_t len;
ipc_callid_t callid;
 
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *path = malloc(len + 1);
if (!path) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
int rc;
if ((rc = ipc_data_write_finalize(callid, path, len))) {
ipc_answer_0(rid, rc);
free(path);
return;
}
path[len] = '\0';
 
if (!ipc_data_read_receive(&callid, NULL)) {
free(path);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
vfs_lookup_res_t lr;
fibril_rwlock_read_lock(&namespace_rwlock);
rc = vfs_lookup_internal(path, L_NONE, &lr, NULL);
free(path);
if (rc != EOK) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(callid, rc);
ipc_answer_0(rid, rc);
return;
}
vfs_node_t *node = vfs_node_get(&lr);
if (!node) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
fibril_rwlock_read_unlock(&namespace_rwlock);
 
int fs_phone = vfs_grab_phone(node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev_handle,
node->index, false, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
ipcarg_t rv;
async_wait_for(msg, &rv);
vfs_release_phone(fs_phone);
 
ipc_answer_0(rid, rv);
 
vfs_node_put(node);
}
 
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
{
int mode = IPC_GET_ARG1(*request);
1001,6 → 1055,9
return;
}
path[len] = '\0';
 
/* Ignore mode for now. */
(void) mode;
fibril_rwlock_write_lock(&namespace_rwlock);
int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
1050,7 → 1107,7
/*
* The name has already been unlinked by vfs_lookup_internal().
* We have to get and put the VFS node to ensure that it is
* VFS_DESTROY'ed after the last reference to it is dropped.
* VFS_OUT_DESTROY'ed after the last reference to it is dropped.
*/
vfs_node_t *node = vfs_node_get(&lr);
fibril_mutex_lock(&nodes_mutex);
/branches/network/uspace/srv/vfs/vfs.h
198,14 → 198,15
extern void vfs_mount(ipc_callid_t, ipc_call_t *);
extern void vfs_open(ipc_callid_t, ipc_call_t *);
extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
extern void vfs_device(ipc_callid_t, ipc_call_t *);
extern void vfs_sync(ipc_callid_t, ipc_call_t *);
extern void vfs_node(ipc_callid_t, ipc_call_t *);
extern void vfs_close(ipc_callid_t, ipc_call_t *);
extern void vfs_read(ipc_callid_t, ipc_call_t *);
extern void vfs_write(ipc_callid_t, ipc_call_t *);
extern void vfs_seek(ipc_callid_t, ipc_call_t *);
extern void vfs_truncate(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_stat(ipc_callid_t, ipc_call_t *);
extern void vfs_mkdir(ipc_callid_t, ipc_call_t *);
extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
extern void vfs_rename(ipc_callid_t, ipc_call_t *);
/branches/network/uspace/srv/vfs/vfs_node.c
129,7 → 129,7
*/
int phone = vfs_grab_phone(node->fs_handle);
ipcarg_t rc;
rc = async_req_2_0(phone, VFS_DESTROY,
rc = async_req_2_0(phone, VFS_OUT_DESTROY,
(ipcarg_t)node->dev_handle, (ipcarg_t)node->index);
assert(rc == EOK);
vfs_release_phone(phone);
/branches/network/uspace/srv/vfs/vfs_lookup.c
159,7 → 159,7
 
ipc_call_t answer;
int phone = vfs_grab_phone(root->fs_handle);
aid_t req = async_send_5(phone, VFS_LOOKUP, (ipcarg_t) first,
aid_t req = async_send_5(phone, VFS_OUT_LOOKUP, (ipcarg_t) first,
(ipcarg_t) (first + len - 1) % PLB_SIZE,
(ipcarg_t) root->dev_handle, (ipcarg_t) lflag, (ipcarg_t) index,
&answer);
204,7 → 204,7
int phone = vfs_grab_phone(result->triplet.fs_handle);
ipc_call_t answer;
aid_t req = async_send_2(phone, VFS_OPEN_NODE,
aid_t req = async_send_2(phone, VFS_OUT_OPEN_NODE,
(ipcarg_t) result->triplet.dev_handle,
(ipcarg_t) result->triplet.index, &answer);