2 * NVMe over Fabrics common host code.
3 * Copyright (c) 2015-2016 HGST, a Western Digital Company.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 #include <linux/init.h>
16 #include <linux/miscdevice.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
19 #include <linux/parser.h>
20 #include <linux/seq_file.h>
24 static LIST_HEAD(nvmf_transports);
25 static DEFINE_MUTEX(nvmf_transports_mutex);
27 static LIST_HEAD(nvmf_hosts);
28 static DEFINE_MUTEX(nvmf_hosts_mutex);
30 static struct nvmf_host *nvmf_default_host;
32 static struct nvmf_host *__nvmf_host_find(const char *hostnqn)
34 struct nvmf_host *host;
36 list_for_each_entry(host, &nvmf_hosts, list) {
37 if (!strcmp(host->nqn, hostnqn))
44 static struct nvmf_host *nvmf_host_add(const char *hostnqn)
46 struct nvmf_host *host;
48 mutex_lock(&nvmf_hosts_mutex);
49 host = __nvmf_host_find(hostnqn);
53 host = kmalloc(sizeof(*host), GFP_KERNEL);
57 kref_init(&host->ref);
58 memcpy(host->nqn, hostnqn, NVMF_NQN_SIZE);
59 uuid_le_gen(&host->id);
61 list_add_tail(&host->list, &nvmf_hosts);
63 mutex_unlock(&nvmf_hosts_mutex);
67 static struct nvmf_host *nvmf_host_default(void)
69 struct nvmf_host *host;
71 host = kmalloc(sizeof(*host), GFP_KERNEL);
75 kref_init(&host->ref);
76 uuid_le_gen(&host->id);
77 snprintf(host->nqn, NVMF_NQN_SIZE,
78 "nqn.2014-08.org.nvmexpress:NVMf:uuid:%pUl", &host->id);
80 mutex_lock(&nvmf_hosts_mutex);
81 list_add_tail(&host->list, &nvmf_hosts);
82 mutex_unlock(&nvmf_hosts_mutex);
87 static void nvmf_host_destroy(struct kref *ref)
89 struct nvmf_host *host = container_of(ref, struct nvmf_host, ref);
94 static void nvmf_host_put(struct nvmf_host *host)
97 kref_put(&host->ref, nvmf_host_destroy);
101 * nvmf_get_address() - Get address/port
102 * @ctrl: Host NVMe controller instance which we got the address
103 * @buf: OUTPUT parameter that will contain the address/port
106 int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
108 return snprintf(buf, size, "traddr=%s,trsvcid=%s\n",
109 ctrl->opts->traddr, ctrl->opts->trsvcid);
111 EXPORT_SYMBOL_GPL(nvmf_get_address);
114 * nvmf_get_subsysnqn() - Get subsystem NQN
115 * @ctrl: Host NVMe controller instance which we got the NQN
117 const char *nvmf_get_subsysnqn(struct nvme_ctrl *ctrl)
119 return ctrl->opts->subsysnqn;
121 EXPORT_SYMBOL_GPL(nvmf_get_subsysnqn);
124 * nvmf_reg_read32() - NVMe Fabrics "Property Get" API function.
125 * @ctrl: Host NVMe controller instance maintaining the admin
126 * queue used to submit the property read command to
127 * the allocated NVMe controller resource on the target system.
128 * @off: Starting offset value of the targeted property
129 * register (see the fabrics section of the NVMe standard).
130 * @val: OUTPUT parameter that will contain the value of
131 * the property after a successful read.
133 * Used by the host system to retrieve a 32-bit capsule property value
134 * from an NVMe controller on the target system.
136 * ("Capsule property" is an "PCIe register concept" applied to the
137 * NVMe fabrics space.)
141 * > 0: NVMe error status code
142 * < 0: Linux errno error code
144 int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
146 struct nvme_command cmd;
147 struct nvme_completion cqe;
150 memset(&cmd, 0, sizeof(cmd));
151 cmd.prop_get.opcode = nvme_fabrics_command;
152 cmd.prop_get.fctype = nvme_fabrics_type_property_get;
153 cmd.prop_get.offset = cpu_to_le32(off);
155 ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, &cqe, NULL, 0, 0,
159 *val = le64_to_cpu(cqe.result64);
160 if (unlikely(ret != 0))
161 dev_err(ctrl->device,
162 "Property Get error: %d, offset %#x\n",
163 ret > 0 ? ret & ~NVME_SC_DNR : ret, off);
167 EXPORT_SYMBOL_GPL(nvmf_reg_read32);
170 * nvmf_reg_read64() - NVMe Fabrics "Property Get" API function.
171 * @ctrl: Host NVMe controller instance maintaining the admin
172 * queue used to submit the property read command to
173 * the allocated controller resource on the target system.
174 * @off: Starting offset value of the targeted property
175 * register (see the fabrics section of the NVMe standard).
176 * @val: OUTPUT parameter that will contain the value of
177 * the property after a successful read.
179 * Used by the host system to retrieve a 64-bit capsule property value
180 * from an NVMe controller on the target system.
182 * ("Capsule property" is an "PCIe register concept" applied to the
183 * NVMe fabrics space.)
187 * > 0: NVMe error status code
188 * < 0: Linux errno error code
190 int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
192 struct nvme_command cmd;
193 struct nvme_completion cqe;
196 memset(&cmd, 0, sizeof(cmd));
197 cmd.prop_get.opcode = nvme_fabrics_command;
198 cmd.prop_get.fctype = nvme_fabrics_type_property_get;
199 cmd.prop_get.attrib = 1;
200 cmd.prop_get.offset = cpu_to_le32(off);
202 ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, &cqe, NULL, 0, 0,
206 *val = le64_to_cpu(cqe.result64);
207 if (unlikely(ret != 0))
208 dev_err(ctrl->device,
209 "Property Get error: %d, offset %#x\n",
210 ret > 0 ? ret & ~NVME_SC_DNR : ret, off);
213 EXPORT_SYMBOL_GPL(nvmf_reg_read64);
216 * nvmf_reg_write32() - NVMe Fabrics "Property Write" API function.
217 * @ctrl: Host NVMe controller instance maintaining the admin
218 * queue used to submit the property read command to
219 * the allocated NVMe controller resource on the target system.
220 * @off: Starting offset value of the targeted property
221 * register (see the fabrics section of the NVMe standard).
222 * @val: Input parameter that contains the value to be
223 * written to the property.
225 * Used by the NVMe host system to write a 32-bit capsule property value
226 * to an NVMe controller on the target system.
228 * ("Capsule property" is an "PCIe register concept" applied to the
229 * NVMe fabrics space.)
232 * 0: successful write
233 * > 0: NVMe error status code
234 * < 0: Linux errno error code
236 int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
238 struct nvme_command cmd;
241 memset(&cmd, 0, sizeof(cmd));
242 cmd.prop_set.opcode = nvme_fabrics_command;
243 cmd.prop_set.fctype = nvme_fabrics_type_property_set;
244 cmd.prop_set.attrib = 0;
245 cmd.prop_set.offset = cpu_to_le32(off);
246 cmd.prop_set.value = cpu_to_le64(val);
248 ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, NULL, 0, 0,
251 dev_err(ctrl->device,
252 "Property Set error: %d, offset %#x\n",
253 ret > 0 ? ret & ~NVME_SC_DNR : ret, off);
256 EXPORT_SYMBOL_GPL(nvmf_reg_write32);
259 * nvmf_log_connect_error() - Error-parsing-diagnostic print
260 * out function for connect() errors.
262 * @ctrl: the specific /dev/nvmeX device that had the error.
264 * @errval: Error code to be decoded in a more human-friendly
267 * @offset: For use with the NVMe error code NVME_SC_CONNECT_INVALID_PARAM.
269 * @cmd: This is the SQE portion of a submission capsule.
271 * @data: This is the "Data" portion of a submission capsule.
273 static void nvmf_log_connect_error(struct nvme_ctrl *ctrl,
274 int errval, int offset, struct nvme_command *cmd,
275 struct nvmf_connect_data *data)
277 int err_sctype = errval & (~NVME_SC_DNR);
279 switch (err_sctype) {
281 case (NVME_SC_CONNECT_INVALID_PARAM):
283 char *inv_data = "Connect Invalid Data Parameter";
285 switch (offset & 0xffff) {
286 case (offsetof(struct nvmf_connect_data, cntlid)):
287 dev_err(ctrl->device,
289 inv_data, data->cntlid);
291 case (offsetof(struct nvmf_connect_data, hostnqn)):
292 dev_err(ctrl->device,
293 "%s, hostnqn \"%s\"\n",
294 inv_data, data->hostnqn);
296 case (offsetof(struct nvmf_connect_data, subsysnqn)):
297 dev_err(ctrl->device,
298 "%s, subsysnqn \"%s\"\n",
299 inv_data, data->subsysnqn);
302 dev_err(ctrl->device,
303 "%s, starting byte offset: %d\n",
304 inv_data, offset & 0xffff);
308 char *inv_sqe = "Connect Invalid SQE Parameter";
311 case (offsetof(struct nvmf_connect_command, qid)):
312 dev_err(ctrl->device,
314 inv_sqe, cmd->connect.qid);
317 dev_err(ctrl->device,
318 "%s, starting byte offset: %d\n",
324 dev_err(ctrl->device,
325 "Connect command failed, error wo/DNR bit: %d\n",
328 } /* switch (err_sctype) */
332 * nvmf_connect_admin_queue() - NVMe Fabrics Admin Queue "Connect"
334 * @ctrl: Host nvme controller instance used to request
335 * a new NVMe controller allocation on the target
336 * system and establish an NVMe Admin connection to
339 * This function enables an NVMe host device to request a new allocation of
340 * an NVMe controller resource on a target system as well establish a
341 * fabrics-protocol connection of the NVMe Admin queue between the
342 * host system device and the allocated NVMe controller on the
343 * target system via a NVMe Fabrics "Connect" command.
347 * > 0: NVMe error status code
348 * < 0: Linux errno error code
351 int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl)
353 struct nvme_command cmd;
354 struct nvme_completion cqe;
355 struct nvmf_connect_data *data;
358 memset(&cmd, 0, sizeof(cmd));
359 cmd.connect.opcode = nvme_fabrics_command;
360 cmd.connect.fctype = nvme_fabrics_type_connect;
362 cmd.connect.sqsize = cpu_to_le16(ctrl->sqsize);
364 * Set keep-alive timeout in seconds granularity (ms * 1000)
365 * and add a grace period for controller kato enforcement
367 cmd.connect.kato = ctrl->opts->discovery_nqn ? 0 :
368 cpu_to_le32((ctrl->kato + NVME_KATO_GRACE) * 1000);
370 data = kzalloc(sizeof(*data), GFP_KERNEL);
374 memcpy(&data->hostid, &ctrl->opts->host->id, sizeof(uuid_le));
375 data->cntlid = cpu_to_le16(0xffff);
376 strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
377 strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);
379 ret = __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, &cqe,
380 data, sizeof(*data), 0, NVME_QID_ANY, 1,
381 BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT);
383 nvmf_log_connect_error(ctrl, ret, le32_to_cpu(cqe.result),
388 ctrl->cntlid = le16_to_cpu(cqe.result16);
394 EXPORT_SYMBOL_GPL(nvmf_connect_admin_queue);
397 * nvmf_connect_io_queue() - NVMe Fabrics I/O Queue "Connect"
399 * @ctrl: Host nvme controller instance used to establish an
400 * NVMe I/O queue connection to the already allocated NVMe
401 * controller on the target system.
402 * @qid: NVMe I/O queue number for the new I/O connection between
403 * host and target (note qid == 0 is illegal as this is
404 * the Admin queue, per NVMe standard).
406 * This function issues a fabrics-protocol connection
407 * of a NVMe I/O queue (via NVMe Fabrics "Connect" command)
408 * between the host system device and the allocated NVMe controller
409 * on the target system.
413 * > 0: NVMe error status code
414 * < 0: Linux errno error code
416 int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid)
418 struct nvme_command cmd;
419 struct nvmf_connect_data *data;
420 struct nvme_completion cqe;
423 memset(&cmd, 0, sizeof(cmd));
424 cmd.connect.opcode = nvme_fabrics_command;
425 cmd.connect.fctype = nvme_fabrics_type_connect;
426 cmd.connect.qid = cpu_to_le16(qid);
427 cmd.connect.sqsize = cpu_to_le16(ctrl->sqsize);
429 data = kzalloc(sizeof(*data), GFP_KERNEL);
433 memcpy(&data->hostid, &ctrl->opts->host->id, sizeof(uuid_le));
434 data->cntlid = cpu_to_le16(ctrl->cntlid);
435 strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
436 strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);
438 ret = __nvme_submit_sync_cmd(ctrl->connect_q, &cmd, &cqe,
439 data, sizeof(*data), 0, qid, 1,
440 BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT);
442 nvmf_log_connect_error(ctrl, ret, le32_to_cpu(cqe.result),
448 EXPORT_SYMBOL_GPL(nvmf_connect_io_queue);
451 * nvmf_register_transport() - NVMe Fabrics Library registration function.
452 * @ops: Transport ops instance to be registered to the
453 * common fabrics library.
455 * API function that registers the type of specific transport fabric
456 * being implemented to the common NVMe fabrics library. Part of
457 * the overall init sequence of starting up a fabrics driver.
459 void nvmf_register_transport(struct nvmf_transport_ops *ops)
461 mutex_lock(&nvmf_transports_mutex);
462 list_add_tail(&ops->entry, &nvmf_transports);
463 mutex_unlock(&nvmf_transports_mutex);
465 EXPORT_SYMBOL_GPL(nvmf_register_transport);
468 * nvmf_unregister_transport() - NVMe Fabrics Library unregistration function.
469 * @ops: Transport ops instance to be unregistered from the
470 * common fabrics library.
472 * Fabrics API function that unregisters the type of specific transport
473 * fabric being implemented from the common NVMe fabrics library.
474 * Part of the overall exit sequence of unloading the implemented driver.
476 void nvmf_unregister_transport(struct nvmf_transport_ops *ops)
478 mutex_lock(&nvmf_transports_mutex);
479 list_del(&ops->entry);
480 mutex_unlock(&nvmf_transports_mutex);
482 EXPORT_SYMBOL_GPL(nvmf_unregister_transport);
484 static struct nvmf_transport_ops *nvmf_lookup_transport(
485 struct nvmf_ctrl_options *opts)
487 struct nvmf_transport_ops *ops;
489 lockdep_assert_held(&nvmf_transports_mutex);
491 list_for_each_entry(ops, &nvmf_transports, entry) {
492 if (strcmp(ops->name, opts->transport) == 0)
499 static const match_table_t opt_tokens = {
500 { NVMF_OPT_TRANSPORT, "transport=%s" },
501 { NVMF_OPT_TRADDR, "traddr=%s" },
502 { NVMF_OPT_TRSVCID, "trsvcid=%s" },
503 { NVMF_OPT_NQN, "nqn=%s" },
504 { NVMF_OPT_QUEUE_SIZE, "queue_size=%d" },
505 { NVMF_OPT_NR_IO_QUEUES, "nr_io_queues=%d" },
506 { NVMF_OPT_TL_RETRY_COUNT, "tl_retry_count=%d" },
507 { NVMF_OPT_RECONNECT_DELAY, "reconnect_delay=%d" },
508 { NVMF_OPT_KATO, "keep_alive_tmo=%d" },
509 { NVMF_OPT_HOSTNQN, "hostnqn=%s" },
510 { NVMF_OPT_ERR, NULL }
513 static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
516 substring_t args[MAX_OPT_ARGS];
517 char *options, *o, *p;
522 opts->queue_size = NVMF_DEF_QUEUE_SIZE;
523 opts->nr_io_queues = num_online_cpus();
524 opts->tl_retry_count = 2;
525 opts->reconnect_delay = NVMF_DEF_RECONNECT_DELAY;
527 options = o = kstrdup(buf, GFP_KERNEL);
531 while ((p = strsep(&o, ",\n")) != NULL) {
535 token = match_token(p, opt_tokens, args);
538 case NVMF_OPT_TRANSPORT:
539 p = match_strdup(args);
547 p = match_strdup(args);
553 nqnlen = strlen(opts->subsysnqn);
554 if (nqnlen >= NVMF_NQN_SIZE) {
555 pr_err("%s needs to be < %d bytes\n",
556 opts->subsysnqn, NVMF_NQN_SIZE);
560 opts->discovery_nqn =
561 !(strcmp(opts->subsysnqn,
562 NVME_DISC_SUBSYS_NAME));
563 if (opts->discovery_nqn)
564 opts->nr_io_queues = 0;
566 case NVMF_OPT_TRADDR:
567 p = match_strdup(args);
574 case NVMF_OPT_TRSVCID:
575 p = match_strdup(args);
582 case NVMF_OPT_QUEUE_SIZE:
583 if (match_int(args, &token)) {
587 if (token < NVMF_MIN_QUEUE_SIZE ||
588 token > NVMF_MAX_QUEUE_SIZE) {
589 pr_err("Invalid queue_size %d\n", token);
593 opts->queue_size = token;
595 case NVMF_OPT_NR_IO_QUEUES:
596 if (match_int(args, &token)) {
601 pr_err("Invalid number of IOQs %d\n", token);
605 opts->nr_io_queues = min_t(unsigned int,
606 num_online_cpus(), token);
608 case NVMF_OPT_TL_RETRY_COUNT:
609 if (match_int(args, &token)) {
614 pr_err("Invalid tl_retry_count %d\n", token);
618 opts->tl_retry_count = token;
621 if (match_int(args, &token)) {
626 if (opts->discovery_nqn) {
627 pr_err("Discovery controllers cannot accept keep_alive_tmo != 0\n");
633 pr_err("Invalid keep_alive_tmo %d\n", token);
636 } else if (token == 0) {
637 /* Allowed for debug */
638 pr_warn("keep_alive_tmo 0 won't execute keep alives!!!\n");
642 case NVMF_OPT_HOSTNQN:
644 pr_err("hostnqn already user-assigned: %s\n",
649 p = match_strdup(args);
655 if (nqnlen >= NVMF_NQN_SIZE) {
656 pr_err("%s needs to be < %d bytes\n",
661 opts->host = nvmf_host_add(p);
667 case NVMF_OPT_RECONNECT_DELAY:
668 if (match_int(args, &token)) {
673 pr_err("Invalid reconnect_delay %d\n", token);
677 opts->reconnect_delay = token;
680 pr_warn("unknown parameter or missing value '%s' in ctrl creation request\n",
688 kref_get(&nvmf_default_host->ref);
689 opts->host = nvmf_default_host;
693 if (!opts->discovery_nqn && !opts->kato)
694 opts->kato = NVME_DEFAULT_KATO;
699 static int nvmf_check_required_opts(struct nvmf_ctrl_options *opts,
700 unsigned int required_opts)
702 if ((opts->mask & required_opts) != required_opts) {
705 for (i = 0; i < ARRAY_SIZE(opt_tokens); i++) {
706 if ((opt_tokens[i].token & required_opts) &&
707 !(opt_tokens[i].token & opts->mask)) {
708 pr_warn("missing parameter '%s'\n",
709 opt_tokens[i].pattern);
719 static int nvmf_check_allowed_opts(struct nvmf_ctrl_options *opts,
720 unsigned int allowed_opts)
722 if (opts->mask & ~allowed_opts) {
725 for (i = 0; i < ARRAY_SIZE(opt_tokens); i++) {
726 if (opt_tokens[i].token & ~allowed_opts) {
727 pr_warn("invalid parameter '%s'\n",
728 opt_tokens[i].pattern);
738 void nvmf_free_options(struct nvmf_ctrl_options *opts)
740 nvmf_host_put(opts->host);
741 kfree(opts->transport);
743 kfree(opts->trsvcid);
744 kfree(opts->subsysnqn);
747 EXPORT_SYMBOL_GPL(nvmf_free_options);
749 #define NVMF_REQUIRED_OPTS (NVMF_OPT_TRANSPORT | NVMF_OPT_NQN)
750 #define NVMF_ALLOWED_OPTS (NVMF_OPT_QUEUE_SIZE | NVMF_OPT_NR_IO_QUEUES | \
751 NVMF_OPT_KATO | NVMF_OPT_HOSTNQN)
753 static struct nvme_ctrl *
754 nvmf_create_ctrl(struct device *dev, const char *buf, size_t count)
756 struct nvmf_ctrl_options *opts;
757 struct nvmf_transport_ops *ops;
758 struct nvme_ctrl *ctrl;
761 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
763 return ERR_PTR(-ENOMEM);
765 ret = nvmf_parse_options(opts, buf);
770 * Check the generic options first as we need a valid transport for
771 * the lookup below. Then clear the generic flags so that transport
772 * drivers don't have to care about them.
774 ret = nvmf_check_required_opts(opts, NVMF_REQUIRED_OPTS);
777 opts->mask &= ~NVMF_REQUIRED_OPTS;
779 mutex_lock(&nvmf_transports_mutex);
780 ops = nvmf_lookup_transport(opts);
782 pr_info("no handler found for transport %s.\n",
788 ret = nvmf_check_required_opts(opts, ops->required_opts);
791 ret = nvmf_check_allowed_opts(opts, NVMF_ALLOWED_OPTS |
792 ops->allowed_opts | ops->required_opts);
796 ctrl = ops->create_ctrl(dev, opts);
802 mutex_unlock(&nvmf_transports_mutex);
806 mutex_unlock(&nvmf_transports_mutex);
808 nvmf_host_put(opts->host);
813 static struct class *nvmf_class;
814 static struct device *nvmf_device;
815 static DEFINE_MUTEX(nvmf_dev_mutex);
817 static ssize_t nvmf_dev_write(struct file *file, const char __user *ubuf,
818 size_t count, loff_t *pos)
820 struct seq_file *seq_file = file->private_data;
821 struct nvme_ctrl *ctrl;
825 if (count > PAGE_SIZE)
828 buf = memdup_user_nul(ubuf, count);
832 mutex_lock(&nvmf_dev_mutex);
833 if (seq_file->private) {
838 ctrl = nvmf_create_ctrl(nvmf_device, buf, count);
844 seq_file->private = ctrl;
847 mutex_unlock(&nvmf_dev_mutex);
849 return ret ? ret : count;
852 static int nvmf_dev_show(struct seq_file *seq_file, void *private)
854 struct nvme_ctrl *ctrl;
857 mutex_lock(&nvmf_dev_mutex);
858 ctrl = seq_file->private;
864 seq_printf(seq_file, "instance=%d,cntlid=%d\n",
865 ctrl->instance, ctrl->cntlid);
868 mutex_unlock(&nvmf_dev_mutex);
872 static int nvmf_dev_open(struct inode *inode, struct file *file)
875 * The miscdevice code initializes file->private_data, but doesn't
876 * make use of it later.
878 file->private_data = NULL;
879 return single_open(file, nvmf_dev_show, NULL);
882 static int nvmf_dev_release(struct inode *inode, struct file *file)
884 struct seq_file *seq_file = file->private_data;
885 struct nvme_ctrl *ctrl = seq_file->private;
889 return single_release(inode, file);
892 static const struct file_operations nvmf_dev_fops = {
893 .owner = THIS_MODULE,
894 .write = nvmf_dev_write,
896 .open = nvmf_dev_open,
897 .release = nvmf_dev_release,
900 static struct miscdevice nvmf_misc = {
901 .minor = MISC_DYNAMIC_MINOR,
902 .name = "nvme-fabrics",
903 .fops = &nvmf_dev_fops,
906 static int __init nvmf_init(void)
910 nvmf_default_host = nvmf_host_default();
911 if (!nvmf_default_host)
914 nvmf_class = class_create(THIS_MODULE, "nvme-fabrics");
915 if (IS_ERR(nvmf_class)) {
916 pr_err("couldn't register class nvme-fabrics\n");
917 ret = PTR_ERR(nvmf_class);
922 device_create(nvmf_class, NULL, MKDEV(0, 0), NULL, "ctl");
923 if (IS_ERR(nvmf_device)) {
924 pr_err("couldn't create nvme-fabris device!\n");
925 ret = PTR_ERR(nvmf_device);
926 goto out_destroy_class;
929 ret = misc_register(&nvmf_misc);
931 pr_err("couldn't register misc device: %d\n", ret);
932 goto out_destroy_device;
938 device_destroy(nvmf_class, MKDEV(0, 0));
940 class_destroy(nvmf_class);
942 nvmf_host_put(nvmf_default_host);
946 static void __exit nvmf_exit(void)
948 misc_deregister(&nvmf_misc);
949 device_destroy(nvmf_class, MKDEV(0, 0));
950 class_destroy(nvmf_class);
951 nvmf_host_put(nvmf_default_host);
953 BUILD_BUG_ON(sizeof(struct nvmf_connect_command) != 64);
954 BUILD_BUG_ON(sizeof(struct nvmf_property_get_command) != 64);
955 BUILD_BUG_ON(sizeof(struct nvmf_property_set_command) != 64);
956 BUILD_BUG_ON(sizeof(struct nvmf_connect_data) != 1024);
959 MODULE_LICENSE("GPL v2");
961 module_init(nvmf_init);
962 module_exit(nvmf_exit);