From patchwork Wed Feb 22 12:55:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Milard X-Patchwork-Id: 94320 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp926578obz; Wed, 22 Feb 2017 04:09:12 -0800 (PST) X-Received: by 10.55.71.210 with SMTP id u201mr8160842qka.90.1487765351956; Wed, 22 Feb 2017 04:09:11 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id b125si485280qke.226.2017.02.22.04.09.11; Wed, 22 Feb 2017 04:09:11 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 9C26962D18; Wed, 22 Feb 2017 12:09:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 0D57960E15; Wed, 22 Feb 2017 11:59:30 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 2E52E62FDA; Wed, 22 Feb 2017 11:59:25 +0000 (UTC) Received: from mail-lf0-f41.google.com (mail-lf0-f41.google.com [209.85.215.41]) by lists.linaro.org (Postfix) with ESMTPS id 8E50F60E15 for ; Wed, 22 Feb 2017 11:57:33 +0000 (UTC) Received: by mail-lf0-f41.google.com with SMTP id g134so162438lfe.1 for ; Wed, 22 Feb 2017 03:57:33 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7d0KCN5tj5i3b5VJB5WwACQiexviaYvXvupJGf96iPw=; b=AAHpLd2n/Vdm1gk6qkhR/D6Yr9MIhXc42ULp5ejvH0QbRCZWahJ2x4jClDj5nAvTaF 1D/iKSIxcBZCpBMWFIS+vDgndCyPslGlXDxqXfyhrNSf0TjUQThjMjVDXJYxjiAEgXtQ /KFp1GCs8iWFkZ65xltHrA689jAfMtgQAHwsfelt3qO6WNYgvwVL3SDsqQeWabRk6U3D 4rYggnBc/oA91VpO6lEiL3828xUruGikUKT/2k6BeoqTygjez3FQPv+ApLhd2fv0sevu Kmt3BOGKXw6SlHhISC+ilySuXM7+lygUpU5yXH1ZAqdKOJ2eRHGLn6KRn+4pSR+xuVGY swAw== X-Gm-Message-State: AMke39kuW5w69PSc6sVHfAc0TO26HlmyZkW1QidjlSoDXDg0K+7nPHS87gb8u6zvjvSIi72QPJU= X-Received: by 10.46.7.82 with SMTP id i18mr6387633ljd.0.1487764652328; Wed, 22 Feb 2017 03:57:32 -0800 (PST) Received: from erachmi-ericsson.ki.sw.ericsson.se (c-83-233-76-66.cust.bredband2.com. [83.233.76.66]) by smtp.gmail.com with ESMTPSA id v21sm7035187ljd.9.2017.02.22.03.57.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Feb 2017 03:57:31 -0800 (PST) From: Christophe Milard To: mike.holmes@linaro.org, yi.he@linaro.org, forrest.shi@linaro.org, sachin.saxena@linaro.com, bill.fischofer@linaro.org, lng-odp@lists.linaro.org Date: Wed, 22 Feb 2017 13:55:56 +0100 Message-Id: <1487768164-43184-14-git-send-email-christophe.milard@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1487768164-43184-1-git-send-email-christophe.milard@linaro.org> References: <1487768164-43184-1-git-send-email-christophe.milard@linaro.org> Subject: [lng-odp] [API-NEXT PATCH 13/21] linux-gen: drv: devio registration X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" devios (dev IO) provide a interface for drivers to access a device: Devices enumerated by enumerators may be accessed in by different mechanisms (depending on iommu presence or other factors). This extra abstraction is provided by devios, which provide a sets of methods to access the devices of a given type (i.e. registred enumerator(s) enumerating devices of the same kind (e.g. PCI)). This patch just implements the devio registration method provided by the driver API. Signed-off-by: Christophe Milard --- platform/linux-generic/drv_driver.c | 134 +++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 3 deletions(-) -- 2.7.4 diff --git a/platform/linux-generic/drv_driver.c b/platform/linux-generic/drv_driver.c index 517a3c6..eb0dc48 100644 --- a/platform/linux-generic/drv_driver.c +++ b/platform/linux-generic/drv_driver.c @@ -28,6 +28,7 @@ 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; typedef struct _odpdrv_device_s _odpdrv_device_t; +typedef struct _odpdrv_devio_s _odpdrv_devio_t; /* an enumerator class (list element) */ struct _odpdrv_enumr_class_s { @@ -72,6 +73,20 @@ typedef struct _odpdrv_device_lst_t { } _odpdrv_device_lst_t; static struct _odpdrv_device_lst_t device_lst; +/* a devio (list element) */ +struct _odpdrv_devio_s { + odpdrv_devio_param_t param; + _odp_ishm_pool_t *pool; + struct _odpdrv_devio_s *next; +} _odpdrv_devio_s; + +/* the devio list: */ +typedef struct _odpdrv_devio_lst_t { + odp_rwlock_recursive_t lock; + _odpdrv_devio_t *head; +} _odpdrv_devio_lst_t; +static struct _odpdrv_devio_lst_t devio_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. @@ -149,6 +164,30 @@ static void dev_list_write_unlock(void) odp_rwlock_recursive_write_unlock(&device_lst.lock); } +static void devio_list_read_lock(void) +{ + if (init_global_status == DONE) + odp_rwlock_recursive_read_lock(&devio_lst.lock); +} + +static void devio_list_read_unlock(void) +{ + if (init_global_status == DONE) + odp_rwlock_recursive_read_unlock(&devio_lst.lock); +} + +static void devio_list_write_lock(void) +{ + if (init_global_status == DONE) + odp_rwlock_recursive_write_lock(&devio_lst.lock); +} + +static void devio_list_write_unlock(void) +{ + if (init_global_status == DONE) + odp_rwlock_recursive_write_unlock(&devio_lst.lock); +} + odpdrv_enumr_class_t odpdrv_enumr_class_register(odpdrv_enumr_class_param_t *param) { @@ -415,10 +454,65 @@ odpdrv_device_t *odpdrv_device_query(odpdrv_enumr_t enumr, const char *address) odpdrv_devio_t odpdrv_devio_register(odpdrv_devio_param_t *param) { - ODP_ERR("NOT Supported yet! Driver %s Registration!\n.", - param->api_name); + _odpdrv_devio_t *devio; + + /* parse the list of already registered devios to make + * sure no devio providing the same interface using th esame enumerator + * already exists: + */ + devio_list_read_lock(); + devio = devio_lst.head; + while (devio) { + if ((strncmp(param->api_name, devio->param.api_name, + ODPDRV_NAME_SIZE) == 0) && + (strncmp(param->enumr_api_name, devio->param.enumr_api_name, + ODPDRV_NAME_SIZE) == 0)) { + ODP_ERR("a devio providing interface '%s' for devices " + "of type '%s' is already registered\n!", + param->api_name, param->enumr_api_name); + devio_list_read_unlock(); + return ODPDRV_DEVIO_INVALID; + } + devio = devio->next; + } + devio_list_read_unlock(); - return ODPDRV_DEVIO_INVALID; + /* allocate memory for the new devio: + * If init_global has not been done yet, then, we cannot allocate + * from any _ishm pool (ishm has not even been initialised at this + * stage...this happens when statically linked devios + * register: their __constructor__ function is run before main() + * is called). But any malloc performed here(before init_global) + * will be inherited by any odpthreads (process or pthreads) as we + * are still running in the ODP instantiation processes and all + * other processes are guaranteed to be descendent of this one... + * If init_global has been done, then we allocate from the _ishm pool + * to guarantee visibility from any ODP thread. + */ + + if (init_global_status == UNDONE) { + devio = malloc(sizeof(_odpdrv_devio_t)); + if (!devio) + return ODPDRV_DEVIO_INVALID; + devio->pool = NULL; + } else { + devio = _odp_ishm_pool_alloc(list_elt_pool, + sizeof(_odpdrv_devio_t)); + if (!devio) { + ODP_ERR("_odp_ishm_pool_alloc failed!\n"); + return ODPDRV_DEVIO_INVALID; + } + devio->pool = list_elt_pool; + } + + /* save init parameters and insert devio in list */ + devio->param = *param; + devio_list_write_lock(); + devio->next = devio_lst.head; + devio_lst.head = devio; + devio_list_write_unlock(); + + return (odpdrv_devio_t)devio; } odpdrv_driver_t odpdrv_driver_register(odpdrv_driver_param_t *param) @@ -469,6 +563,7 @@ int odpdrv_print_all(void) _odpdrv_enumr_class_t *enumr_c; _odpdrv_enumr_t *enumr; _odpdrv_device_t *dev; + _odpdrv_devio_t *devio; /* we cannot use ODP_DBG before ODP init... */ if (init_global_status == UNDONE) @@ -519,6 +614,21 @@ int odpdrv_print_all(void) } dev_list_read_unlock(); + /* print the list of registered devios: */ + devio_list_read_lock(); + devio = devio_lst.head; + ODP_DBG("The following dev IOs have been registered:\n"); + while (devio) { + ODP_DBG(" devio providing interface: '%s' (version %d) for " + " devices of type '%s' (version %d)\n", + devio->param.api_name, + devio->param.api_version, + devio->param.enumr_api_name, + devio->param.enumr_api_version); + devio = devio->next; + } + devio_list_read_unlock(); + return 0; } @@ -536,6 +646,7 @@ int _odpdrv_driver_init_global(void) odp_rwlock_recursive_init(&enumr_class_lst.lock); odp_rwlock_recursive_init(&enumr_lst.lock); odp_rwlock_recursive_init(&device_lst.lock); + odp_rwlock_recursive_init(&devio_lst.lock); /* probe things... */ _odpdrv_driver_probe_drv_items(); @@ -553,12 +664,29 @@ int _odpdrv_driver_init_local(void) int _odpdrv_driver_term_global(void) { + _odpdrv_devio_t *devio; _odpdrv_enumr_class_t *enumr_c; _odpdrv_enumr_t *enumr; if (init_global_status == UNDONE) return 0; + /* remove all devios which are registered: */ + devio_list_write_lock(); + while (devio_lst.head) { + devio = devio_lst.head; /* run removal function, if any */ + if (devio->param.remove) { + if (devio->param.remove()) + ODP_ERR("devio removal indicated failure!\n"); + } + devio_lst.head = devio->next; + if (devio->pool) + _odp_ishm_pool_free(list_elt_pool, devio); + else + free(devio); + } + devio_list_write_unlock(); + /* remove all enumerators which are registered: */ enumr_list_write_lock(); while (enumr_lst.head) {