From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id C32FD5F1D for ; Fri, 9 Mar 2018 16:34:50 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Mar 2018 07:34:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,446,1515484800"; d="scan'208";a="23862679" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga008.jf.intel.com with ESMTP; 09 Mar 2018 07:34:49 -0800 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 9 Mar 2018 07:34:48 -0800 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 9 Mar 2018 07:34:48 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.226]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.166]) with mapi id 14.03.0319.002; Fri, 9 Mar 2018 23:34:46 +0800 From: "Xu, Rosen" To: "gaetan.rivet@6wind.com" CC: "dev@dpdk.org" , "Doherty, Declan" , "Zhang, Tianfei" Thread-Topic: [dpdk-dev] [RFC 1/4] drivers/bus/ifpga:Intel FPGA Bus Lib Code Thread-Index: AQHTtTK2FL2YhNnW9UyOQ7S/7ao5VqPIDabw Date: Fri, 9 Mar 2018 15:34:45 +0000 Message-ID: <0E78D399C70DA940A335608C6ED296D739F1B595@SHSMSX104.ccr.corp.intel.com> References: <1520300638-134954-1-git-send-email-rosen.xu@intel.com> <1520300638-134954-2-git-send-email-rosen.xu@intel.com> <20180306100554.grsraayxpfqhtcf2@bidouze.vm.6wind.com> In-Reply-To: <20180306100554.grsraayxpfqhtcf2@bidouze.vm.6wind.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiY2U2NTMyYTgtMjQwNS00YjBhLWIzMTgtMDgyNmVjZjVmMWE5IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE2LjUuOS4zIiwiVHJ1c3RlZExhYmVsSGFzaCI6IlJtSjA1c0FHeXZWS3BiQytpODlJazg3ZlBjTm4rYkJoQ0MwdWdrbU85T2M9In0= x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [RFC 1/4] drivers/bus/ifpga:Intel FPGA Bus Lib Code X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Mar 2018 15:34:51 -0000 Thanks a lot Rivet, I have modified it, pls see my newest patch. -----Original Message----- From: Ga=EBtan Rivet [mailto:gaetan.rivet@6wind.com]=20 Sent: Tuesday, March 06, 2018 18:06 To: Xu, Rosen Cc: dev@dpdk.org; Doherty, Declan ; Zhang, Tianfe= i Subject: Re: [dpdk-dev] [RFC 1/4] drivers/bus/ifpga:Intel FPGA Bus Lib Code Hi Rosen, A few comments inline. (I will skip elements already pointed out by Shreyansh.) On Tue, Mar 06, 2018 at 09:43:55AM +0800, Rosen Xu wrote: > Signed-off-by: Rosen Xu > --- > drivers/bus/ifpga/Makefile | 64 ++++ > drivers/bus/ifpga/ifpga_bus.c | 527 ++++++++++++++++++++++= ++++++ > drivers/bus/ifpga/ifpga_common.c | 168 +++++++++ > drivers/bus/ifpga/ifpga_common.h | 46 +++ > drivers/bus/ifpga/ifpga_logs.h | 59 ++++ > drivers/bus/ifpga/rte_bus_ifpga.h | 153 ++++++++ > drivers/bus/ifpga/rte_bus_ifpga_version.map | 8 + > 7 files changed, 1025 insertions(+) > create mode 100644 drivers/bus/ifpga/Makefile create mode 100644=20 > drivers/bus/ifpga/ifpga_bus.c create mode 100644=20 > drivers/bus/ifpga/ifpga_common.c create mode 100644=20 > drivers/bus/ifpga/ifpga_common.h create mode 100644=20 > drivers/bus/ifpga/ifpga_logs.h create mode 100644=20 > drivers/bus/ifpga/rte_bus_ifpga.h create mode 100644=20 > drivers/bus/ifpga/rte_bus_ifpga_version.map >=20 > diff --git a/drivers/bus/ifpga/Makefile b/drivers/bus/ifpga/Makefile=20 > new file mode 100644 index 0000000..c71f186 > --- /dev/null > +++ b/drivers/bus/ifpga/Makefile > @@ -0,0 +1,64 @@ > +# BSD LICENSE > +# > +# Copyright(c) 2010-2017 Intel Corporation. All rights reserved. > +# All rights reserved. > +# > +# Redistribution and use in source and binary forms, with or without > +# modification, are permitted provided that the following conditions > +# are met: > +# > +# * Redistributions of source code must retain the above copyright > +# notice, this list of conditions and the following disclaimer. > +# * Redistributions in binary form must reproduce the above copyrigh= t > +# notice, this list of conditions and the following disclaimer in > +# the documentation and/or other materials provided with the > +# distribution. > +# * Neither the name of Intel Corporation nor the names of its > +# contributors may be used to endorse or promote products derived > +# from this software without specific prior written permission. > +# > +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FO= R > +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT > +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL= , > +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE= , > +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON AN= Y > +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE US= E > +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + > +include $(RTE_SDK)/mk/rte.vars.mk > + > +# > +# library name > +# > +LIB =3D librte_bus_ifpga.a > +LIBABIVER :=3D 1 > +EXPORT_MAP :=3D rte_bus_ifpga_version.map > + > +ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_DEBUG_INIT),y) > +CFLAGS +=3D -O0 -g > +CFLAGS +=3D "-Wno-error" > +else > +CFLAGS +=3D -O3 > +CFLAGS +=3D $(WERROR_FLAGS) > +endif > + > +CFLAGS +=3D -I$(RTE_SDK)/drivers/bus/ifpga CFLAGS +=3D=20 > +-I$(RTE_SDK)/drivers/bus/pci CFLAGS +=3D=20 > +-I$(RTE_SDK)/lib/librte_eal/linuxapp/eal > +CFLAGS +=3D -I$(RTE_SDK)/lib/librte_eal/common > +#CFLAGS +=3D -I$(RTE_SDK)/lib/librte_rawdev #LDLIBS +=3D -lrte_eal=20 > +-lrte_mbuf -lrte_mempool -lrte_ring -lrte_rawdev LDLIBS +=3D -lrte_eal=20 > +-lrte_mbuf -lrte_mempool -lrte_ring #LDLIBS +=3D -lrte_ethdev > + > +VPATH +=3D $(SRCDIR)/base > + > +SRCS-y +=3D \ > + ifpga_bus.c \ > + ifpga_common.c > + > +include $(RTE_SDK)/mk/rte.lib.mk > diff --git a/drivers/bus/ifpga/ifpga_bus.c=20 > b/drivers/bus/ifpga/ifpga_bus.c new file mode 100644 index=20 > 0000000..382d550 > --- /dev/null > +++ b/drivers/bus/ifpga/ifpga_bus.c > @@ -0,0 +1,527 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. > + * Copyright 2013-2014 6WIND S.A. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * * Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * * Redistributions in binary form must reproduce the above copyrig= ht > + * notice, this list of conditions and the following disclaimer in > + * the documentation and/or other materials provided with the > + * distribution. > + * * Neither the name of Intel Corporation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS F= OR > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGH= T > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US= E, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON A= NY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE U= SE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE= . > + */ > + > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#include "rte_rawdev.h" > +#include "rte_rawdev_pmd.h" > +#include "rte_bus_ifpga.h" > +#include "ifpga_logs.h" > +#include "ifpga_common.h" > + > +int ifpga_bus_logtype; > + > +/*register a ifpga bus based driver */ void=20 > +rte_ifpga_driver_register(struct rte_afu_driver *driver) { > + RTE_VERIFY(driver); > + > + TAILQ_INSERT_TAIL(&rte_ifpga_bus.driver_list, driver, next); } > + > +/*un-register a fpga bus based driver */ void=20 > +rte_ifpga_driver_unregister(struct rte_afu_driver *driver) { > + TAILQ_REMOVE(&rte_ifpga_bus.driver_list, driver, next); } > + > +static struct rte_afu_device * > +ifpga_find_afu_dev(const struct rte_afu_id *afu_id) { > + struct rte_afu_device *afu_dev =3D NULL; > +=09 You seem to have trailing spaces (here tabs), and some inconsistencies in y= our file (sometimes spaces are used, sometime tabs). You need to run checkpatch on your series. See those errors: http://dpdk.org/ml/archives/test-report/2018-March/043185.html A script is available in devtools to run this before submitting. > + TAILQ_FOREACH (afu_dev, &rte_ifpga_bus.afu_list, next) { > + > + if(!ifpga_afu_id_cmp(&afu_dev->id, afu_id)) { > + return afu_dev; > + } > + } > + return NULL; > +} > + > +static const char *valid_args[] =3D { > +#define IFPGA_ARG_BDF "bdf" > + IFPGA_ARG_BDF, > +#define IFPGA_ARG_PORT "port" > + IFPGA_ARG_PORT, > +#define IFPGA_ARG_PATH "path" > + IFPGA_ARG_PATH, > +#define IFPGA_ARG_UUID_HIGH "uuid_high" > + IFPGA_ARG_UUID_HIGH, > +#define IFPGA_ARG_UUID_LOW "uuid_low" > + IFPGA_ARG_UUID_LOW, > +#define IFPGA_ARG_PR_ENABLE "pr_enable" > + IFPGA_ARG_PR_ENABLE, > +#define IFPGA_ARG_DEBUG "debug" > + IFPGA_ARG_DEBUG, > + NULL > +}; > + > +/* > + * Scan the content of the FPGA bus, and the devices in the devices > + * list > + */ > +static struct rte_afu_device * > +rte_ifpga_scan_one(struct rte_devargs *devargs) { > + struct rte_kvargs *kvlist =3D NULL; > + struct rte_bus *pci_bus =3D NULL; > + struct rte_device *dev =3D NULL; > + struct rte_rawdev *rawdev; > + struct rte_afu_device *afu_dev =3D NULL; > + struct rte_afu_pr_conf afu_pr_conf; > + char rawdev_name[RTE_RAWDEV_NAME_MAX_LEN]; > + int ret; > + char *path =3D NULL; > + int pr_enable =3D 1; > + int debug =3D 0; > + > + memset((char *)(&afu_pr_conf), 0, sizeof(struct=20 > + rte_afu_pr_conf)); > +=09 > + kvlist =3D rte_kvargs_parse(devargs->args, valid_args); > + if (!kvlist) { > + IFPGA_BUS_ERR("error when parsing param"); > + goto end; > + } > + =20 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_BDF) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_BDF, > + &ifpga_get_bdf_arg, &afu_pr_conf.afu_id.pci_addr) < 0) { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_BDF); > + goto end; > + } > + } else { > + IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus", > + IFPGA_ARG_PATH); > + goto end; > + } > + =20 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT, > + &ifpga_get_integer32_arg, &afu_pr_conf.afu_id.port) < 0) { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_PORT); > + goto end; > + } > + } > + else { > + IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus", > + IFPGA_ARG_PATH); > + goto end; > + } > +=09 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_PATH) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_PATH, > + &ifpga_get_string_arg, &path) < 0) { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_PATH); > + goto end; > + } > + } else { > + IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus", > + IFPGA_ARG_PATH); > + goto end; > + } > +=09 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_UUID_HIGH) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_UUID_HIGH, > + &ifpga_get_integer64_arg, &afu_pr_conf.afu_id.uuid_high) < 0)= { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_UUID_HIGH); > + goto end; > + } > + } else { > + IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus", > + IFPGA_ARG_PATH); > + goto end; > + } > +=09 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_UUID_LOW) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_UUID_LOW, > + &ifpga_get_integer64_arg, &afu_pr_conf.afu_id.uuid_low) < 0) = { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_UUID_LOW); > + goto end; > + } > + } else { > + IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus", > + IFPGA_ARG_PATH); > + goto end; > + } > +=09 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_PR_ENABLE) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_PR_ENABLE, > + &ifpga_get_integer32_arg, &pr_enable) < 0) { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_UUID_HIGH); > + goto end; > + } > + } > +=09 > + if (rte_kvargs_count(kvlist, IFPGA_ARG_DEBUG) =3D=3D 1) { > + if (rte_kvargs_process(kvlist, IFPGA_ARG_DEBUG, > + &ifpga_get_integer32_arg, &debug) < 0) { > + IFPGA_BUS_ERR("error to parse %s", > + IFPGA_ARG_UUID_HIGH); > + goto end; > + } > + } > +=09 > + if(!debug) > + { > + pci_bus =3D rte_bus_find_by_name("pci"); > + if (pci_bus =3D=3D NULL) { > + IFPGA_BUS_ERR("unable to find PCI bus\n"); > + goto end; > + } > + =20 > + dev =3D pci_bus->find_device(NULL, ifpga_pci_addr_cmp, &afu_pr_conf= .afu_id.pci_addr); > + if (dev =3D=3D NULL) { > + IFPGA_BUS_ERR("unable to find PCI device\n"); > + goto end; > + } > + } > + else > + { > + IFPGA_BUS_DEBUG("pci_addr domain : %x\n", afu_pr_conf.afu_id.pci_a= ddr.domain); > + IFPGA_BUS_DEBUG("pci_addr bus : %x\n", afu_pr_conf.afu_id.pci_a= ddr.bus); > + IFPGA_BUS_DEBUG("pci_addr devid : %x\n", afu_pr_conf.afu_id.pci_a= ddr.devid); > + IFPGA_BUS_DEBUG("pci_addr function : %x\n", afu_pr_conf.afu_id.pci_a= ddr.function); Alternatively, it could be interesting to have a PCI_ADDR_FMT and PCI_ADDR_= ARGS in librte_pci, to help printing PCI addresses in a standard way. This = could be leveraged in librte_bus_pci as well. > + =09 > + IFPGA_BUS_DEBUG("uuid_low : %lx\n", afu_pr_conf.afu_id.uuid_l= ow); > + IFPGA_BUS_DEBUG("uuid_high : %lx\n", afu_pr_conf.afu_id.uuid_h= igh); > + =09 > + IFPGA_BUS_DEBUG("afu port : %x\n", afu_pr_conf.afu_id.port)= ; > + } > +=09 > + if (ifpga_find_afu_dev(&afu_pr_conf.afu_id)) > + goto end; > + > + memset(rawdev_name, sizeof(rawdev_name), 0); > + snprintf(rawdev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%x:%x", afu_pr= _conf.afu_id.pci_addr.bus, afu_pr_conf.afu_id.pci_addr.devid, afu_pr_conf.a= fu_id.pci_addr.function); > + rawdev =3D rte_rawdev_pmd_get_named_dev(rawdev_name); > + if(!rawdev) > + goto end; > +=09 > + rawdev->dev_ops->dev_start(rawdev); > + =09 > + if (pr_enable) > + { > + ret=3Drawdev->dev_ops->firmware_load(rawdev, &afu_pr_conf); > + if (ret) { > + printf("do pr error\n"); > + return NULL; > + } > + } > + =09 > + afu_dev =3D calloc(1, sizeof(*afu_dev)); > + if (!afu_dev) > + goto end; > + > + afu_dev->device.devargs =3D devargs; > + afu_dev->device.numa_node =3D SOCKET_ID_ANY; > + afu_dev->device.name =3D devargs->name; > + afu_dev->rawdev =3D rawdev; > + afu_dev->id.pci_addr.domain =3D afu_pr_conf.afu_id.pci_addr.domain; > + afu_dev->id.pci_addr.bus =3D afu_pr_conf.afu_id.pci_addr.bus; > + afu_dev->id.pci_addr.devid =3D afu_pr_conf.afu_id.pci_addr.devid; > + afu_dev->id.pci_addr.function =3D=20 > +afu_pr_conf.afu_id.pci_addr.function; A pci_addr_cpy function could be written. > + afu_dev->id.uuid_low =3D afu_pr_conf.afu_id.uuid_low; > + afu_dev->id.uuid_high =3D afu_pr_conf.afu_id.uuid_high; > + afu_dev->id.port =3D afu_pr_conf.afu_id.port; > +=09 > + rawdev->dev_ops->dev_info_get(rawdev, afu_dev); > + > + return afu_dev; > + =20 > +end: > + if (kvlist) > + rte_kvargs_free(kvlist); > + if (path) > + free(path); > +=09 > + return NULL; > +} > + > +/* > + * Scan the content of the FPGA bus, and the devices in the devices > + * list > + */ > +static int > +rte_ifpga_scan(void) > +{ > + struct rte_bus *pci_bus; > + struct rte_afu_device *afu_dev; > + struct rte_devargs *devargs; > + > + pci_bus =3D rte_bus_find_by_name("pci"); > + if (pci_bus =3D=3D NULL) { > + IFPGA_BUS_ERR("unable to find PCI bus\n"); > + return -1; > + } > +=09 > + /* for virtual devices we scan the devargs_list populated via cmdline *= / > + TAILQ_FOREACH(devargs, &devargs_list, next) { > + =20 > + if (devargs->bus !=3D &rte_ifpga_bus.bus) > + continue; > + =09 > + afu_dev =3D rte_ifpga_scan_one(devargs); > + =20 > + if(afu_dev) > + TAILQ_INSERT_TAIL(&rte_ifpga_bus.afu_list, afu_dev, next); > + } > + > + return 0; > +} > + > +static int > +ifpga_probe_one_driver(struct rte_afu_driver *drv, > + struct rte_afu_device *afu_dev) > +{ > + int ret; > + > + if((drv->id.pci_addr.bus =3D=3D afu_dev->id.pci_addr.bus) && > + (drv->id.pci_addr.devid =3D=3D afu_dev->id.pci_addr.devid) && > + (drv->id.pci_addr.function =3D=3D afu_dev->id.pci_addr.function)= =20 > + && Is it expected to ignore the domain here? You should use rte_pci_addr_cmp instead. > + (drv->id.uuid_low =3D=3D afu_dev->id.uuid_low) && > + (drv->id.uuid_high =3D=3D afu_dev->id.uuid_high) && > + (drv->id.port =3D=3D afu_dev->id.port)) { > + =09 > + afu_dev->driver =3D drv; > + =09 > + /* call the driver probe() function */ > + ret =3D drv->probe(afu_dev); > + if (ret) > + afu_dev->driver =3D NULL; > + return ret; > + } > +=09 > + /* return positive value if driver doesn't support this device */ > + return 1; > +} > + > +static int > +ifpga_probe_all_drivers(struct rte_afu_device *afu_dev) { > + const char *name; > + struct rte_afu_driver *drv =3D NULL; > + int rc; > + > + if (afu_dev =3D=3D NULL) > + return -1; > + > + /* Check if a driver is already loaded */ > + if (afu_dev->driver !=3D NULL) > + return 0; > + =09 > + name =3D rte_ifpga_device_name(afu_dev); > + IFPGA_BUS_DEBUG("Search driver %s to probe device %s\n", name, > + rte_ifpga_device_name(afu_dev)); > + =20 > + TAILQ_FOREACH(drv, &rte_ifpga_bus.driver_list, next) { > + rc =3D ifpga_probe_one_driver(drv, afu_dev); > + if (rc < 0) > + /* negative value is an error */ > + return -1; > + if (rc > 0) > + /* positive value means driver doesn't support it */ > + continue; > + return 0; > + } > + return 1; > + } > + > +/* > + * Scan the content of the PCI bus, and call the probe() function for > + * all registered drivers that have a matching entry in its id_table > + * for discovered devices. > + */ > +static int > +rte_ifpga_probe(void) > +{ > + struct rte_afu_device *afu_dev =3D NULL; > + int ret =3D 0; > + > + TAILQ_FOREACH (afu_dev, &rte_ifpga_bus.afu_list, next) { > + > + if (afu_dev->device.driver) > + continue; > + =09 > + ret =3D ifpga_probe_all_drivers(afu_dev); > + if (ret < 0) > + IFPGA_BUS_ERR("failed to initialize %s device\n", > + rte_ifpga_device_name(afu_dev)); > + } > + > + return 0; > +} > + > +static int > +rte_ifpga_plug(struct rte_device *dev) { > + return ifpga_probe_all_drivers(RTE_DEV_TO_AFU(dev)); > +} > + > +static int ifpga_remove_driver(struct rte_afu_device *afu_dev) { > + const char *name; > + const struct rte_afu_driver *driver; > + > + name =3D rte_ifpga_device_name(afu_dev); > + if (!afu_dev->device.driver) { > + IFPGA_BUS_DEBUG("no driver attach to device %s\n", name); > + return 1; > + } > + > + driver =3D container_of(afu_dev->device.driver, const struct rte_afu_dr= iver, > + driver); > + return driver->remove(afu_dev); > +} > + > +static int > +rte_ifpga_unplug(struct rte_device *dev) { > + struct rte_afu_device *afu_dev; > + struct rte_devargs *devargs; > + int ret; > + > + if (dev =3D=3D NULL) > + return -EINVAL; > + > + afu_dev =3D RTE_DEV_TO_AFU(dev); > + if (!dev) > + return -ENOENT; > + > + devargs =3D dev->devargs; > + > + ret =3D ifpga_remove_driver(afu_dev); > + if (ret) > + return ret; > + > + TAILQ_REMOVE(&rte_ifpga_bus.afu_list, afu_dev, next); > + > + TAILQ_REMOVE(&devargs_list, devargs, next); > + > + free(devargs->args); > + free(devargs); > + free(afu_dev); > + return 0; > + > +} > + > +static struct rte_device * > +rte_ifpga_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, > + const void *data) { > + struct rte_afu_device *afu_dev; > + > + TAILQ_FOREACH(afu_dev, &rte_ifpga_bus.afu_list, next) { > + if (start && &afu_dev->device =3D=3D start) { > + start =3D NULL; > + continue; > + } > + if (cmp(&afu_dev->device, data) =3D=3D 0) > + return &afu_dev->device; > + } > + return NULL; > +} > +static int > +rte_ifpga_parse(const char *name, void *addr) { > + struct rte_afu_driver **out =3D addr; > + struct rte_afu_driver *driver =3D NULL; > + > + TAILQ_FOREACH(driver, &rte_ifpga_bus.driver_list, next) { > + if (strncmp(driver->driver.name, name, > + strlen(driver->driver.name)) =3D=3D 0) > + break; > + if (driver->driver.alias && > + strncmp(driver->driver.alias, name, > + strlen(driver->driver.alias)) =3D=3D 0) > + break; > + } > + if (driver !=3D NULL && > + addr !=3D NULL) > + *out =3D driver; > + return driver =3D=3D NULL; > +} > + > +struct rte_ifpga_bus rte_ifpga_bus =3D { > + .bus =3D { > + .scan =3D rte_ifpga_scan, > + .probe =3D rte_ifpga_probe, > + .find_device =3D rte_ifpga_find_device, You should use only one tab each lines. > + .plug =3D rte_ifpga_plug, > + .unplug =3D rte_ifpga_unplug, > + .parse =3D rte_ifpga_parse, > + }, > + .afu_list =3D TAILQ_HEAD_INITIALIZER(rte_ifpga_bus.afu_list), > + .driver_list =3D TAILQ_HEAD_INITIALIZER(rte_ifpga_bus.driver_list), > + }; > + > +RTE_REGISTER_BUS(IFPGA_BUS_NAME, rte_ifpga_bus.bus); > + > +RTE_INIT(ifpga_init_log) > +{ > + ifpga_bus_logtype =3D rte_log_register("bus.ifpga"); > + if (ifpga_bus_logtype >=3D 0) > + rte_log_set_level(ifpga_bus_logtype, RTE_LOG_NOTICE); } > + > diff --git a/drivers/bus/ifpga/ifpga_common.c=20 > b/drivers/bus/ifpga/ifpga_common.c > new file mode 100644 > index 0000000..2aa6bb0 > --- /dev/null > +++ b/drivers/bus/ifpga/ifpga_common.c > @@ -0,0 +1,168 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. > + * Copyright 2013-2014 6WIND S.A. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * * Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * * Redistributions in binary form must reproduce the above copyrig= ht > + * notice, this list of conditions and the following disclaimer in > + * the documentation and/or other materials provided with the > + * distribution. > + * * Neither the name of Intel Corporation nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS F= OR > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGH= T > + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US= E, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON A= NY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE U= SE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE= . > + */ > + > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#include "rte_bus_ifpga.h" > +#include "ifpga_logs.h" > +#include "ifpga_common.h" > + > +int ifpga_get_string_arg(const char *key __rte_unused, > + const char *value, void *extra_args) { > + if (!value || !extra_args) > + return -EINVAL; > + > + *(char **)extra_args =3D strdup(value); > + > + if (!*(char **)extra_args) > + return -ENOMEM; > + > + return 0; > +} > +int ifpga_get_integer32_arg(const char *key __rte_unused, const char=20 > +*value, void *extra_args) { > + if (!value || !extra_args) > + return -EINVAL; > + > + *(int *)extra_args =3D strtoull(value, NULL, 0); > + > + return 0; > +} > +int ifpga_get_integer64_arg(const char *key __rte_unused, const char=20 > +*value, void *extra_args) { > + if (!value || !extra_args) > + return -EINVAL; > + > + *(uint64_t *)extra_args =3D strtoull(value, NULL, 0); > + > + return 0; > +} > +int ifpga_get_unsigned_long(const char *str, int base) { > + unsigned long num; > + char *end =3D NULL; > + > + errno =3D 0; > + > + num =3D strtoul(str, &end, base); > + if ((str[0] =3D=3D '\0') || (end =3D=3D NULL) || (*end !=3D '\0') || (e= rrno !=3D 0)) > + return -1; > + > + return num; > + > +} > +int ifpga_get_bdf_arg(const char *key __rte_unused, const char=20 > +*value, void *extra_args) { #define MAX_PATH_LEN 1024 > + struct rte_pci_addr *addr; > + int num[4]; > + char str[MAX_PATH_LEN]; > + int i, j; > +=09 > + if (!value || !extra_args) > + return -EINVAL; > + > + addr =3D (struct rte_pci_addr *)extra_args; Okay, you seem to be reading a PCI address here. Why not use directly rte_pci_addr_parse? > + strcpy(str, value); > + memset(num, 0, 4 * sizeof(num[0])); > + i =3D strlen(str) - 1; > + j =3D 3; > + while (i > 0 && j >=3D 0) { > + while ((str[i - 1] !=3D ':' && str[i - 1] !=3D '.') && i > 0) > + i--; > + num[j--] =3D ifpga_get_unsigned_long(&str[i], 16); > + i--; > + if (i >=3D 0) > + str[i] =3D '\0'; > + } > + addr->domain =3D num[0]; > + addr->bus =3D num[1]; > + addr->devid =3D num[2]; > + addr->function =3D num[3]; > + printf("[%s]: bdf %04d:%02d:%02d.%02d\n", > + __func__, > + addr->domain, > + addr->bus, > + addr->devid, > + addr->function); > + > + return 0; > +} > +int ifpga_afu_id_cmp(const struct rte_afu_id *afu_id0, const struct=20 > +rte_afu_id *afu_id1) { > + if((afu_id0->pci_addr.bus =3D=3D afu_id1->pci_addr.bus) && > + (afu_id0->pci_addr.devid =3D=3D afu_id1->pci_addr.devid) && > + (afu_id0->pci_addr.function =3D=3D afu_id1->pci_addr.function) &= & Same as before: you should use rte_pci_addr_cmp here? > + (afu_id0->uuid_low =3D=3D afu_id1->uuid_low) && > + (afu_id0->uuid_high =3D=3D afu_id1->uuid_high) && > + (afu_id0->port =3D=3D afu_id1->port)) { > + =09 > + return 0; > + } > + else > + return 1; > +} > +int ifpga_pci_addr_cmp(const struct rte_device *dev, const void=20 > +*_pci_addr) { > + struct rte_pci_device *pdev; > + const struct rte_pci_addr *paddr =3D _pci_addr; > + > + pdev =3D RTE_DEV_TO_PCI(*(struct rte_device **)(void *)&dev); > + return rte_eal_compare_pci_addr(&pdev->addr, paddr); This function is deprecated, rte_pci_addr_cmp must be used instead. Regards, -- Ga=EBtan Rivet 6WIND