/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); |