| 819 | } |
| 820 | |
| 821 | static struct rt_nvme_queue *nvme_alloc_queue(struct rt_nvme_controller *nvme, |
| 822 | int qid, int depth) |
| 823 | { |
| 824 | rt_err_t err; |
| 825 | rt_ubase_t dma_flags; |
| 826 | struct rt_nvme_queue *queue = &nvme->queue[qid]; |
| 827 | |
| 828 | rt_memset(queue, 0, sizeof(*queue)); |
| 829 | |
| 830 | queue->nvme = nvme; |
| 831 | queue->doorbell = &nvme->doorbell_tbl[qid * 2 * nvme->doorbell_stride]; |
| 832 | queue->qid = qid; |
| 833 | queue->depth = depth; |
| 834 | queue->cq_head = 0; |
| 835 | queue->cq_phase = 1; |
| 836 | rt_completion_init(&queue->done); |
| 837 | rt_spin_lock_init(&queue->lock); |
| 838 | |
| 839 | dma_flags = nvme_queue_dma_flags(); |
| 840 | |
| 841 | /* struct rt_nvme_command */ |
| 842 | queue->sq_cmds = rt_dma_alloc(nvme->dev, |
| 843 | sizeof(*queue->sq_cmds) * depth, &queue->sq_cmds_phy, dma_flags); |
| 844 | |
| 845 | if (!queue->sq_cmds) |
| 846 | { |
| 847 | err = -RT_ENOMEM; |
| 848 | goto _fail; |
| 849 | } |
| 850 | |
| 851 | /* struct rt_nvme_completion */ |
| 852 | queue->cq_entry = rt_dma_alloc(nvme->dev, |
| 853 | sizeof(*queue->cq_entry) * depth, &queue->cq_entry_phy, dma_flags); |
| 854 | |
| 855 | if (!queue->cq_entry) |
| 856 | { |
| 857 | err = -RT_ENOMEM; |
| 858 | goto _fail; |
| 859 | } |
| 860 | |
| 861 | rt_memset(queue->sq_cmds, 0, sizeof(struct rt_nvme_command) * depth); |
| 862 | rt_memset(queue->cq_entry, 0, sizeof(struct rt_nvme_completion) * depth); |
| 863 | |
| 864 | if (nvme->ops->setup_queue) |
| 865 | { |
| 866 | if (!(err = nvme->ops->setup_queue(queue))) |
| 867 | { |
| 868 | LOG_E("Setup[%s] queue error = %s", nvme->ops->name, rt_strerror(err)); |
| 869 | |
| 870 | goto _fail; |
| 871 | } |
| 872 | } |
| 873 | |
| 874 | return queue; |
| 875 | |
| 876 | _fail: |
| 877 | nvme_free_queue(queue); |
| 878 |
no test coverage detected