00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00040 #include <assert.h>
00041 #include <stdio.h>
00042 #include <errno.h>
00043 #include <bool.h>
00044 #include <fibril_synch.h>
00045 #include <stdlib.h>
00046 #include <str.h>
00047 #include <str_error.h>
00048 #include <ctype.h>
00049 #include <macros.h>
00050 #include <inttypes.h>
00051 #include <sysinfo.h>
00052
00053 #include <ddf/driver.h>
00054 #include <ddf/log.h>
00055 #include <devman.h>
00056 #include <ipc/devman.h>
00057
00058 #define NAME "root"
00059
00060 #define PLATFORM_FUN_NAME "hw"
00061 #define PLATFORM_FUN_MATCH_ID_FMT "platform/%s"
00062 #define PLATFORM_FUN_MATCH_SCORE 100
00063
00064 #define VIRTUAL_FUN_NAME "virt"
00065 #define VIRTUAL_FUN_MATCH_ID "rootvirt"
00066 #define VIRTUAL_FUN_MATCH_SCORE 100
00067
00068 static int root_add_device(ddf_dev_t *dev);
00069
00071 static driver_ops_t root_ops = {
00072 .add_device = &root_add_device
00073 };
00074
00076 static driver_t root_driver = {
00077 .name = NAME,
00078 .driver_ops = &root_ops
00079 };
00080
00086 static int add_virtual_root_fun(ddf_dev_t *dev)
00087 {
00088 const char *name = VIRTUAL_FUN_NAME;
00089 ddf_fun_t *fun;
00090 int rc;
00091
00092 ddf_msg(LVL_DEBUG, "Adding new function for virtual devices. "
00093 "Function node is `%s' (%d %s)", name,
00094 VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID);
00095
00096 fun = ddf_fun_create(dev, fun_inner, name);
00097 if (fun == NULL) {
00098 ddf_msg(LVL_ERROR, "Failed creating function %s", name);
00099 return ENOMEM;
00100 }
00101
00102 rc = ddf_fun_add_match_id(fun, VIRTUAL_FUN_MATCH_ID,
00103 VIRTUAL_FUN_MATCH_SCORE);
00104 if (rc != EOK) {
00105 ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s",
00106 name);
00107 ddf_fun_destroy(fun);
00108 return rc;
00109 }
00110
00111 rc = ddf_fun_bind(fun);
00112 if (rc != EOK) {
00113 ddf_msg(LVL_ERROR, "Failed binding function %s: %s", name,
00114 str_error(rc));
00115 ddf_fun_destroy(fun);
00116 return rc;
00117 }
00118
00119 return EOK;
00120 }
00121
00127 static int add_platform_fun(ddf_dev_t *dev)
00128 {
00129 char *match_id;
00130 char *platform;
00131 size_t platform_size;
00132
00133 const char *name = PLATFORM_FUN_NAME;
00134 ddf_fun_t *fun;
00135 int rc;
00136
00137
00138 platform = sysinfo_get_data("platform", &platform_size);
00139 if (platform == NULL) {
00140 ddf_msg(LVL_ERROR, "Failed to obtain platform name.");
00141 return ENOENT;
00142 }
00143
00144
00145 platform = realloc(platform, platform_size + 1);
00146 if (platform == NULL) {
00147 ddf_msg(LVL_ERROR, "Memory allocation failed.");
00148 return ENOMEM;
00149 }
00150
00151 platform[platform_size] = '\0';
00152
00153
00154 if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) {
00155 ddf_msg(LVL_ERROR, "Memory allocation failed.");
00156 return ENOMEM;
00157 }
00158
00159
00160 ddf_msg(LVL_DEBUG, "Adding platform function. Function node is `%s' "
00161 " (%d %s)", PLATFORM_FUN_NAME, PLATFORM_FUN_MATCH_SCORE,
00162 match_id);
00163
00164 fun = ddf_fun_create(dev, fun_inner, name);
00165 if (fun == NULL) {
00166 ddf_msg(LVL_ERROR, "Error creating function %s", name);
00167 return ENOMEM;
00168 }
00169
00170 rc = ddf_fun_add_match_id(fun, match_id, PLATFORM_FUN_MATCH_SCORE);
00171 if (rc != EOK) {
00172 ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s",
00173 name);
00174 ddf_fun_destroy(fun);
00175 return rc;
00176 }
00177
00178 rc = ddf_fun_bind(fun);
00179 if (rc != EOK) {
00180 ddf_msg(LVL_ERROR, "Failed binding function %s: %s", name,
00181 str_error(rc));
00182 ddf_fun_destroy(fun);
00183 return rc;
00184 }
00185
00186 return EOK;
00187 }
00188
00194 static int root_add_device(ddf_dev_t *dev)
00195 {
00196 ddf_msg(LVL_DEBUG, "root_add_device, device handle=%" PRIun,
00197 dev->handle);
00198
00199
00200
00201
00202
00203
00204 add_virtual_root_fun(dev);
00205
00206
00207 int res = add_platform_fun(dev);
00208 if (EOK != res)
00209 ddf_msg(LVL_ERROR, "Failed adding child device for platform.");
00210
00211 return res;
00212 }
00213
00214 int main(int argc, char *argv[])
00215 {
00216 printf(NAME ": HelenOS root device driver\n");
00217
00218 ddf_log_init(NAME, LVL_ERROR);
00219 return ddf_driver_main(&root_driver);
00220 }
00221