~jakub/helenos/ia64-revival

« back to all changes in this revision

Viewing changes to uspace/drv/test/test1/test1.c

  • Committer: Jakub Jermar
  • Date: 2012-02-18 16:47:38 UTC
  • mfrom: (527.1.874 HelenOS.mainline)
  • Revision ID: jakub@jermar.eu-20120218164738-abnijv1f5ckddwd9
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (c) 2010 Vojtech Horky
 
3
 * Copyright (c) 2011 Jiri Svoboda
3
4
 * All rights reserved.
4
5
 *
5
6
 * Redistribution and use in source and binary forms, with or without
38
39
 
39
40
#include "test1.h"
40
41
 
41
 
static int test1_add_device(ddf_dev_t *dev);
 
42
static int test1_dev_add(ddf_dev_t *dev);
 
43
static int test1_dev_remove(ddf_dev_t *dev);
 
44
static int test1_dev_gone(ddf_dev_t *dev);
 
45
static int test1_fun_online(ddf_fun_t *fun);
 
46
static int test1_fun_offline(ddf_fun_t *fun);
42
47
 
43
48
static driver_ops_t driver_ops = {
44
 
        .add_device = &test1_add_device
 
49
        .dev_add = &test1_dev_add,
 
50
        .dev_remove = &test1_dev_remove,
 
51
        .dev_gone = &test1_dev_gone,
 
52
        .fun_online = &test1_fun_online,
 
53
        .fun_offline = &test1_fun_offline
45
54
};
46
55
 
47
56
static driver_t test1_driver = {
49
58
        .driver_ops = &driver_ops
50
59
};
51
60
 
 
61
typedef struct {
 
62
        ddf_fun_t *fun_a;
 
63
        ddf_fun_t *clone;
 
64
        ddf_fun_t *child;
 
65
} test1_t;
 
66
 
52
67
/** Register child and inform user about it.
53
68
 *
54
69
 * @param parent Parent device.
59
74
 */
60
75
static int register_fun_verbose(ddf_dev_t *parent, const char *message,
61
76
    const char *name, const char *match_id, int match_score,
62
 
    int expected_rc)
 
77
    int expected_rc, ddf_fun_t **pfun)
63
78
{
64
79
        ddf_fun_t *fun = NULL;
65
80
        int rc;
102
117
                ddf_fun_destroy(fun);
103
118
        }
104
119
 
 
120
        if (pfun != NULL)
 
121
                *pfun = fun;
 
122
 
105
123
        return rc;
106
124
}
107
125
 
122
140
 * @param dev New device.
123
141
 * @return Error code reporting success of the operation.
124
142
 */
125
 
static int test1_add_device(ddf_dev_t *dev)
 
143
static int test1_dev_add(ddf_dev_t *dev)
126
144
{
127
145
        ddf_fun_t *fun_a;
 
146
        test1_t *test1;
128
147
        int rc;
129
148
 
130
 
        ddf_msg(LVL_DEBUG, "add_device(name=\"%s\", handle=%d)",
 
149
        ddf_msg(LVL_DEBUG, "dev_add(name=\"%s\", handle=%d)",
131
150
            dev->name, (int) dev->handle);
132
151
 
 
152
        test1 = ddf_dev_data_alloc(dev, sizeof(test1_t));
 
153
        if (test1 == NULL) {
 
154
                ddf_msg(LVL_ERROR, "Failed allocating soft state.\n");
 
155
                return ENOMEM;
 
156
        }
 
157
 
133
158
        fun_a = ddf_fun_create(dev, fun_exposed, "a");
134
159
        if (fun_a == NULL) {
135
160
                ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
136
161
                return ENOMEM;
137
162
        }
138
163
 
 
164
        test1->fun_a = fun_a;
 
165
 
139
166
        rc = ddf_fun_bind(fun_a);
140
167
        if (rc != EOK) {
141
168
                ddf_msg(LVL_ERROR, "Failed binding function 'a'.");
 
169
                ddf_fun_destroy(fun_a);
142
170
                return rc;
143
171
        }
144
172
 
150
178
        } else if (str_cmp(dev->name, "test1") == 0) {
151
179
                (void) register_fun_verbose(dev,
152
180
                    "cloning myself ;-)", "clone",
153
 
                    "virtual&test1", 10, EOK);
 
181
                    "virtual&test1", 10, EOK, &test1->clone);
154
182
                (void) register_fun_verbose(dev,
155
183
                    "cloning myself twice ;-)", "clone",
156
 
                    "virtual&test1", 10, EEXISTS);
 
184
                    "virtual&test1", 10, EEXISTS, NULL);
157
185
        } else if (str_cmp(dev->name, "clone") == 0) {
158
186
                (void) register_fun_verbose(dev,
159
187
                    "run by the same task", "child",
160
 
                    "virtual&test1&child", 10, EOK);
 
188
                    "virtual&test1&child", 10, EOK, &test1->child);
161
189
        }
162
190
 
163
191
        ddf_msg(LVL_DEBUG, "Device `%s' accepted.", dev->name);
165
193
        return EOK;
166
194
}
167
195
 
 
196
static int fun_remove(ddf_fun_t *fun, const char *name)
 
197
{
 
198
        int rc;
 
199
 
 
200
        ddf_msg(LVL_DEBUG, "fun_remove(%p, '%s')", fun, name);
 
201
        rc = ddf_fun_offline(fun);
 
202
        if (rc != EOK) {
 
203
                ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name);
 
204
                return rc;
 
205
        }
 
206
 
 
207
        rc = ddf_fun_unbind(fun);
 
208
        if (rc != EOK) {
 
209
                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
 
210
                return rc;
 
211
        }
 
212
 
 
213
        ddf_fun_destroy(fun);
 
214
        return EOK;
 
215
}
 
216
 
 
217
static int fun_unbind(ddf_fun_t *fun, const char *name)
 
218
{
 
219
        int rc;
 
220
 
 
221
        ddf_msg(LVL_DEBUG, "fun_unbind(%p, '%s')", fun, name);
 
222
        rc = ddf_fun_unbind(fun);
 
223
        if (rc != EOK) {
 
224
                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
 
225
                return rc;
 
226
        }
 
227
 
 
228
        ddf_fun_destroy(fun);
 
229
        return EOK;
 
230
}
 
231
 
 
232
static int test1_dev_remove(ddf_dev_t *dev)
 
233
{
 
234
        test1_t *test1 = (test1_t *)dev->driver_data;
 
235
        int rc;
 
236
 
 
237
        ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev);
 
238
 
 
239
        if (test1->fun_a != NULL) {
 
240
                rc = fun_remove(test1->fun_a, "a");
 
241
                if (rc != EOK)
 
242
                        return rc;
 
243
        }
 
244
 
 
245
        if (test1->clone != NULL) {
 
246
                rc = fun_remove(test1->clone, "clone");
 
247
                if (rc != EOK)
 
248
                        return rc;
 
249
        }
 
250
 
 
251
        if (test1->child != NULL) {
 
252
                rc = fun_remove(test1->child, "child");
 
253
                if (rc != EOK)
 
254
                        return rc;
 
255
        }
 
256
 
 
257
        return EOK;
 
258
}
 
259
 
 
260
static int test1_dev_gone(ddf_dev_t *dev)
 
261
{
 
262
        test1_t *test1 = (test1_t *)dev->driver_data;
 
263
        int rc;
 
264
 
 
265
        ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev);
 
266
 
 
267
        if (test1->fun_a != NULL) {
 
268
                rc = fun_unbind(test1->fun_a, "a");
 
269
                if (rc != EOK)
 
270
                        return rc;
 
271
        }
 
272
 
 
273
        if (test1->clone != NULL) {
 
274
                rc = fun_unbind(test1->clone, "clone");
 
275
                if (rc != EOK)
 
276
                        return rc;
 
277
        }
 
278
 
 
279
        if (test1->child != NULL) {
 
280
                rc = fun_unbind(test1->child, "child");
 
281
                if (rc != EOK)
 
282
                        return rc;
 
283
        }
 
284
 
 
285
        return EOK;
 
286
}
 
287
 
 
288
static int test1_fun_online(ddf_fun_t *fun)
 
289
{
 
290
        ddf_msg(LVL_DEBUG, "test1_fun_online()");
 
291
        return ddf_fun_online(fun);
 
292
}
 
293
 
 
294
static int test1_fun_offline(ddf_fun_t *fun)
 
295
{
 
296
        ddf_msg(LVL_DEBUG, "test1_fun_offline()");
 
297
        return ddf_fun_offline(fun);
 
298
}
 
299
 
168
300
int main(int argc, char *argv[])
169
301
{
170
302
        printf(NAME ": HelenOS test1 virtual device driver\n");