From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id A51EF376C for ; Mon, 2 Feb 2015 07:22:31 +0100 (CET) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 01 Feb 2015 22:22:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,504,1418112000"; d="scan'208";a="679525382" Received: from pgsmsx101.gar.corp.intel.com ([10.221.44.78]) by orsmga002.jf.intel.com with ESMTP; 01 Feb 2015 22:22:28 -0800 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by PGSMSX101.gar.corp.intel.com (10.221.44.78) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 2 Feb 2015 14:22:26 +0800 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.253]) by shsmsx102.ccr.corp.intel.com ([169.254.2.124]) with mapi id 14.03.0195.001; Mon, 2 Feb 2015 14:22:25 +0800 From: "Qiu, Michael" To: Tetsuya Mukawa , "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH v6 12/13] eal/pci: Add rte_eal_dev_attach/detach() functions Thread-Index: AQHQPdPy7Blels9imUGFi8evC3UPTA== Date: Mon, 2 Feb 2015 06:22:24 +0000 Message-ID: <533710CFB86FA344BFBF2D6802E60286CD25B9@SHSMSX101.ccr.corp.intel.com> References: <1421664027-17971-9-git-send-email-mukawa@igel.co.jp> <1422763322-13742-1-git-send-email-mukawa@igel.co.jp> <1422763322-13742-13-git-send-email-mukawa@igel.co.jp> <533710CFB86FA344BFBF2D6802E60286CD256A@SHSMSX101.ccr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v6 12/13] eal/pci: Add rte_eal_dev_attach/detach() functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Feb 2015 06:22:32 -0000 On 2/2/2015 1:43 PM, Qiu, Michael wrote:=0A= > On 2/1/2015 12:02 PM, Tetsuya Mukawa wrote:=0A= >> These functions are used for attaching or detaching a port.=0A= >> When rte_eal_dev_attach() is called, the function tries to realize the= =0A= >> device name as pci address. If this is done successfully,=0A= >> rte_eal_dev_attach() will attach physical device port. If not, attaches= =0A= >> virtual devive port.=0A= >> When rte_eal_dev_detach() is called, the function gets the device type= =0A= >> of this port to know whether the port is came from physical or virtual.= =0A= >> And then specific detaching function will be called.=0A= >>=0A= >> v5:=0A= >> - Change function names like below.=0A= >> rte_eal_dev_find_and_invoke() to rte_eal_vdev_find_and_invoke().=0A= >> rte_eal_dev_invoke() to rte_eal_vdev_invoke().=0A= >> - Add code to handle a return value of rte_eal_devargs_remove().=0A= >> - Fix pci address format in rte_eal_dev_detach().=0A= >> v4:=0A= >> - Fix comment.=0A= >> - Add error checking.=0A= >> - Fix indent of 'if' statement.=0A= >> - Change function name.=0A= >>=0A= =0A= [...]=0A= =0A= >> +/* attach the new virtual device, then store port_id of the device */= =0A= >> +static int=0A= >> +rte_eal_dev_attach_vdev(const char *vdevargs, uint8_t *port_id)=0A= >> +{=0A= >> + char *args;=0A= >> + uint8_t new_port_id;=0A= >> + struct rte_eth_dev devs[RTE_MAX_ETHPORTS];=0A= >> +=0A= >> + if ((vdevargs =3D=3D NULL) || (port_id =3D=3D NULL))=0A= >> + goto err0;=0A= >> +=0A= >> + args =3D strdup(vdevargs);=0A= >> + if (args =3D=3D NULL)=0A= >> + goto err0;=0A= >> +=0A= >> + /* save current port status */=0A= >> + rte_eth_dev_save(devs);=0A= >> + /* add the vdevargs to devargs_list */=0A= >> + if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, args))=0A= >> + goto err1;=0A= >> + /* parse vdevargs, then retrieve device name */=0A= >> + get_vdev_name(args);=0A= >> + /* walk around dev_driver_list to find the driver of the device,=0A= >> + * then invoke probe function o the driver */=0A= >> + if (rte_eal_vdev_find_and_invoke(args, RTE_EAL_INVOKE_TYPE_PROBE))=0A= >> + goto err2;=0A= >> + /* get port_id enabled by above procedures */=0A= >> + if (rte_eth_dev_get_changed_port(devs, &new_port_id))=0A= >> + goto err2;=0A= >> +=0A= >> + free(args);=0A= >> + *port_id =3D new_port_id;=0A= >> + return 0;=0A= >> +err2:=0A= >> + rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, args);=0A= >> +err1:=0A= >> + free(args);=0A= >> +err0:=0A= >> + RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");=0A= =0A= Here "cannot detach the device\n" should be "cannot attach the device" I=0A= think.=0A= =0A= > Here also "Drver",=0A= >=0A= >=0A= > Thanks,=0A= > Michael=0A= >> + return -1;=0A= >> +}=0A= >> +=0A= >> +/* detach the new virtual device, then store the name of the device */= =0A= >> +static int=0A= >> +rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname)=0A= >> +{=0A= >> + char name[RTE_ETH_NAME_MAX_LEN];=0A= >> +=0A= >> + if (vdevname =3D=3D NULL)=0A= >> + goto err;=0A= >> +=0A= >> + /* check whether the driver supports detach feature, or not */=0A= >> + if (rte_eth_dev_check_detachable(port_id))=0A= >> + goto err;=0A= >> +=0A= >> + /* get device name by port id */=0A= >> + if (rte_eth_dev_get_name_by_port(port_id, name))=0A= >> + goto err;=0A= >> + /* walk around dev_driver_list to find the driver of the device,=0A= >> + * then invoke close function o the driver */=0A= >> + if (rte_eal_vdev_find_and_invoke(name, RTE_EAL_INVOKE_TYPE_CLOSE))=0A= >> + goto err;=0A= >> + /* remove the vdevname from devargs_list */=0A= >> + if (rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, name))=0A= >> + goto err;=0A= >> +=0A= >> + strncpy(vdevname, name, sizeof(name));=0A= >> + return 0;=0A= >> +err:=0A= >> + RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");=0A= >> + return -1;=0A= >> +}=0A= >> +=0A= >> +/* attach the new device, then store port_id of the device */=0A= >> +int=0A= >> +rte_eal_dev_attach(const char *devargs, uint8_t *port_id)=0A= >> +{=0A= >> + struct rte_pci_addr addr;=0A= >> +=0A= >> + if ((devargs =3D=3D NULL) || (port_id =3D=3D NULL))=0A= >> + return -EINVAL;=0A= >> +=0A= >> + if (eal_parse_pci_DomBDF(devargs, &addr) =3D=3D 0)=0A= >> + return rte_eal_dev_attach_pdev(&addr, port_id);=0A= >> + else=0A= >> + return rte_eal_dev_attach_vdev(devargs, port_id);=0A= >> +}=0A= >> +=0A= >> +/* detach the device, then store the name of the device */=0A= >> +int=0A= >> +rte_eal_dev_detach(uint8_t port_id, char *name)=0A= >> +{=0A= >> + struct rte_pci_addr addr;=0A= >> + int ret;=0A= >> +=0A= >> + if (name =3D=3D NULL)=0A= >> + return -EINVAL;=0A= >> +=0A= >> + if (rte_eth_dev_get_device_type(port_id) =3D=3D RTE_ETH_DEV_PHYSICAL) = {=0A= >> + ret =3D rte_eth_dev_get_addr_by_port(port_id, &addr);=0A= >> + if (ret < 0)=0A= >> + return ret;=0A= >> +=0A= >> + ret =3D rte_eal_dev_detach_pdev(port_id, &addr);=0A= >> + if (ret =3D=3D 0)=0A= >> + snprintf(name, RTE_ETH_NAME_MAX_LEN,=0A= >> + "%04x:%02x:%02x.%d",=0A= >> + addr.domain, addr.bus,=0A= >> + addr.devid, addr.function);=0A= >> +=0A= >> + return ret;=0A= >> + } else=0A= >> + return rte_eal_dev_detach_vdev(port_id, name);=0A= >> +}=0A= >> +#else /* ENABLE_HOTPLUG */=0A= >> +int=0A= >> +rte_eal_dev_attach(const char *devargs __rte_unused,=0A= >> + uint8_t *port_id __rte_unused)=0A= >> +{=0A= >> + RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");=0A= >> + return -1;=0A= >> +}=0A= >> +=0A= >> +/* detach the device, then store the name of the device */=0A= >> +int=0A= >> +rte_eal_dev_detach(uint8_t port_id __rte_unused,=0A= >> + char *name __rte_unused)=0A= >> +{=0A= >> + RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");=0A= >> + return -1;=0A= >> +}=0A= >> +#endif /* ENABLE_HOTPLUG */=0A= >> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common= /eal_private.h=0A= >> index 1a362ab..8168a7a 100644=0A= >> --- a/lib/librte_eal/common/eal_private.h=0A= >> +++ b/lib/librte_eal/common/eal_private.h=0A= >> @@ -163,6 +163,17 @@ enum rte_eal_invoke_type {=0A= >> };=0A= >> =0A= >> /**=0A= >> + * Scan the content of the PCI bus, and the devices in the devices=0A= >> + * list=0A= >> + *=0A= >> + * This function is private to EAL.=0A= >> + *=0A= >> + * @return=0A= >> + * 0 on success, negative on error=0A= >> + */=0A= >> +int rte_eal_pci_scan(void);=0A= >> +=0A= >> +/**=0A= >> * Mmap memory for single PCI device=0A= >> *=0A= >> * This function is private to EAL.=0A= >> diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/co= mmon/include/rte_dev.h=0A= >> index f7e3a10..e63dd1c 100644=0A= >> --- a/lib/librte_eal/common/include/rte_dev.h=0A= >> +++ b/lib/librte_eal/common/include/rte_dev.h=0A= >> @@ -47,6 +47,7 @@ extern "C" {=0A= >> #endif=0A= >> =0A= >> #include =0A= >> +#include =0A= >> =0A= >> /** Double linked list of device drivers. */=0A= >> TAILQ_HEAD(rte_driver_list, rte_driver);=0A= >> @@ -57,6 +58,11 @@ TAILQ_HEAD(rte_driver_list, rte_driver);=0A= >> typedef int (rte_dev_init_t)(const char *name, const char *args);=0A= >> =0A= >> /**=0A= >> + * Uninitilization function called for each device driver once.=0A= >> + */=0A= >> +typedef int (rte_dev_uninit_t)(const char *name, const char *args);=0A= >> +=0A= >> +/**=0A= >> * Driver type enumeration=0A= >> */=0A= >> enum pmd_type {=0A= >> @@ -72,6 +78,7 @@ struct rte_driver {=0A= >> enum pmd_type type; /**< PMD Driver type */=0A= >> const char *name; /**< Driver name. */=0A= >> rte_dev_init_t *init; /**< Device init. function. */=0A= >> + rte_dev_uninit_t *uninit; /**< Device uninit. function. */=0A= >> };=0A= >> =0A= >> /**=0A= >> @@ -93,6 +100,32 @@ void rte_eal_driver_register(struct rte_driver *driv= er);=0A= >> void rte_eal_driver_unregister(struct rte_driver *driver);=0A= >> =0A= >> /**=0A= >> + * Attach a new device.=0A= >> + *=0A= >> + * @param devargs=0A= >> + * A pointer to a strings array describing the new device=0A= >> + * to be attached. The strings should be a pci address like=0A= >> + * '0000:01:00.0' or virtual device name like 'eth_pcap0'.=0A= >> + * @param port_id=0A= >> + * A pointer to a port identifier actually attached.=0A= >> + * @return=0A= >> + * 0 on success and port_id is filled, negative on error=0A= >> + */=0A= >> +int rte_eal_dev_attach(const char *devargs, uint8_t *port_id);=0A= >> +=0A= >> +/**=0A= >> + * Detach a device.=0A= >> + *=0A= >> + * @param port_id=0A= >> + * The port identifier of the device to detach.=0A= >> + * @param addr=0A= >> + * A pointer to a device name actually detached.=0A= >> + * @return=0A= >> + * 0 on success and devname is filled, negative on error=0A= >> + */=0A= >> +int rte_eal_dev_detach(uint8_t port_id, char *devname);=0A= >> +=0A= >> +/**=0A= >> * Initalize all the registered drivers in this process=0A= >> */=0A= >> int rte_eal_dev_init(void);=0A= >> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linux= app/eal/Makefile=0A= >> index 72ecf3a..0ec83b5 100644=0A= >> --- a/lib/librte_eal/linuxapp/eal/Makefile=0A= >> +++ b/lib/librte_eal/linuxapp/eal/Makefile=0A= >> @@ -41,6 +41,7 @@ CFLAGS +=3D -I$(RTE_SDK)/lib/librte_eal/common/include= =0A= >> CFLAGS +=3D -I$(RTE_SDK)/lib/librte_ring=0A= >> CFLAGS +=3D -I$(RTE_SDK)/lib/librte_mempool=0A= >> CFLAGS +=3D -I$(RTE_SDK)/lib/librte_malloc=0A= >> +CFLAGS +=3D -I$(RTE_SDK)/lib/librte_mbuf=0A= >> CFLAGS +=3D -I$(RTE_SDK)/lib/librte_ether=0A= >> CFLAGS +=3D -I$(RTE_SDK)/lib/librte_ivshmem=0A= >> CFLAGS +=3D -I$(RTE_SDK)/lib/librte_pmd_ring=0A= >> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linu= xapp/eal/eal_pci.c=0A= >> index 831422e..1f43688 100644=0A= >> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c=0A= >> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c=0A= >> @@ -431,8 +431,8 @@ error:=0A= >> * Scan the content of the PCI bus, and the devices in the devices=0A= >> * list=0A= >> */=0A= >> -static int=0A= >> -pci_scan(void)=0A= >> +int=0A= >> +rte_eal_pci_scan(void)=0A= >> {=0A= >> struct dirent *e;=0A= >> DIR *dir;=0A= >> @@ -764,7 +764,7 @@ rte_eal_pci_init(void)=0A= >> if (internal_config.no_pci)=0A= >> return 0;=0A= >> =0A= >> - if (pci_scan() < 0) {=0A= >> + if (rte_eal_pci_scan() < 0) {=0A= >> RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);=0A= >> return -1;=0A= >> }=0A= >=0A= =0A=