[dpdk-dev] [PATCH v6 12/13] eal/pci: Add rte_eal_dev_attach/detach() functions

Qiu, Michael michael.qiu at intel.com
Mon Feb 2 07:22:24 CET 2015


On 2/2/2015 1:43 PM, Qiu, Michael wrote:
> On 2/1/2015 12:02 PM, Tetsuya Mukawa wrote:
>> These functions are used for attaching or detaching a port.
>> When rte_eal_dev_attach() is called, the function tries to realize the
>> device name as pci address. If this is done successfully,
>> rte_eal_dev_attach() will attach physical device port. If not, attaches
>> virtual devive port.
>> When rte_eal_dev_detach() is called, the function gets the device type
>> of this port to know whether the port is came from physical or virtual.
>> And then specific detaching function will be called.
>>
>> v5:
>> - Change function names like below.
>>   rte_eal_dev_find_and_invoke() to rte_eal_vdev_find_and_invoke().
>>   rte_eal_dev_invoke() to rte_eal_vdev_invoke().
>> - Add code to handle a return value of rte_eal_devargs_remove().
>> - Fix pci address format in rte_eal_dev_detach().
>> v4:
>> - Fix comment.
>> - Add error checking.
>> - Fix indent of 'if' statement.
>> - Change function name.
>>

[...]

>> +/* attach the new virtual device, then store port_id of the device */
>> +static int
>> +rte_eal_dev_attach_vdev(const char *vdevargs, uint8_t *port_id)
>> +{
>> +	char *args;
>> +	uint8_t new_port_id;
>> +	struct rte_eth_dev devs[RTE_MAX_ETHPORTS];
>> +
>> +	if ((vdevargs == NULL) || (port_id == NULL))
>> +		goto err0;
>> +
>> +	args = strdup(vdevargs);
>> +	if (args == NULL)
>> +		goto err0;
>> +
>> +	/* save current port status */
>> +	rte_eth_dev_save(devs);
>> +	/* add the vdevargs to devargs_list */
>> +	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, args))
>> +		goto err1;
>> +	/* parse vdevargs, then retrieve device name */
>> +	get_vdev_name(args);
>> +	/* walk around dev_driver_list to find the driver of the device,
>> +	 * then invoke probe function o the driver */
>> +	if (rte_eal_vdev_find_and_invoke(args, RTE_EAL_INVOKE_TYPE_PROBE))
>> +		goto err2;
>> +	/* get port_id enabled by above procedures */
>> +	if (rte_eth_dev_get_changed_port(devs, &new_port_id))
>> +		goto err2;
>> +
>> +	free(args);
>> +	*port_id = new_port_id;
>> +	return 0;
>> +err2:
>> +	rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, args);
>> +err1:
>> +	free(args);
>> +err0:
>> +	RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");

Here "cannot detach the device\n" should be "cannot attach the device" I
think.

> Here also "Drver",
>
>
> Thanks,
> Michael
>> +	return -1;
>> +}
>> +
>> +/* detach the new virtual device, then store the name of the device */
>> +static int
>> +rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname)
>> +{
>> +	char name[RTE_ETH_NAME_MAX_LEN];
>> +
>> +	if (vdevname == NULL)
>> +		goto err;
>> +
>> +	/* check whether the driver supports detach feature, or not */
>> +	if (rte_eth_dev_check_detachable(port_id))
>> +		goto err;
>> +
>> +	/* get device name by port id */
>> +	if (rte_eth_dev_get_name_by_port(port_id, name))
>> +		goto err;
>> +	/* walk around dev_driver_list to find the driver of the device,
>> +	 * then invoke close function o the driver */
>> +	if (rte_eal_vdev_find_and_invoke(name, RTE_EAL_INVOKE_TYPE_CLOSE))
>> +		goto err;
>> +	/* remove the vdevname from devargs_list */
>> +	if (rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, name))
>> +		goto err;
>> +
>> +	strncpy(vdevname, name, sizeof(name));
>> +	return 0;
>> +err:
>> +	RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
>> +	return -1;
>> +}
>> +
>> +/* attach the new device, then store port_id of the device */
>> +int
>> +rte_eal_dev_attach(const char *devargs, uint8_t *port_id)
>> +{
>> +	struct rte_pci_addr addr;
>> +
>> +	if ((devargs == NULL) || (port_id == NULL))
>> +		return -EINVAL;
>> +
>> +	if (eal_parse_pci_DomBDF(devargs, &addr) == 0)
>> +		return rte_eal_dev_attach_pdev(&addr, port_id);
>> +	else
>> +		return rte_eal_dev_attach_vdev(devargs, port_id);
>> +}
>> +
>> +/* detach the device, then store the name of the device */
>> +int
>> +rte_eal_dev_detach(uint8_t port_id, char *name)
>> +{
>> +	struct rte_pci_addr addr;
>> +	int ret;
>> +
>> +	if (name == NULL)
>> +		return -EINVAL;
>> +
>> +	if (rte_eth_dev_get_device_type(port_id) == RTE_ETH_DEV_PHYSICAL) {
>> +		ret = rte_eth_dev_get_addr_by_port(port_id, &addr);
>> +		if (ret < 0)
>> +			return ret;
>> +
>> +		ret = rte_eal_dev_detach_pdev(port_id, &addr);
>> +		if (ret == 0)
>> +			snprintf(name, RTE_ETH_NAME_MAX_LEN,
>> +				"%04x:%02x:%02x.%d",
>> +				addr.domain, addr.bus,
>> +				addr.devid, addr.function);
>> +
>> +		return ret;
>> +	} else
>> +		return rte_eal_dev_detach_vdev(port_id, name);
>> +}
>> +#else /* ENABLE_HOTPLUG */
>> +int
>> +rte_eal_dev_attach(const char *devargs __rte_unused,
>> +			uint8_t *port_id __rte_unused)
>> +{
>> +	RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
>> +	return -1;
>> +}
>> +
>> +/* detach the device, then store the name of the device */
>> +int
>> +rte_eal_dev_detach(uint8_t port_id __rte_unused,
>> +			char *name __rte_unused)
>> +{
>> +	RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
>> +	return -1;
>> +}
>> +#endif /* ENABLE_HOTPLUG */
>> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
>> index 1a362ab..8168a7a 100644
>> --- a/lib/librte_eal/common/eal_private.h
>> +++ b/lib/librte_eal/common/eal_private.h
>> @@ -163,6 +163,17 @@ enum rte_eal_invoke_type {
>>  };
>>  
>>  /**
>> + * Scan the content of the PCI bus, and the devices in the devices
>> + * list
>> + *
>> + * This function is private to EAL.
>> + *
>> + * @return
>> + *  0 on success, negative on error
>> + */
>> +int rte_eal_pci_scan(void);
>> +
>> +/**
>>   * Mmap memory for single PCI device
>>   *
>>   * This function is private to EAL.
>> diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
>> index f7e3a10..e63dd1c 100644
>> --- a/lib/librte_eal/common/include/rte_dev.h
>> +++ b/lib/librte_eal/common/include/rte_dev.h
>> @@ -47,6 +47,7 @@ extern "C" {
>>  #endif
>>  
>>  #include <sys/queue.h>
>> +#include <rte_pci.h>
>>  
>>  /** Double linked list of device drivers. */
>>  TAILQ_HEAD(rte_driver_list, rte_driver);
>> @@ -57,6 +58,11 @@ TAILQ_HEAD(rte_driver_list, rte_driver);
>>  typedef int (rte_dev_init_t)(const char *name, const char *args);
>>  
>>  /**
>> + * Uninitilization function called for each device driver once.
>> + */
>> +typedef int (rte_dev_uninit_t)(const char *name, const char *args);
>> +
>> +/**
>>   * Driver type enumeration
>>   */
>>  enum pmd_type {
>> @@ -72,6 +78,7 @@ struct rte_driver {
>>  	enum pmd_type type;		   /**< PMD Driver type */
>>  	const char *name;                   /**< Driver name. */
>>  	rte_dev_init_t *init;              /**< Device init. function. */
>> +	rte_dev_uninit_t *uninit;          /**< Device uninit. function. */
>>  };
>>  
>>  /**
>> @@ -93,6 +100,32 @@ void rte_eal_driver_register(struct rte_driver *driver);
>>  void rte_eal_driver_unregister(struct rte_driver *driver);
>>  
>>  /**
>> + * Attach a new device.
>> + *
>> + * @param devargs
>> + *   A pointer to a strings array describing the new device
>> + *   to be attached. The strings should be a pci address like
>> + *   '0000:01:00.0' or virtual device name like 'eth_pcap0'.
>> + * @param port_id
>> + *  A pointer to a port identifier actually attached.
>> + * @return
>> + *  0 on success and port_id is filled, negative on error
>> + */
>> +int rte_eal_dev_attach(const char *devargs, uint8_t *port_id);
>> +
>> +/**
>> + * Detach a device.
>> + *
>> + * @param port_id
>> + *   The port identifier of the device to detach.
>> + * @param addr
>> + *  A pointer to a device name actually detached.
>> + * @return
>> + *  0 on success and devname is filled, negative on error
>> + */
>> +int rte_eal_dev_detach(uint8_t port_id, char *devname);
>> +
>> +/**
>>   * Initalize all the registered drivers in this process
>>   */
>>  int rte_eal_dev_init(void);
>> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
>> index 72ecf3a..0ec83b5 100644
>> --- a/lib/librte_eal/linuxapp/eal/Makefile
>> +++ b/lib/librte_eal/linuxapp/eal/Makefile
>> @@ -41,6 +41,7 @@ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
>>  CFLAGS += -I$(RTE_SDK)/lib/librte_ring
>>  CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
>>  CFLAGS += -I$(RTE_SDK)/lib/librte_malloc
>> +CFLAGS += -I$(RTE_SDK)/lib/librte_mbuf
>>  CFLAGS += -I$(RTE_SDK)/lib/librte_ether
>>  CFLAGS += -I$(RTE_SDK)/lib/librte_ivshmem
>>  CFLAGS += -I$(RTE_SDK)/lib/librte_pmd_ring
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
>> index 831422e..1f43688 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
>> @@ -431,8 +431,8 @@ error:
>>   * Scan the content of the PCI bus, and the devices in the devices
>>   * list
>>   */
>> -static int
>> -pci_scan(void)
>> +int
>> +rte_eal_pci_scan(void)
>>  {
>>  	struct dirent *e;
>>  	DIR *dir;
>> @@ -764,7 +764,7 @@ rte_eal_pci_init(void)
>>  	if (internal_config.no_pci)
>>  		return 0;
>>  
>> -	if (pci_scan() < 0) {
>> +	if (rte_eal_pci_scan() < 0) {
>>  		RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
>>  		return -1;
>>  	}
>



More information about the dev mailing list