@@ -2,6 +2,7 @@ use std::cmp::min;
2
2
use std:: mem:: size_of;
3
3
4
4
use super :: bits:: { self , * } ;
5
+ use super :: queue:: { QueueId , ADMIN_QUEUE_ID } ;
5
6
use crate :: common:: GuestAddr ;
6
7
use crate :: { common:: PAGE_SIZE , dispatch:: DispCtx } ;
7
8
@@ -16,6 +17,14 @@ impl NvmeCtrl {
16
17
cmd : & cmds:: CreateIOCQCmd ,
17
18
ctx : & DispCtx ,
18
19
) -> cmds:: Completion {
20
+ // If the host hasn't specified an IOCQES, fail this request
21
+ if self . ctrl . cc . iocqes ( ) == 0 {
22
+ return cmds:: Completion :: specific_err (
23
+ StatusCodeType :: CmdSpecific ,
24
+ STS_CREATE_IO_Q_INVAL_QSIZE ,
25
+ ) ;
26
+ }
27
+
19
28
if cmd. intr_vector >= super :: NVME_MSIX_COUNT {
20
29
return cmds:: Completion :: specific_err (
21
30
StatusCodeType :: CmdSpecific ,
@@ -57,6 +66,14 @@ impl NvmeCtrl {
57
66
cmd : & cmds:: CreateIOSQCmd ,
58
67
ctx : & DispCtx ,
59
68
) -> cmds:: Completion {
69
+ // If the host hasn't specified an IOSQES, fail this request
70
+ if self . ctrl . cc . iosqes ( ) == 0 {
71
+ return cmds:: Completion :: specific_err (
72
+ StatusCodeType :: CmdSpecific ,
73
+ STS_CREATE_IO_Q_INVAL_QSIZE ,
74
+ ) ;
75
+ }
76
+
60
77
// We only support physical contiguous queues
61
78
if !cmd. phys_contig {
62
79
return cmds:: Completion :: generic_err ( bits:: STS_INVAL_FIELD ) ;
@@ -89,6 +106,79 @@ impl NvmeCtrl {
89
106
}
90
107
}
91
108
109
+ /// Service I/O Delete Completion Queue command.
110
+ ///
111
+ /// See NVMe 1.0e Section 5.5 Delete I/O Submission Queue command
112
+ pub ( super ) fn acmd_delete_io_cq (
113
+ & mut self ,
114
+ cqid : QueueId ,
115
+ _ctx : & DispCtx ,
116
+ ) -> cmds:: Completion {
117
+ // Not allowed to delete the Admin Completion Queue
118
+ if cqid == ADMIN_QUEUE_ID {
119
+ return cmds:: Completion :: specific_err (
120
+ StatusCodeType :: CmdSpecific ,
121
+ STS_DELETE_IO_Q_INVAL_QID ,
122
+ ) ;
123
+ }
124
+
125
+ // Remove the CQ from our list of active CQs.
126
+ // At this point, all associated SQs should've been deleted
127
+ // otherwise we'll return an error.
128
+ match self . delete_cq ( cqid) {
129
+ Ok ( ( ) ) => cmds:: Completion :: success ( ) ,
130
+ Err ( NvmeError :: InvalidCompQueue ( _) ) => {
131
+ cmds:: Completion :: specific_err (
132
+ StatusCodeType :: CmdSpecific ,
133
+ STS_DELETE_IO_Q_INVAL_QID ,
134
+ )
135
+ }
136
+ Err ( NvmeError :: AssociatedSubQueuesStillExist ( _, _) ) => {
137
+ cmds:: Completion :: specific_err (
138
+ StatusCodeType :: CmdSpecific ,
139
+ STS_DELETE_IO_Q_INVAL_Q_DELETION ,
140
+ )
141
+ }
142
+ _ => cmds:: Completion :: generic_err ( STS_INTERNAL_ERR ) ,
143
+ }
144
+ }
145
+
146
+ /// Service I/O Delete Submission Queue command.
147
+ ///
148
+ /// See NVMe 1.0e Section 5.6 Delete I/O Submission Queue command
149
+ pub ( super ) fn acmd_delete_io_sq (
150
+ & mut self ,
151
+ sqid : QueueId ,
152
+ _ctx : & DispCtx ,
153
+ ) -> cmds:: Completion {
154
+ // Not allowed to delete the Admin Submission Queue
155
+ if sqid == ADMIN_QUEUE_ID {
156
+ return cmds:: Completion :: specific_err (
157
+ StatusCodeType :: CmdSpecific ,
158
+ STS_DELETE_IO_Q_INVAL_QID ,
159
+ ) ;
160
+ }
161
+
162
+ // Remove the SQ from our list of active SQs which will stop
163
+ // us from accepting any new requests for it.
164
+ // That should be the only strong ref left to the SubQueue
165
+ // Any in-flight I/O requests that haven't been completed yet
166
+ // only hold a weak ref (via CompQueueEntryPermit).
167
+ // Note: The NVMe 1.0e spec says "The command causes all commands
168
+ // submitted to the indicated Submission Queue that are still in
169
+ // progress to be aborted."
170
+ match self . delete_sq ( sqid) {
171
+ Ok ( ( ) ) => cmds:: Completion :: success ( ) ,
172
+ Err ( NvmeError :: InvalidSubQueue ( _) ) => {
173
+ cmds:: Completion :: specific_err (
174
+ StatusCodeType :: CmdSpecific ,
175
+ STS_DELETE_IO_Q_INVAL_QID ,
176
+ )
177
+ }
178
+ _ => cmds:: Completion :: generic_err ( STS_INTERNAL_ERR ) ,
179
+ }
180
+ }
181
+
92
182
/// Service Get Log Page command.
93
183
///
94
184
/// See NVMe 1.0e Section 5.10 Get Log Page command
0 commit comments