Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2634 → Rev 2635

/trunk/kernel/generic/include/ipc/sysipc.h
52,7 → 52,7
unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec,
int nonblocking);
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, int mode);
unative_t method, unative_t arg1, unative_t arg2, int mode);
unative_t sys_ipc_hangup(int phoneid);
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
irq_code_t *ucode);
/trunk/kernel/generic/include/ipc/ipc.h
138,7 → 138,7
* - sys_connect_me_to - send a synchronous message to name server
* indicating that it wants to be connected to some
* service
* - arg1/2 are user specified, arg3 contains
* - arg1/2/3 are user specified, arg5 contains
* address of the phone that should be connected
* (TODO: it leaks to userspace)
* recipient - if ipc_answer == 0, then accept connection
/trunk/kernel/generic/src/ipc/sysipc.c
191,7 → 191,7
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
/* If the users accepted call, connect */
if (!IPC_GET_RETVAL(answer->data)) {
ipc_phone_connect((phone_t *) IPC_GET_ARG3(*olddata),
ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata),
&TASK->answerbox);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_SEND) {
270,7 → 270,7
if (newphid < 0)
return ELIMIT;
/* Set arg3 for server */
IPC_SET_ARG3(call->data, (unative_t) &TASK->phones[newphid]);
IPC_SET_ARG5(call->data, (unative_t) &TASK->phones[newphid]);
call->flags |= IPC_CALL_CONN_ME_TO;
call->priv = newphid;
break;
318,7 → 318,7
if (IPC_GET_RETVAL(call->data))
phone_dealloc(call->priv);
else
IPC_SET_ARG3(call->data, call->priv);
IPC_SET_ARG5(call->data, call->priv);
}
}
 
552,7 → 552,7
* system IPC
*/
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, int mode)
unative_t method, unative_t arg1, unative_t arg2, int mode)
{
call_t *call;
phone_t *phone;
577,19 → 577,22
 
/*
* Userspace is not allowed to change method of system methods on
* forward, allow changing ARG1 and ARG2 by means of method and arg1.
* forward, allow changing ARG1, ARG2 and ARG3 by means of method,
* arg1 and arg2.
* If the method is immutable, don't change anything.
*/
if (!method_is_immutable(IPC_GET_METHOD(call->data))) {
if (method_is_system(IPC_GET_METHOD(call->data))) {
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
phone_dealloc(IPC_GET_ARG3(call->data));
phone_dealloc(IPC_GET_ARG5(call->data));
 
IPC_SET_ARG1(call->data, method);
IPC_SET_ARG2(call->data, arg1);
IPC_SET_ARG3(call->data, arg2);
} else {
IPC_SET_METHOD(call->data, method);
IPC_SET_ARG1(call->data, arg1);
IPC_SET_ARG2(call->data, arg2);
}
}
 
/trunk/uspace/app/tester/ipc/connect.c
46,7 → 46,7
return "Currently cannot connect to myself, update test";
printf("Connecting to %d..", svc);
phid = ipc_connect_me_to(PHONE_NS, svc, 0);
phid = ipc_connect_me_to(PHONE_NS, svc, 0, 0);
if (phid > 0) {
printf("phoneid: %d\n", phid);
phones[phid] = 1;
/trunk/uspace/app/tester/devmap/devmap1.c
35,24 → 35,112
#include <../../../srv/devmap/devmap.h>
#include "../tester.h"
 
#include <time.h>
 
#define TEST_DEVICE1 "TestDevice1"
#define TEST_DEVICE2 "TestDevice2"
 
/** Handle requests from clients
*
*/
static void driver_client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
int retval;
printf("connected: method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(*icall),
IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), IPC_GET_ARG3(*icall));
 
printf("driver_client_connection.\n");
ipc_answer_0(iid, EOK);
 
/* Ignore parameters, the connection is already opened */
while (1) {
callid = async_get_call(&call);
retval = EOK;
printf("method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(call),
IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call));
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
/* TODO: Handle hangup */
return;
default:
printf("Unknown device method %u.\n", IPC_GET_METHOD(call));
retval = ENOENT;
}
ipc_answer_0(callid, retval);
}
return;
}
 
static int device_client_fibril(void *arg)
{
int handle;
int device_phone;
 
handle = (int)arg;
 
device_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, \
DEVMAP_CONNECT_TO_DEVICE, handle);
 
if (device_phone < 0) {
printf("Failed to connect to devmap as client (handle = %u).\n",
handle);
return -1;
}
/*
* device_phone = (int) IPC_GET_ARG3(answer);
*/
printf("Connected to device.\n");
ipc_call_sync_1_0(device_phone, 1024, 1025);
/*
* ipc_hangup(device_phone);
*/
ipc_hangup(device_phone);
 
return EOK;
}
 
/** Communication test with device.
* @param handle handle to tested instance.
*/
static int device_client(int handle)
{
/* fid_t fid;
ipc_call_t call;
ipc_callid_t callid;
 
fid = fibril_create(device_client_fibril, (void *)handle);
fibril_add_ready(fid);
 
*/
return EOK;
}
 
/**
*
*/
static int driver_register(char *name)
{
int retval;
ipcarg_t retval;
aid_t req;
ipc_call_t answer;
int phone;
ipcarg_t callback_phonehash;
 
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER);
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_DRIVER, 0);
 
while (phone < 0) {
usleep(100000);
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER);
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_DRIVER, 0);
}
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
 
retval = ipc_data_send(phone, (char *)name, strlen(name));
retval = ipc_data_send(phone, (char *)name, strlen(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
59,14 → 147,63
return -1;
}
 
async_set_client_connection(driver_client_connection);
 
ipc_connect_to_me(phone, 0, 0, &callback_phonehash);
 
async_wait_for(req, NULL);
/*
if (NULL == async_new_connection(callback_phonehash, 0, NULL,
driver_client_connection)) {
printf("Failed to create new fibril.\n");
async_wait_for(req, NULL);
return -1;
}
*/
async_wait_for(req, &retval);
printf("Driver '%s' registered.\n", name);
 
return phone;
}
 
static int device_get_handle(int driver_phone, char *name, int *handle)
{
ipcarg_t retval;
aid_t req;
ipc_call_t answer;
 
req = async_send_2(driver_phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0, &answer);
 
retval = ipc_data_send(driver_phone, name, strlen(name) + 1);
 
if (retval != EOK) {
printf("Failed to send device name '%s'.\n", name);
async_wait_for(req, NULL);
return retval;
}
 
async_wait_for(req, &retval);
 
if (NULL != handle) {
*handle = -1;
}
 
if (EOK == retval) {
if (NULL != handle) {
*handle = (int) IPC_GET_ARG1(answer);
}
printf("Device '%s' has handle %u.\n", name, (int) IPC_GET_ARG1(answer));
} else {
printf("Failed to get handle for device '%s'.\n", name);
}
 
return retval;
}
 
/** Register new device.
* @param driver_phone
* @param name Device name.
* @param handle Output variable. Handle to the created instance of device.
*/
static int device_register(int driver_phone, char *name, int *handle)
{
ipcarg_t retval;
75,7 → 212,7
 
req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
 
retval = ipc_data_send(driver_phone, (char *)name, strlen(name));
retval = ipc_data_send(driver_phone, (char *)name, strlen(name) + 1);
 
if (retval != EOK) {
printf("Failed to send device name '%s'.\n", name);
110,6 → 247,7
int dev1_handle;
int dev2_handle;
int dev3_handle;
int handle;
 
/* Register new driver */
driver_phone = driver_register("TestDriver");
119,33 → 257,48
}
 
/* Register new device dev1*/
if (EOK != device_register(driver_phone, "TestDevice1", &dev1_handle)) {
if (EOK != device_register(driver_phone, TEST_DEVICE1, &dev1_handle)) {
ipc_hangup(driver_phone);
return "Error: cannot register device.\n";
}
/* TODO: get handle for dev1*/
 
/* TODO: get handle for dev2 (Should fail unless device is already
/* Get handle for dev2 (Should fail unless device is already
* registered by someone else)
*/
if (EOK == device_get_handle(driver_phone, TEST_DEVICE2, &handle)) {
ipc_hangup(driver_phone);
return "Error: got handle for dev2 before it was registered.\n";
}
 
/* Register new device dev2*/
if (EOK != device_register(driver_phone, "TestDevice2", &dev2_handle)) {
if (EOK != device_register(driver_phone, TEST_DEVICE2, &dev2_handle)) {
ipc_hangup(driver_phone);
return "Error: cannot register device dev2.\n";
}
 
 
/* Register again device dev1 */
if (EOK == device_register(driver_phone, "TestDevice1", &dev3_handle)) {
if (EOK == device_register(driver_phone, TEST_DEVICE1, &dev3_handle)) {
return "Error: dev1 registered twice.\n";
}
 
/* TODO: get handle for dev2 */
/* Get handle for dev1*/
if (EOK != device_get_handle(driver_phone, TEST_DEVICE1, &handle)) {
ipc_hangup(driver_phone);
return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
}
 
/* TODO: */
if (handle != dev1_handle) {
ipc_hangup(driver_phone);
return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
}
 
if (EOK != device_client(dev1_handle)) {
ipc_hangup(driver_phone);
return "Error: failed client test for 'DEVMAP_DEVICE1'.\n";
}
 
/* TODO: */
 
ipc_hangup(driver_phone);
 
return NULL;
/trunk/uspace/lib/libc/include/ipc/ipc.h
253,12 → 253,12
ipc_async_callback_t callback, int can_preempt);
 
extern int ipc_connect_to_me(int phoneid, int arg1, int arg2, ipcarg_t *phone);
extern int ipc_connect_me_to(int phoneid, int arg1, int arg2);
extern int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3);
extern int ipc_hangup(int phoneid);
extern int ipc_register_irq(int inr, int devno, int method, irq_code_t *code);
extern int ipc_unregister_irq(int inr, int devno);
extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method,
ipcarg_t arg1, int mode);
ipcarg_t arg1, ipcarg_t arg2, int mode);
extern int ipc_data_send(int phoneid, void *src, size_t size);
extern int ipc_data_receive(ipc_callid_t *callid, void **dst, size_t *size);
extern ipcarg_t ipc_data_deliver(ipc_callid_t callid, void *dst, size_t size);
/trunk/uspace/lib/libc/generic/ipc.c
587,16 → 587,17
* @param phoneid Phone handle used for contacting the other side.
* @param arg1 User defined argument.
* @param arg2 User defined argument.
* @param arg3 User defined argument.
*
* @return New phone handle on success or a negative error code.
*/
int ipc_connect_me_to(int phoneid, int arg1, int arg2)
int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
{
ipcarg_t newphid;
int res;
 
res = ipc_call_sync_2_3(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, NULL,
NULL, &newphid);
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
NULL, NULL, NULL, NULL, &newphid);
if (res)
return res;
return newphid;
646,20 → 647,21
* @param phoneid Phone handle to use for forwarding.
* @param method New method for the forwarded call.
* @param arg1 New value of the first argument for the forwarded call.
* @param arg2 New value of the second argument for the forwarded call.
* @param mode Flags specifying mode of the forward operation.
*
* @return Zero on success or an error code.
*
* For non-system methods, the old method and arg1 are rewritten by the new
* values. For system methods, the new method and arg1 are written to the old
* arg1 and arg2, respectivelly. Calls with immutable methods are forwarded
* verbatim.
* values. For system methods, the new method, arg1 and arg2 are written
* to the old arg1, arg2 and arg3, respectivelly. Calls with immutable
* methods are forwarded verbatim.
*/
int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method,
ipcarg_t arg1, int mode)
ipcarg_t arg1, ipcarg_t arg2, int mode)
{
return __SYSCALL5(SYS_IPC_FORWARD_FAST, callid, phoneid, method, arg1,
mode);
return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, method, arg1,
arg2, mode);
}
 
/** Wrapper for making IPC_M_DATA_SEND calls.
/trunk/uspace/lib/libc/generic/async.c
538,7 → 538,7
switch (IPC_GET_METHOD(*call)) {
case IPC_M_CONNECT_ME_TO:
/* Open new connection with fibril etc. */
async_new_connection(IPC_GET_ARG3(*call), callid, call,
async_new_connection(IPC_GET_ARG5(*call), callid, call,
client_connection);
return;
}
/trunk/uspace/lib/libc/generic/io/stream.c
96,7 → 96,7
if (console_phone < 0) {
while ((console_phone = ipc_connect_me_to(PHONE_NS,
SERVICE_CONSOLE, 0)) < 0) {
SERVICE_CONSOLE, 0, 0)) < 0) {
usleep(10000);
}
}
115,7 → 115,7
 
if (console_phone < 0) {
while ((console_phone = ipc_connect_me_to(PHONE_NS,
SERVICE_CONSOLE, 0)) < 0) {
SERVICE_CONSOLE, 0, 0)) < 0) {
usleep(10000);
}
}
/trunk/uspace/srv/ns/ns.c
212,8 → 212,8
return ENOENT;
}
hs = hash_table_get_instance(hlp, hashed_service_t, link);
return ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), 0,
IPC_FF_NONE);
return ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
}
 
/** Compute hash index into NS hash table.
/trunk/uspace/srv/console/console.c
482,10 → 482,10
/* Connect to keyboard driver */
 
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0);
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
while (kbd_phone < 0) {
usleep(10000);
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0);
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
}
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, &phonehash) != 0)
494,10 → 494,10
/* Connect to framebuffer driver */
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0);
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0);
while (fb_info.phone < 0) {
usleep(10000);
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0);
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0);
}
/* Save old kernel screen */
/trunk/uspace/srv/fs/fat/fat.c
126,10 → 126,10
 
printf("FAT: HelenOS FAT file system server.\n");
 
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0);
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
while (vfs_phone < EOK) {
usleep(10000);
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0);
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
}
/*
/trunk/uspace/srv/devmap/devmap.h
41,7 → 41,6
typedef enum {
DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
DEVMAP_DRIVER_UNREGISTER,
DEVMAP_DEVICE_CONNECT_ME_TO,
DEVMAP_DEVICE_REGISTER,
DEVMAP_DEVICE_UNREGISTER,
DEVMAP_DEVICE_GET_NAME,
82,12 → 81,18
devmap_driver_t *driver;
} devmap_device_t;
 
/** Interface provided by DevMap.
*
/** Interface provided by devmap.
* Every process that connects to devmap must ask one of following
* interfaces otherwise connection will be refused.
*/
typedef enum {
DEVMAP_DRIVER = 1,
DEVMAP_CLIENT
/** Connect as device driver */
DEVMAP_DRIVER = 1,
/** Connect as client */
DEVMAP_CLIENT,
/** Create new connection to instance of device that
* is specified by second argument of call. */
DEVMAP_CONNECT_TO_DEVICE
} devmap_interface_t;
 
#endif
/trunk/uspace/srv/devmap/devmap.c
448,8 → 448,6
/** Connect client to the device.
* Find device driver owning requested device and forward
* the message to it.
*
*
*/
static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
{
459,7 → 457,7
/*
* Get handle from request
*/
handle = IPC_GET_ARG1(*call);
handle = IPC_GET_ARG2(*call);
dev = devmap_device_find_handle(handle);
 
if (NULL == dev) {
469,9 → 467,8
return;
}
 
/* FIXME: is this correct method how to pass argument on forwarding ?*/
ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle),
0, IPC_FF_NONE);
IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
return;
}
 
669,13 → 666,6
cont = false;
continue; /* Exit thread */
 
case DEVMAP_DEVICE_CONNECT_ME_TO:
/* Connect client to selected device */
printf("DEVMAP: connect to device %d.\n",
IPC_GET_ARG1(call));
devmap_forward(callid, &call);
break;
 
case DEVMAP_DEVICE_GET_HANDLE:
devmap_get_handle(callid, &call);
 
709,6 → 699,12
case DEVMAP_CLIENT:
devmap_connection_client(iid, icall);
break;
case DEVMAP_CONNECT_TO_DEVICE:
/* Connect client to selected device */
printf("DEVMAP: connect to device %d.\n",
IPC_GET_ARG2(*icall));
devmap_forward(iid, icall);
break;
default:
ipc_answer_0(iid, ENOENT); /* No such interface */
printf("DEVMAP: Unknown interface %u.\n",
/trunk/uspace/srv/vfs/vfs_read.c
96,7 → 96,7
* The call will be routed as if sent by ourselves.
*/
ipc_forward_fast(callid, fs_phone, IPC_GET_METHOD(call),
IPC_GET_ARG1(call), IPC_FF_ROUTE_FROM_ME);
IPC_GET_ARG1(call), 0, IPC_FF_ROUTE_FROM_ME);
 
vfs_release_phone(fs_phone);