nvme_submit_user_cmd分析
时间: 2023-07-22 12:33:27 浏览: 426
`nvme_submit_user_cmd()` 函数是 NVMe 驱动中用于向 NVMe 设备提交用户命令的函数。该函数的实现如下:
```c
int nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
void __user *ubuf, void __user *meta, unsigned timeout)
{
...
struct nvme_ns *ns = q->queuedata;
...
struct nvme_user_io io = {
.opcode = cmd->common.opcode,
.flags = cmd->common.flags,
.control = cpu_to_le16((timeout ? NVME_IO_FLAGS_PRACT : 0) |
NVME_IO_FLAGS_CQ_UPDATE |
NVME_IO_FLAGS_SGL_METABUF),
.metadata = (__u64)meta,
.addr = (__u64)ubuf,
.slba = cpu_to_le64(cmd->rw.slba),
.nlb = cpu_to_le16(cmd->rw.nblocks),
.dsmgmt = cpu_to_le16(cmd->rw.dsmgmt),
.reftag = cpu_to_le16(cmd->rw.reftag),
.apptag = cpu_to_le16(cmd->rw.apptag),
.appmask = cpu_to_le16(cmd->rw.appmask),
};
...
ret = nvme_submit_user_cmd_hw(q, ns, &io, &cmd->common, timeout);
...
return ret;
}
```
该函数的主要作用是将用户命令转换为 `nvme_user_io` 结构体,并调用 `nvme_submit_user_cmd_hw()` 函数将该命令提交给 NVMe 设备。下面是对该函数的参数及关键代码进行分析:
- `q`:请求队列指针,用于指定 NVMe 设备所在的请求队列。
- `cmd`:NVMe 命令结构体指针,包含了要提交的 NVMe 写入命令的相关信息。
- `ubuf`:用户数据缓冲区的指针,该缓冲区包含了要写入存储介质的数据。
- `meta`:元数据缓冲区的指针,该缓冲区用于存储 NVMe 设备返回的写入操作结果。
- `timeout`:命令超时时间,以毫秒为单位。
该函数首先从请求队列中获取 NVMe 命名空间指针 `ns`,然后将用户命令转换为 `nvme_user_io` 结构体,并设置了一些命令的控制标志位。接着,该函数调用 `nvme_submit_user_cmd_hw()` 函数将命令提交给 NVMe 设备。
在 `nvme_submit_user_cmd_hw()` 函数中,NVMe 驱动会将 `nvme_user_io` 结构体中的数据转换为 NVMe 命令数据结构,并将该命令放入命令队列中。然后,NVMe 驱动会等待命令完成,并将命令的执行结果存储到元数据缓冲区中。最后,驱动程序会更新命令队列和完成队列的指针,并返回命令的执行状态。
在 NVMe 驱动中,`nvme_submit_user_cmd()` 函数是将用户命令提交给 NVMe 设备的入口函数,它的实现非常简单,主要是将用户命令转换为 NVMe 命令,并调用硬件相关的函数将命令提交给 NVMe 设备。
阅读全文