Subversion Repositories HelenOS

Rev

Rev 2594 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2594 cejka 1
/*
2
 * Copyright (c) 2007 Josef Cejka
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <ipc/ipc.h>
32
#include <ipc/services.h>
33
#include <async.h>
34
#include <errno.h>
35
#include <../../../srv/devmap/devmap.h>
36
#include "../tester.h"
37
 
2635 cejka 38
#include <time.h>
39
 
40
#define TEST_DEVICE1 "TestDevice1"
41
#define TEST_DEVICE2 "TestDevice2"
42
 
43
/** Handle requests from clients
44
 *
45
 */
46
static void driver_client_connection(ipc_callid_t iid, ipc_call_t *icall)
47
{
48
    ipc_callid_t callid;
49
    ipc_call_t call;
50
    int retval;
51
 
52
    printf("connected: method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(*icall),
53
        IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), IPC_GET_ARG3(*icall));
54
 
55
    printf("driver_client_connection.\n");
56
    ipc_answer_0(iid, EOK);
57
 
58
    /* Ignore parameters, the connection is already opened */
59
    while (1) {
60
        callid = async_get_call(&call);
61
        retval = EOK;
62
        printf("method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(call),
63
            IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call));
64
        switch (IPC_GET_METHOD(call)) {
65
        case IPC_M_PHONE_HUNGUP:
66
            /* TODO: Handle hangup */
67
            return;
68
        default:
69
            printf("Unknown device method %u.\n", IPC_GET_METHOD(call));
70
            retval = ENOENT;
71
        }
72
        ipc_answer_0(callid, retval);
73
    }
74
    return;
75
}
76
 
77
static int device_client_fibril(void *arg)
78
{
79
    int handle;
80
    int device_phone;
81
 
82
    handle = (int)arg;
83
 
84
    device_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, \
85
        DEVMAP_CONNECT_TO_DEVICE, handle);
86
 
87
    if (device_phone < 0) {
88
        printf("Failed to connect to devmap as client (handle = %u).\n",
89
            handle);
90
        return -1;
91
    }
92
/* 
93
 *  device_phone = (int) IPC_GET_ARG3(answer);
94
 */
95
    printf("Connected to device.\n");
96
    ipc_call_sync_1_0(device_phone, 1024, 1025);
97
/*
98
 * ipc_hangup(device_phone);
99
 */
100
    ipc_hangup(device_phone);
101
 
102
    return EOK;
103
}
104
 
105
/** Communication test with device.
106
 * @param handle handle to tested instance.
107
 */
108
static int device_client(int handle)
109
{
110
/*  fid_t fid;
111
    ipc_call_t call;
112
    ipc_callid_t callid;
113
 
114
    fid = fibril_create(device_client_fibril, (void *)handle);
115
    fibril_add_ready(fid);
116
 
117
*/
118
    return EOK;
119
}
120
 
121
/**
122
 *
123
 */
2594 cejka 124
static int driver_register(char *name)
125
{
2635 cejka 126
    ipcarg_t retval;
2594 cejka 127
    aid_t req;
128
    ipc_call_t answer;
129
    int phone;
130
    ipcarg_t callback_phonehash;
131
 
2635 cejka 132
    phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
133
        DEVMAP_DRIVER, 0);
2594 cejka 134
 
135
    while (phone < 0) {
136
        usleep(100000);
2635 cejka 137
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
138
            DEVMAP_DRIVER, 0);
2594 cejka 139
    }
140
 
141
    req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
142
 
2635 cejka 143
    retval = ipc_data_send(phone, (char *)name, strlen(name) + 1);
2594 cejka 144
 
145
    if (retval != EOK) {
146
        async_wait_for(req, NULL);
147
        return -1;
148
    }
149
 
2635 cejka 150
    async_set_client_connection(driver_client_connection);
151
 
2594 cejka 152
    ipc_connect_to_me(phone, 0, 0, &callback_phonehash);
2635 cejka 153
/* 
154
    if (NULL == async_new_connection(callback_phonehash, 0, NULL,
155
            driver_client_connection)) {
156
        printf("Failed to create new fibril.\n");  
157
        async_wait_for(req, NULL);
158
        return -1;
159
    }
160
*/
161
    async_wait_for(req, &retval);
2594 cejka 162
    printf("Driver '%s' registered.\n", name);
163
 
164
    return phone;
165
}
166
 
2635 cejka 167
static int device_get_handle(int driver_phone, char *name, int *handle)
168
{
169
    ipcarg_t retval;
170
    aid_t req;
171
    ipc_call_t answer;
172
 
173
    req = async_send_2(driver_phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0, &answer);
174
 
175
    retval = ipc_data_send(driver_phone, name, strlen(name) + 1);
176
 
177
    if (retval != EOK) {
178
        printf("Failed to send device name '%s'.\n", name);
179
        async_wait_for(req, NULL);
180
        return retval;
181
    }
182
 
183
    async_wait_for(req, &retval);
184
 
185
    if (NULL != handle) {
186
        *handle = -1;
187
    }
188
 
189
    if (EOK == retval) {
190
 
191
        if (NULL != handle) {
192
            *handle = (int) IPC_GET_ARG1(answer);
193
        }
194
        printf("Device '%s' has handle %u.\n", name, (int) IPC_GET_ARG1(answer));
195
    } else {
196
        printf("Failed to get handle for device '%s'.\n", name);
197
    }
198
 
199
    return retval;
200
}
201
 
202
/** Register new device.
203
 * @param driver_phone
204
 * @param name Device name.
205
 * @param handle Output variable. Handle to the created instance of device.
206
 */
2594 cejka 207
static int device_register(int driver_phone, char *name, int *handle)
208
{
209
    ipcarg_t retval;
210
    aid_t req;
211
    ipc_call_t answer;
212
 
213
    req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
214
 
2635 cejka 215
    retval = ipc_data_send(driver_phone, (char *)name, strlen(name) + 1);
2594 cejka 216
 
217
    if (retval != EOK) {
218
        printf("Failed to send device name '%s'.\n", name);
219
        async_wait_for(req, NULL);
220
        return retval;
221
    }
222
 
223
    async_wait_for(req, &retval);
224
 
225
    if (NULL != handle) {
226
        *handle = -1;
227
    }
228
 
229
    if (EOK == retval) {
230
 
231
        if (NULL != handle) {
232
            *handle = (int) IPC_GET_ARG1(answer);
233
        }
234
        printf("Device registered with handle %u.\n", (int) IPC_GET_ARG1(answer));
235
    }
236
 
237
    return retval;
238
}
239
 
240
/** Test DevMap from the driver's point of view.
241
 *
242
 *
243
 */
244
char * test_devmap1(bool quiet)
245
{
246
    int driver_phone;
247
    int dev1_handle;
248
    int dev2_handle;
249
    int dev3_handle;
2635 cejka 250
    int handle;
2594 cejka 251
 
252
    /* Register new driver */
253
    driver_phone = driver_register("TestDriver");
254
 
255
    if (driver_phone < 0) {
256
        return "Error: Cannot register driver.\n"; 
257
    }
258
 
259
    /* Register new device dev1*/
2635 cejka 260
    if (EOK != device_register(driver_phone, TEST_DEVICE1, &dev1_handle)) {
2594 cejka 261
        ipc_hangup(driver_phone);
262
        return "Error: cannot register device.\n";
263
    }
264
 
2635 cejka 265
    /* Get handle for dev2 (Should fail unless device is already
2594 cejka 266
     * registered by someone else)
267
     */
2635 cejka 268
    if (EOK == device_get_handle(driver_phone, TEST_DEVICE2, &handle)) {
269
        ipc_hangup(driver_phone);
270
        return "Error: got handle for dev2 before it was registered.\n";
271
    }
2594 cejka 272
 
273
    /* Register new device dev2*/
2635 cejka 274
    if (EOK != device_register(driver_phone, TEST_DEVICE2, &dev2_handle)) {
2594 cejka 275
        ipc_hangup(driver_phone);
276
        return "Error: cannot register device dev2.\n";
277
    }
278
 
279
    /* Register again device dev1 */
2635 cejka 280
    if (EOK == device_register(driver_phone, TEST_DEVICE1, &dev3_handle)) {
2594 cejka 281
        return "Error: dev1 registered twice.\n";
282
    }
283
 
2635 cejka 284
    /* Get handle for dev1*/
285
    if (EOK != device_get_handle(driver_phone, TEST_DEVICE1, &handle)) {
286
        ipc_hangup(driver_phone);
287
        return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
288
    }
2594 cejka 289
 
2635 cejka 290
    if (handle != dev1_handle) {
291
        ipc_hangup(driver_phone);
292
        return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
293
    }
2594 cejka 294
 
2635 cejka 295
    if (EOK != device_client(dev1_handle)) {
296
        ipc_hangup(driver_phone);
297
        return "Error: failed client test for 'DEVMAP_DEVICE1'.\n";
298
    }
299
 
300
    /* TODO: */
301
 
2594 cejka 302
    ipc_hangup(driver_phone);
303
 
304
    return NULL;
305
}
306
 
307
char *test_devmap2(bool quiet)
308
{
309
    /*TODO: Full automatic test */
310
    return NULL;
311
}
312
 
313
char *test_devmap3(bool quiet)
314
{
315
    /* TODO: allow user to call test functions in random order */
316
    return NULL;
317
}
318