-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathadminqueue.cc
124 lines (112 loc) · 3.64 KB
/
adminqueue.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "adminqueue.h"
void DevNvmeAdminQueue::Init(DevNvme *nvme) {
_nvme = nvme;
_queue = new DevNvmeQueue();
_queue->Init(_nvme, 0, kASQSize, kACQSize);
nvme->SetCtrlReg64(DevNvme::kCtrlReg64OffsetASQ,
_queue->GetSubmissionQueuePhysPtr());
nvme->SetCtrlReg64(DevNvme::kCtrlReg64OffsetACQ,
_queue->GetCompletionQueuePhysPtr());
{
uint32_t aqa = 0;
aqa |= (0xfff & kACQSize) << 16;
aqa |= (0xfff & kASQSize);
nvme->SetCtrlReg32(DevNvme::kCtrlReg32OffsetAQA, aqa);
}
}
void DevNvmeAdminQueue::InterruptHandler() { _queue->InterruptHandler(); }
volatile CompletionQueueEntry *DevNvmeAdminQueue::AttachNamespace(
uint16_t nsid, uint16_t qid) {
Memory prp(4096);
uint16_t *ctrl_list = prp.GetVirtPtr<uint16_t>();
ctrl_list[0] = 1;
ctrl_list[1] = qid;
volatile CompletionQueueEntry *cqe =
SubmitCmdNamespaceAttachment(&prp, 0, nsid);
cqe->PrintIfError("AttachNamespace");
return cqe;
}
volatile CompletionQueueEntry *DevNvmeAdminQueue::SubmitCmdIdentify(
const Memory *prp1, uint32_t nsid, uint16_t cntid, uint8_t cns) {
_queue->Lock();
int32_t slot = _queue->GetNextSubmissionSlot();
//
volatile CommandSet *cmd = _queue->GetCommandSet(slot);
cmd->CDW0.OPC = kCmdIdentify;
cmd->CDW0.CID = slot;
cmd->CDW0.FUSE = kFUSE_Normal;
cmd->CDW0.PSDT = kPSDT_UsePRP;
//
cmd->PRP1 = prp1->GetPhysPtr();
cmd->NSID = nsid;
cmd->CDW10 = cntid << 16 | cns;
//
_queue->SubmitCommand();
volatile CompletionQueueEntry *cqe = _queue->WaitUntilCompletion(slot);
_queue->Unlock();
return cqe;
}
volatile CompletionQueueEntry *
DevNvmeAdminQueue::SubmitCmdCreateIoCompletionQueue(const Memory *prp1,
uint16_t size,
uint16_t qid) {
_queue->Lock();
int32_t slot = _queue->GetNextSubmissionSlot();
//
volatile CommandSet *cmd = _queue->GetCommandSet(slot);
cmd->CDW0.OPC = kCmdCreateIoCompletionQueue;
cmd->CDW0.CID = slot;
cmd->CDW0.FUSE = kFUSE_Normal;
cmd->CDW0.PSDT = kPSDT_UsePRP;
//
cmd->PRP1 = prp1->GetPhysPtr();
cmd->CDW10 = size << 16 | qid;
cmd->CDW11 = 3;
//
_queue->SubmitCommand();
volatile CompletionQueueEntry *cqe = _queue->WaitUntilCompletion(slot);
_queue->Unlock();
return cqe;
}
volatile CompletionQueueEntry *
DevNvmeAdminQueue::SubmitCmdCreateIoSubmissionQueue(const Memory *prp1,
uint16_t size, uint16_t qid,
uint16_t cqid) {
_queue->Lock();
int32_t slot = _queue->GetNextSubmissionSlot();
//
volatile CommandSet *cmd = _queue->GetCommandSet(slot);
cmd->CDW0.OPC = kCmdCreateIoSubmissionQueue;
cmd->CDW0.CID = slot;
cmd->CDW0.FUSE = kFUSE_Normal;
cmd->CDW0.PSDT = kPSDT_UsePRP;
//
cmd->PRP1 = prp1->GetPhysPtr();
cmd->CDW10 = size << 16 | qid;
cmd->CDW11 = cqid << 16 | 1;
//
_queue->SubmitCommand();
volatile CompletionQueueEntry *cqe = _queue->WaitUntilCompletion(slot);
_queue->Unlock();
return cqe;
}
volatile CompletionQueueEntry *DevNvmeAdminQueue::SubmitCmdNamespaceAttachment(
const Memory *prp1, int sel, uint16_t nsid) {
_queue->Lock();
int32_t slot = _queue->GetNextSubmissionSlot();
//
volatile CommandSet *cmd = _queue->GetCommandSet(slot);
cmd->CDW0.OPC = kCmdIdentify;
cmd->CDW0.CID = slot;
cmd->CDW0.FUSE = kFUSE_Normal;
cmd->CDW0.PSDT = kPSDT_UsePRP;
//
cmd->NSID = nsid;
cmd->PRP1 = prp1->GetPhysPtr();
cmd->CDW10 = sel;
//
_queue->SubmitCommand();
volatile CompletionQueueEntry *cqe = _queue->WaitUntilCompletion(slot);
_queue->Unlock();
return cqe;
}