oracle intsr,SR-IOV 驱动程序 Ioctl

SR-IOV 驱动程序 Ioctl

SR-IOV 驱动程序 ioctl 用于标识可由管理员配置的特定于设备的参数,并在应用特定配置之前验证此特定配置。以下各节介绍了 ioctl 数据结构和接口。

数据结构

以下各节列出了 PF 驱动程序在实现 ioctl 之前应该定义并初始化的数据结构:

iov_param_ver_info 结构

iov_param_ver_info 结构定义如下:#define IOV_IOCTL (('I' << 24) | ('O' << 16) | ('V' << 8))

#define IOV_GET_VER_INFO (IOV_IOCTL | 0)

#define IOV_GET_PARAM_INFO (IOV_IOCTL | 1)

#define IOV_VALIDATE_PARAM (IOV_IOCTL | 2)

#define IOV_PARAM_DESC_VERSION 1

iov_param_ver_info 结构包含以下字段:typedef struct iov_param_ver_info {

uint32_t version;

uint32_t num_params;

} iov_param_ver_info_t;

其中:version

版本信息

num_params

参数个数

iov_param_validate 结构

iov_param_validate 结构定义如下:#define IOV_IOCTL (('I' << 24) | ('O' << 16) | ('V' << 8))

#define IOV_GET_VER_INFO (IOV_IOCTL | 0)

#define IOV_GET_PARAM_INFO (IOV_IOCTL | 1)

#define IOV_VALIDATE_PARAM (IOV_IOCTL | 2)

#define IOV_PARAM_DESC_VERSION 1

iov_param_validate 包含以下字段:typedef struct iov_param_validate {

char pv_reason[MAX_REASON_LEN + 1];

int32_t pv_buflen;

/* encoded buffer containing params */

char pv_buf[1]; /* size of buf is pv_buflen */

} iov_param_validate_t;

其中:pv_reason

ioctl 调用失败时用于解释失败原因的一个 ASCII 字符串

pv_buflen

缓冲区 pv_buf 的长度

pv_buf

包含参数的缓冲区

iov_param_desc 结构

iov_param_desc 结构定义如下:#define IOV_IOCTL (('I' << 24) | ('O' << 16) | ('V' << 8))

#define IOV_GET_VER_INFO (IOV_IOCTL | 0)

#define IOV_GET_PARAM_INFO (IOV_IOCTL | 1)

#define IOV_VALIDATE_PARAM (IOV_IOCTL | 2)

#define IOV_PARAM_DESC_VERSION 1

iov_param_desc 结构包含以下字段:typedef struct iov_param_desc {

char pd_name[MAX_PARAM_NAME_SIZE];

char pd_desc[MAX_PARAM_DESC_SIZE];

int32_t pd_flag; /* applicable for PF or VF or both */

int32_t pd_data_type; /* integer, string, plist */

/* Following 3 are applicable for integer data types */

uint64_t pd_default_value;

uint64_t pd_min64;

uint64_t pd_max64;

char pd_default_string [MAX_PARAM_DEFAULT_STRING_SIZE];

} iov_param_desc_t;

其中:pd_name

在 ldm(1M) 命令或 pci.conf 文件中使用,用于为参数指定值。

pd_desc

参数的简短说明。

pd_flag

指示参数是仅适用于 PF,还是仅适用于 VF,亦或是同时适用于 PF 和 VF。

pd_default_value

未在 ldm() 命令或 pci.conf 文件中指定参数时由驱动程序指定的值。

pd_min64

指定整数参数值的最小范围。

pd_max64

指定整数参数值的最大范围。

pd_default_string

指定将使用的缺省字符串(如果参数是字符串)。

IOV_GET_VER_INFO Ioctl

实现了 IOV_GET_VER_INFO IOCTL() ioctl 的 SR-IOV 设备驱动程序应在 iov_param_ver_info 结构中设置 version 和 num_params 字段,并将值返回到调用函数。调用函数随后将使用

version 和 num_params 参数确定使用 IOV_GET_PARAM_INFO() ioctl 调用获取参数描述所需的缓冲区大小。

IOV_GET_PARAM_INFO Ioctl

调用 IOV_GET_PARAM_INFO() ioctl 的驱动程序的一般控制流如下所述:

保留 iov_param_desc_t 结构的数组,这些结构包含各自支持的每个可配置参数的说明。有关结构说明的信息,请参见 iov_param_desc 结构。

将 iov_param_desc_t 结构的数组复制到 arg 参数。iov_param_desc_t 结构中的字段是静态字段,可在编译时定义。

数组中元素的数量是 IOV_GET_VER_INFO() ioctl 调用返回的 num_params 值。缓冲区的大小为 sizeof (iov_param_desc_t) * num_params。

IOV_VALIDATE_PARAM Ioctl

对调用 IOV_VALIDATE_PARAM() 的驱动程序的一般控制流程如下所述:

将 arg 参数发送到 pci_param_get_ioctl() 接口并获取指向 pci_param_t 结构的指针。

当 param 验证失败时,向 pv_reason 数组写入一个解释性的字符串。

依次调用 pci_get_plist() 接口和 pci_plist_lookup() 接口来获取设备参数。

在 PF plist 中查找 vfs 名称-值对以获取要针对此配置的验证而配置的 VF 的数量。驱动程序应使用长度至少为 16 位的整数数据类型查找 vfs 名称-值对。使用 pciv_plist_getvf() 接口获取 VF 设备的 plist 参数。

在不实际将参数应用于设备的情况下对参数进行验证。

在找到有效配置时返回 0。

9ec17bb8362d132e8f41d90e209eb49c.gif注意 -上述过程中验证的参数与设备的当前配置毫不相关。它们需要单独进行验证(假定它们可以进一步配置)。如果不单独进行验证,驱动程序应返回 DDI_EINVAL 来指示配置不正确。当发现了无效配置时,驱动程序还应在 iov_param_validate 结构的 pv_reason 字段中提供一个解释性字符串。此字符串会将配置失败的原因告知管理员。

驱动程序回调

DDI 接口 ddi_cb_register() 和 ddi_cb_unregister() 用来注册回调。回调用于事件通知和传入数据通信。回调在传输期间充当每个事件的事件处理程序。

SR-IOV 驱动程序应实现其他回调以在配置或取消配置 VF 前后通知 PF 驱动程序。

驱动程序可以使用以下 DDI 回调注册机制接口实现回调:

int ddi_cb_register(dev_info_t *dip, ddi_cb_flags_t flags, ddi_cb_func_t cbfunc,

void *arg1, void *arg2,ddi_cb_handle_t *ret_hdlp)

typedef int(*ddi_cb_func_t)

(dev_info_t *dip, ddi_cb_action_t action,

void *cbarg, void *arg1, void *arg2)

其中:dip

是指向 dev_info 结构的指针。

cbarg

是指向 pciv_config_vf_t 结构的指针。

action

设置为 DDI_CB_PCIV_CONFIG_VF 以接收有关对 VF 配置所做更改的通知。

arg1

在每次执行自己的 cbfunc() 例程期间发送给自己的专用参数。

arg2

在每次执行自己的 cbfunc() 例程期间发送给自己的专用参数。

有关更多信息,请参见注册回调处理程序函数。

注 -具有 SR-IOV 功能的所有 PF 驱动程序必须使用 ddi_cb_flags_t DDI_CB_FLAG_SRIOV 来通知 Oracle Solaris IOV 框架 PF

驱动程序具有 SR-IOV 功能。

驱动程序 Ioctl 的样例代码

enum ioc_reply

igb_ioctl(igb_t *igb, struct iocblk *iocp, mblk_t *mp)

{

int rval = 0;

iov_param_ver_info_t *iov_param_ver;

iov_param_validate_t pvalidate;

pci_param_t my_params;

char reason[81];

if (mp->b_cont == NULL)

return (IOC_INVAL);

if ((int)iocp->ioc_count < 0)

return (IOC_INVAL);

switch (iocp->ioc_cmd) {

case IOV_GET_PARAM_VER_INFO:

if (iocp->ioc_count < sizeof (iov_param_ver_info_t))

return (IOC_INVAL);

iov_param_ver = (iov_param_ver_info_t *)(mp->b_cont->b_rptr);

iov_param_ver->version = IOV_PARAM_DESC_VERSION;

iov_param_ver->num_params = NUM_OF_PARAMS;

return (IOC_REPLY);

case IOV_GET_PARAM_INFO:

if (iocp->ioc_count < sizeof (pci_list))

return (IOC_INVAL);

memcpy((caddr_t)(mp->b_cont->b_rptr), &pci_list,sizeof (pci_list));

return (IOC_REPLY);

case IOV_VALIDATE_PARAM:

if (iocp->ioc_count <= 0)

return (IOC_INVAL);

strcpy(reason, "Failed to read params sent\n");

rval = pci_param_get_ioctl(igb->dip,(uintptr_t)(mp->b_cont->b_rptr),

iocp->ioc_flag | FKIOCTL,&my_params );

if (rval == 0) {

rval = validate_params(igb->dip, my_params, reason);

pci_param_free(my_params);

}

if (rval) {

memcpy(mp->b_cont->b_rptr, reason, sizeof (reason));

iocp->ioc_count = sizeof (reason);

return (IOC_REPLY);

}

iocp->ioc_count = 0;

return (IOC_REPLY);

iov_param_ver_info_t iov_param_ver;

iov_param_validate_t pvalidate;

pci_param_t my_params;

switch (cmd) {

case IOV_GET_PARAM_VER_INFO:

iov_param_ver.version = IOV_PARAM_DESC_VERSION;

iov_param_ver.num_params = NUM_OF_PARAMS;

if (ddi_copyout(&iov_param_ver, (caddr_t)arg,

sizeof (iov_param_ver_info_t), mode) != DDI_SUCCESS)

return (DEFAULT);

return (0);

case IOV_GET_PARAM_INFO:

if (ddi_copyout(&pci_list, (caddr_t)arg,param_list_size, mode) != DDI_SUCCESS)

return (DEFAULT);

return (0);

case IOV_VALIDATE_PARAM:

strcpy(reason, "Failed to read params sent\n");

rv = pci_param_get_ioctl(state->dip, arg, mode, &my_params);

if (rv == 0)

rv = validate_params(state->dip, my_params, reason);

else

return (rv);

pci_param_free(my_params);

if (rv) {

if (ddi_copyout(reason,iov_param_validate_t *)arg)->pv_reason,

sizeof (reason), mode) != DDI_SUCCESS)

return (DEFAULT);

return (rv);

}

return (0);

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值