@@ -24,6 +24,7 @@ static enum {UNDONE, IN_PROGRESS, DONE} init_global_status;
static _odp_ishm_pool_t *list_elt_pool;
typedef struct _odpdrv_enumr_class_s _odpdrv_enumr_class_t;
+typedef struct _odpdrv_enumr_s _odpdrv_enumr_t;
/* an enumerator class (list element) */
struct _odpdrv_enumr_class_s {
@@ -40,6 +41,20 @@ typedef struct _odpdrv_enumr_class_lst_t {
} _odpdrv_enumr_class_lst_t;
static struct _odpdrv_enumr_class_lst_t enumr_class_lst;
+/* an enumerator (list element) */
+struct _odpdrv_enumr_s {
+ odpdrv_enumr_param_t param;
+ int probed;
+ struct _odpdrv_enumr_s *next;
+};
+
+/* the enumerator list: */
+typedef struct _odpdrv_enumr_lst_t {
+ odp_rwlock_recursive_t lock;
+ _odpdrv_enumr_t *head;
+} _odpdrv_enumr_lst_t;
+static struct _odpdrv_enumr_lst_t enumr_lst;
+
/* some driver elements (such as enumeraor classes, drivers, devio) may
* register before init_global and init_local complete. Mutex will fail
* in this cases but should be used later on.
@@ -69,6 +84,35 @@ static void enumr_class_list_write_unlock(void)
odp_rwlock_recursive_write_unlock(&enumr_class_lst.lock);
}
+static void enumr_list_read_lock(void)
+{
+ if (init_global_status == DONE)
+ odp_rwlock_recursive_read_lock(&enumr_lst.lock);
+}
+
+static void enumr_list_read_unlock(void)
+{
+ if (init_global_status == DONE)
+ odp_rwlock_recursive_read_unlock(&enumr_lst.lock);
+}
+
+static void enumr_list_write_lock(void)
+{
+ if (init_global_status == DONE)
+ odp_rwlock_recursive_write_lock(&enumr_lst.lock);
+}
+
+static void enumr_list_write_unlock(void)
+{
+ if (init_global_status == DONE)
+ odp_rwlock_recursive_write_unlock(&enumr_lst.lock);
+}
+
+/* some functions to get internal pointers from handles... */
+static inline _odpdrv_enumr_class_t *get_enumr_class(odpdrv_enumr_class_t class)
+{
+ return (_odpdrv_enumr_class_t *)(void *)class;
+}
odpdrv_enumr_class_t odpdrv_enumr_class_register(odpdrv_enumr_class_param_t
*param)
@@ -133,10 +177,52 @@ odpdrv_enumr_class_t odpdrv_enumr_class_register(odpdrv_enumr_class_param_t
odpdrv_enumr_t odpdrv_enumr_register(odpdrv_enumr_param_t *param)
{
- ODP_ERR("NOT Supported yet! Enumerator API %s Registration!\n.",
- param->api_name);
+ _odpdrv_enumr_t *enumr;
+ _odpdrv_enumr_class_t *enumr_c;
+ int found_class = 0;
- return ODPDRV_ENUMR_INVALID;
+ /* make sure that the provided enumerator_class does indeed exist: */
+ enumr_class_list_read_lock();
+ enumr_c = enumr_class_lst.head;
+ while (enumr_c) {
+ if (get_enumr_class(param->enumr_class) == enumr_c) {
+ found_class = 1;
+ break;
+ }
+ enumr_c = enumr_c->next;
+ }
+ enumr_class_list_read_unlock();
+ if (!found_class) {
+ ODP_ERR("invalid enumerator class provided!\n");
+ return ODPDRV_ENUMR_INVALID;
+ }
+
+ /* allocate memory for the new enumerator:
+ * If init_global has not been done yet, we have a big issue,
+ * as none of the enumerator classes should be probed before that!
+ * We cannot even issue an error as ODP_* functions have not been
+ * initialised yet, but this is no good...
+ */
+
+ if (init_global_status == UNDONE)
+ return ODPDRV_ENUMR_INVALID;
+
+ enumr = _odp_ishm_pool_alloc(list_elt_pool,
+ sizeof(_odpdrv_enumr_t));
+ if (!enumr) {
+ ODP_ERR("_odp_ishm_pool_alloc failed!\n");
+ return ODPDRV_ENUMR_INVALID;
+ }
+
+ /* save init parameters and insert enumerator in list */
+ enumr->param = *param;
+ enumr->probed = 0;
+ enumr_list_write_lock();
+ enumr->next = enumr_lst.head;
+ enumr_lst.head = enumr;
+ enumr_list_write_unlock();
+
+ return (odpdrv_enumr_t)enumr;
}
odpdrv_device_t odpdrv_device_create(odpdrv_device_param_t *param)
@@ -174,6 +260,7 @@ odpdrv_driver_t odpdrv_driver_register(odpdrv_driver_param_t *param)
void _odpdrv_driver_probe_drv_items(void)
{
_odpdrv_enumr_class_t *enumr_c;
+ _odpdrv_enumr_t *enumr;
/* probe unprobed enumerators: */
enumr_class_list_read_lock();
@@ -186,11 +273,26 @@ void _odpdrv_driver_probe_drv_items(void)
enumr_c = enumr_c->next;
}
enumr_class_list_read_unlock();
+
+ /* go through the list of registered enumerator probing the new
+ * (never probed) ones:
+ */
+ enumr_list_read_lock();
+ enumr = enumr_lst.head;
+ while (enumr) {
+ if (!enumr->probed) {
+ enumr->param.probe();
+ enumr->probed = 1;
+ }
+ enumr = enumr->next;
+ }
+ enumr_list_read_unlock();
}
int odpdrv_print_all(void)
{
_odpdrv_enumr_class_t *enumr_c;
+ _odpdrv_enumr_t *enumr;
/* we cannot use ODP_DBG before ODP init... */
if (init_global_status == UNDONE)
@@ -207,6 +309,21 @@ int odpdrv_print_all(void)
enumr_c = enumr_c->next;
}
enumr_class_list_read_unlock();
+
+ /* print the list of registered enumerators: */
+ enumr_list_read_lock();
+ enumr = enumr_lst.head;
+ ODP_DBG("The following enumerators have been registered:\n");
+ while (enumr) {
+ enumr_c = get_enumr_class(enumr->param.enumr_class);
+ ODP_DBG(" enumerator: class: %s, API: %s, Version: %d\n",
+ enumr_c->param.name,
+ enumr->param.api_name,
+ enumr->param.api_version);
+ enumr = enumr->next;
+ }
+ enumr_list_read_unlock();
+
return 0;
}
@@ -222,6 +339,7 @@ int _odpdrv_driver_init_global(void)
/* from now, we want to ensure mutex on the list: init lock: */
odp_rwlock_recursive_init(&enumr_class_lst.lock);
+ odp_rwlock_recursive_init(&enumr_lst.lock);
/* probe things... */
_odpdrv_driver_probe_drv_items();
@@ -240,10 +358,25 @@ int _odpdrv_driver_init_local(void)
int _odpdrv_driver_term_global(void)
{
_odpdrv_enumr_class_t *enumr_c;
+ _odpdrv_enumr_t *enumr;
if (init_global_status == UNDONE)
return 0;
+ /* remove all enumerators which are registered: */
+ enumr_list_write_lock();
+ while (enumr_lst.head) {
+ enumr = enumr_lst.head;
+ if (enumr->param.remove) { /* run remove callback, if any */
+ if (enumr->param.remove())
+ ODP_ERR("Enumerator (API %s) removal failed.\n",
+ enumr->param.api_name);
+ }
+ enumr_lst.head = enumr->next;
+ _odp_ishm_pool_free(list_elt_pool, enumr);
+ }
+ enumr_list_write_unlock();
+
/* remove all enumerator classes which are registered: */
enumr_class_list_write_lock();
while (enumr_class_lst.head) {
The enumerator registration functions for the linux-gen ODP implementation. Signed-off-by: Christophe Milard <christophe.milard@linaro.org> --- platform/linux-generic/drv_driver.c | 139 +++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 3 deletions(-) -- 2.7.4