Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * NVMe over Fabrics common host code.
0004  * Copyright (c) 2015-2016 HGST, a Western Digital Company.
0005  */
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007 #include <linux/init.h>
0008 #include <linux/miscdevice.h>
0009 #include <linux/module.h>
0010 #include <linux/mutex.h>
0011 #include <linux/parser.h>
0012 #include <linux/seq_file.h>
0013 #include "nvme.h"
0014 #include "fabrics.h"
0015 
0016 static LIST_HEAD(nvmf_transports);
0017 static DECLARE_RWSEM(nvmf_transports_rwsem);
0018 
0019 static LIST_HEAD(nvmf_hosts);
0020 static DEFINE_MUTEX(nvmf_hosts_mutex);
0021 
0022 static struct nvmf_host *nvmf_default_host;
0023 
0024 static struct nvmf_host *__nvmf_host_find(const char *hostnqn)
0025 {
0026     struct nvmf_host *host;
0027 
0028     list_for_each_entry(host, &nvmf_hosts, list) {
0029         if (!strcmp(host->nqn, hostnqn))
0030             return host;
0031     }
0032 
0033     return NULL;
0034 }
0035 
0036 static struct nvmf_host *nvmf_host_add(const char *hostnqn)
0037 {
0038     struct nvmf_host *host;
0039 
0040     mutex_lock(&nvmf_hosts_mutex);
0041     host = __nvmf_host_find(hostnqn);
0042     if (host) {
0043         kref_get(&host->ref);
0044         goto out_unlock;
0045     }
0046 
0047     host = kmalloc(sizeof(*host), GFP_KERNEL);
0048     if (!host)
0049         goto out_unlock;
0050 
0051     kref_init(&host->ref);
0052     strlcpy(host->nqn, hostnqn, NVMF_NQN_SIZE);
0053 
0054     list_add_tail(&host->list, &nvmf_hosts);
0055 out_unlock:
0056     mutex_unlock(&nvmf_hosts_mutex);
0057     return host;
0058 }
0059 
0060 static struct nvmf_host *nvmf_host_default(void)
0061 {
0062     struct nvmf_host *host;
0063 
0064     host = kmalloc(sizeof(*host), GFP_KERNEL);
0065     if (!host)
0066         return NULL;
0067 
0068     kref_init(&host->ref);
0069     uuid_gen(&host->id);
0070     snprintf(host->nqn, NVMF_NQN_SIZE,
0071         "nqn.2014-08.org.nvmexpress:uuid:%pUb", &host->id);
0072 
0073     mutex_lock(&nvmf_hosts_mutex);
0074     list_add_tail(&host->list, &nvmf_hosts);
0075     mutex_unlock(&nvmf_hosts_mutex);
0076 
0077     return host;
0078 }
0079 
0080 static void nvmf_host_destroy(struct kref *ref)
0081 {
0082     struct nvmf_host *host = container_of(ref, struct nvmf_host, ref);
0083 
0084     mutex_lock(&nvmf_hosts_mutex);
0085     list_del(&host->list);
0086     mutex_unlock(&nvmf_hosts_mutex);
0087 
0088     kfree(host);
0089 }
0090 
0091 static void nvmf_host_put(struct nvmf_host *host)
0092 {
0093     if (host)
0094         kref_put(&host->ref, nvmf_host_destroy);
0095 }
0096 
0097 /**
0098  * nvmf_get_address() -  Get address/port
0099  * @ctrl:   Host NVMe controller instance which we got the address
0100  * @buf:    OUTPUT parameter that will contain the address/port
0101  * @size:   buffer size
0102  */
0103 int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
0104 {
0105     int len = 0;
0106 
0107     if (ctrl->opts->mask & NVMF_OPT_TRADDR)
0108         len += scnprintf(buf, size, "traddr=%s", ctrl->opts->traddr);
0109     if (ctrl->opts->mask & NVMF_OPT_TRSVCID)
0110         len += scnprintf(buf + len, size - len, "%strsvcid=%s",
0111                 (len) ? "," : "", ctrl->opts->trsvcid);
0112     if (ctrl->opts->mask & NVMF_OPT_HOST_TRADDR)
0113         len += scnprintf(buf + len, size - len, "%shost_traddr=%s",
0114                 (len) ? "," : "", ctrl->opts->host_traddr);
0115     if (ctrl->opts->mask & NVMF_OPT_HOST_IFACE)
0116         len += scnprintf(buf + len, size - len, "%shost_iface=%s",
0117                 (len) ? "," : "", ctrl->opts->host_iface);
0118     len += scnprintf(buf + len, size - len, "\n");
0119 
0120     return len;
0121 }
0122 EXPORT_SYMBOL_GPL(nvmf_get_address);
0123 
0124 /**
0125  * nvmf_reg_read32() -  NVMe Fabrics "Property Get" API function.
0126  * @ctrl:   Host NVMe controller instance maintaining the admin
0127  *      queue used to submit the property read command to
0128  *      the allocated NVMe controller resource on the target system.
0129  * @off:    Starting offset value of the targeted property
0130  *      register (see the fabrics section of the NVMe standard).
0131  * @val:    OUTPUT parameter that will contain the value of
0132  *      the property after a successful read.
0133  *
0134  * Used by the host system to retrieve a 32-bit capsule property value
0135  * from an NVMe controller on the target system.
0136  *
0137  * ("Capsule property" is an "PCIe register concept" applied to the
0138  * NVMe fabrics space.)
0139  *
0140  * Return:
0141  *  0: successful read
0142  *  > 0: NVMe error status code
0143  *  < 0: Linux errno error code
0144  */
0145 int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
0146 {
0147     struct nvme_command cmd = { };
0148     union nvme_result res;
0149     int ret;
0150 
0151     cmd.prop_get.opcode = nvme_fabrics_command;
0152     cmd.prop_get.fctype = nvme_fabrics_type_property_get;
0153     cmd.prop_get.offset = cpu_to_le32(off);
0154 
0155     ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0,
0156             NVME_QID_ANY, 0, 0);
0157 
0158     if (ret >= 0)
0159         *val = le64_to_cpu(res.u64);
0160     if (unlikely(ret != 0))
0161         dev_err(ctrl->device,
0162             "Property Get error: %d, offset %#x\n",
0163             ret > 0 ? ret & ~NVME_SC_DNR : ret, off);
0164 
0165     return ret;
0166 }
0167 EXPORT_SYMBOL_GPL(nvmf_reg_read32);
0168 
0169 /**
0170  * nvmf_reg_read64() -  NVMe Fabrics "Property Get" API function.
0171  * @ctrl:   Host NVMe controller instance maintaining the admin
0172  *      queue used to submit the property read command to
0173  *      the allocated controller resource on the target system.
0174  * @off:    Starting offset value of the targeted property
0175  *      register (see the fabrics section of the NVMe standard).
0176  * @val:    OUTPUT parameter that will contain the value of
0177  *      the property after a successful read.
0178  *
0179  * Used by the host system to retrieve a 64-bit capsule property value
0180  * from an NVMe controller on the target system.
0181  *
0182  * ("Capsule property" is an "PCIe register concept" applied to the
0183  * NVMe fabrics space.)
0184  *
0185  * Return:
0186  *  0: successful read
0187  *  > 0: NVMe error status code
0188  *  < 0: Linux errno error code
0189  */
0190 int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
0191 {
0192     struct nvme_command cmd = { };
0193     union nvme_result res;
0194     int ret;
0195 
0196     cmd.prop_get.opcode = nvme_fabrics_command;
0197     cmd.prop_get.fctype = nvme_fabrics_type_property_get;
0198     cmd.prop_get.attrib = 1;
0199     cmd.prop_get.offset = cpu_to_le32(off);
0200 
0201     ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0,
0202             NVME_QID_ANY, 0, 0);
0203 
0204     if (ret >= 0)
0205         *val = le64_to_cpu(res.u64);
0206     if (unlikely(ret != 0))
0207         dev_err(ctrl->device,
0208             "Property Get error: %d, offset %#x\n",
0209             ret > 0 ? ret & ~NVME_SC_DNR : ret, off);
0210     return ret;
0211 }
0212 EXPORT_SYMBOL_GPL(nvmf_reg_read64);
0213 
0214 /**
0215  * nvmf_reg_write32() -  NVMe Fabrics "Property Write" API function.
0216  * @ctrl:   Host NVMe controller instance maintaining the admin
0217  *      queue used to submit the property read command to
0218  *      the allocated NVMe controller resource on the target system.
0219  * @off:    Starting offset value of the targeted property
0220  *      register (see the fabrics section of the NVMe standard).
0221  * @val:    Input parameter that contains the value to be
0222  *      written to the property.
0223  *
0224  * Used by the NVMe host system to write a 32-bit capsule property value
0225  * to an NVMe controller on the target system.
0226  *
0227  * ("Capsule property" is an "PCIe register concept" applied to the
0228  * NVMe fabrics space.)
0229  *
0230  * Return:
0231  *  0: successful write
0232  *  > 0: NVMe error status code
0233  *  < 0: Linux errno error code
0234  */
0235 int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
0236 {
0237     struct nvme_command cmd = { };
0238     int ret;
0239 
0240     cmd.prop_set.opcode = nvme_fabrics_command;
0241     cmd.prop_set.fctype = nvme_fabrics_type_property_set;
0242     cmd.prop_set.attrib = 0;
0243     cmd.prop_set.offset = cpu_to_le32(off);
0244     cmd.prop_set.value = cpu_to_le64(val);
0245 
0246     ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0,
0247             NVME_QID_ANY, 0, 0);
0248     if (unlikely(ret))
0249         dev_err(ctrl->device,
0250             "Property Set error: %d, offset %#x\n",
0251             ret > 0 ? ret & ~NVME_SC_DNR : ret, off);
0252     return ret;
0253 }
0254 EXPORT_SYMBOL_GPL(nvmf_reg_write32);
0255 
0256 /**
0257  * nvmf_log_connect_error() - Error-parsing-diagnostic print out function for
0258  *              connect() errors.
0259  * @ctrl:   The specific /dev/nvmeX device that had the error.
0260  * @errval: Error code to be decoded in a more human-friendly
0261  *      printout.
0262  * @offset: For use with the NVMe error code
0263  *      NVME_SC_CONNECT_INVALID_PARAM.
0264  * @cmd:    This is the SQE portion of a submission capsule.
0265  * @data:   This is the "Data" portion of a submission capsule.
0266  */
0267 static void nvmf_log_connect_error(struct nvme_ctrl *ctrl,
0268         int errval, int offset, struct nvme_command *cmd,
0269         struct nvmf_connect_data *data)
0270 {
0271     int err_sctype = errval & ~NVME_SC_DNR;
0272 
0273     if (errval < 0) {
0274         dev_err(ctrl->device,
0275             "Connect command failed, errno: %d\n", errval);
0276         return;
0277     }
0278 
0279     switch (err_sctype) {
0280     case NVME_SC_CONNECT_INVALID_PARAM:
0281         if (offset >> 16) {
0282             char *inv_data = "Connect Invalid Data Parameter";
0283 
0284             switch (offset & 0xffff) {
0285             case (offsetof(struct nvmf_connect_data, cntlid)):
0286                 dev_err(ctrl->device,
0287                     "%s, cntlid: %d\n",
0288                     inv_data, data->cntlid);
0289                 break;
0290             case (offsetof(struct nvmf_connect_data, hostnqn)):
0291                 dev_err(ctrl->device,
0292                     "%s, hostnqn \"%s\"\n",
0293                     inv_data, data->hostnqn);
0294                 break;
0295             case (offsetof(struct nvmf_connect_data, subsysnqn)):
0296                 dev_err(ctrl->device,
0297                     "%s, subsysnqn \"%s\"\n",
0298                     inv_data, data->subsysnqn);
0299                 break;
0300             default:
0301                 dev_err(ctrl->device,
0302                     "%s, starting byte offset: %d\n",
0303                        inv_data, offset & 0xffff);
0304                 break;
0305             }
0306         } else {
0307             char *inv_sqe = "Connect Invalid SQE Parameter";
0308 
0309             switch (offset) {
0310             case (offsetof(struct nvmf_connect_command, qid)):
0311                 dev_err(ctrl->device,
0312                        "%s, qid %d\n",
0313                     inv_sqe, cmd->connect.qid);
0314                 break;
0315             default:
0316                 dev_err(ctrl->device,
0317                     "%s, starting byte offset: %d\n",
0318                     inv_sqe, offset);
0319             }
0320         }
0321         break;
0322     case NVME_SC_CONNECT_INVALID_HOST:
0323         dev_err(ctrl->device,
0324             "Connect for subsystem %s is not allowed, hostnqn: %s\n",
0325             data->subsysnqn, data->hostnqn);
0326         break;
0327     case NVME_SC_CONNECT_CTRL_BUSY:
0328         dev_err(ctrl->device,
0329             "Connect command failed: controller is busy or not available\n");
0330         break;
0331     case NVME_SC_CONNECT_FORMAT:
0332         dev_err(ctrl->device,
0333             "Connect incompatible format: %d",
0334             cmd->connect.recfmt);
0335         break;
0336     case NVME_SC_HOST_PATH_ERROR:
0337         dev_err(ctrl->device,
0338             "Connect command failed: host path error\n");
0339         break;
0340     case NVME_SC_AUTH_REQUIRED:
0341         dev_err(ctrl->device,
0342             "Connect command failed: authentication required\n");
0343         break;
0344     default:
0345         dev_err(ctrl->device,
0346             "Connect command failed, error wo/DNR bit: %d\n",
0347             err_sctype);
0348         break;
0349     }
0350 }
0351 
0352 /**
0353  * nvmf_connect_admin_queue() - NVMe Fabrics Admin Queue "Connect"
0354  *              API function.
0355  * @ctrl:   Host nvme controller instance used to request
0356  *              a new NVMe controller allocation on the target
0357  *              system and  establish an NVMe Admin connection to
0358  *              that controller.
0359  *
0360  * This function enables an NVMe host device to request a new allocation of
0361  * an NVMe controller resource on a target system as well establish a
0362  * fabrics-protocol connection of the NVMe Admin queue between the
0363  * host system device and the allocated NVMe controller on the
0364  * target system via a NVMe Fabrics "Connect" command.
0365  *
0366  * Return:
0367  *  0: success
0368  *  > 0: NVMe error status code
0369  *  < 0: Linux errno error code
0370  *
0371  */
0372 int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl)
0373 {
0374     struct nvme_command cmd = { };
0375     union nvme_result res;
0376     struct nvmf_connect_data *data;
0377     int ret;
0378     u32 result;
0379 
0380     cmd.connect.opcode = nvme_fabrics_command;
0381     cmd.connect.fctype = nvme_fabrics_type_connect;
0382     cmd.connect.qid = 0;
0383     cmd.connect.sqsize = cpu_to_le16(NVME_AQ_DEPTH - 1);
0384 
0385     /*
0386      * Set keep-alive timeout in seconds granularity (ms * 1000)
0387      */
0388     cmd.connect.kato = cpu_to_le32(ctrl->kato * 1000);
0389 
0390     if (ctrl->opts->disable_sqflow)
0391         cmd.connect.cattr |= NVME_CONNECT_DISABLE_SQFLOW;
0392 
0393     data = kzalloc(sizeof(*data), GFP_KERNEL);
0394     if (!data)
0395         return -ENOMEM;
0396 
0397     uuid_copy(&data->hostid, &ctrl->opts->host->id);
0398     data->cntlid = cpu_to_le16(0xffff);
0399     strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
0400     strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);
0401 
0402     ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res,
0403             data, sizeof(*data), NVME_QID_ANY, 1,
0404             BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT);
0405     if (ret) {
0406         nvmf_log_connect_error(ctrl, ret, le32_to_cpu(res.u32),
0407                        &cmd, data);
0408         goto out_free_data;
0409     }
0410 
0411     result = le32_to_cpu(res.u32);
0412     ctrl->cntlid = result & 0xFFFF;
0413     if ((result >> 16) & 0x3) {
0414         /* Authentication required */
0415         ret = nvme_auth_negotiate(ctrl, 0);
0416         if (ret) {
0417             dev_warn(ctrl->device,
0418                  "qid 0: authentication setup failed\n");
0419             ret = NVME_SC_AUTH_REQUIRED;
0420             goto out_free_data;
0421         }
0422         ret = nvme_auth_wait(ctrl, 0);
0423         if (ret)
0424             dev_warn(ctrl->device,
0425                  "qid 0: authentication failed\n");
0426         else
0427             dev_info(ctrl->device,
0428                  "qid 0: authenticated\n");
0429     }
0430 out_free_data:
0431     kfree(data);
0432     return ret;
0433 }
0434 EXPORT_SYMBOL_GPL(nvmf_connect_admin_queue);
0435 
0436 /**
0437  * nvmf_connect_io_queue() - NVMe Fabrics I/O Queue "Connect"
0438  *               API function.
0439  * @ctrl:   Host nvme controller instance used to establish an
0440  *      NVMe I/O queue connection to the already allocated NVMe
0441  *      controller on the target system.
0442  * @qid:    NVMe I/O queue number for the new I/O connection between
0443  *      host and target (note qid == 0 is illegal as this is
0444  *      the Admin queue, per NVMe standard).
0445  *
0446  * This function issues a fabrics-protocol connection
0447  * of a NVMe I/O queue (via NVMe Fabrics "Connect" command)
0448  * between the host system device and the allocated NVMe controller
0449  * on the target system.
0450  *
0451  * Return:
0452  *  0: success
0453  *  > 0: NVMe error status code
0454  *  < 0: Linux errno error code
0455  */
0456 int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid)
0457 {
0458     struct nvme_command cmd = { };
0459     struct nvmf_connect_data *data;
0460     union nvme_result res;
0461     int ret;
0462     u32 result;
0463 
0464     cmd.connect.opcode = nvme_fabrics_command;
0465     cmd.connect.fctype = nvme_fabrics_type_connect;
0466     cmd.connect.qid = cpu_to_le16(qid);
0467     cmd.connect.sqsize = cpu_to_le16(ctrl->sqsize);
0468 
0469     if (ctrl->opts->disable_sqflow)
0470         cmd.connect.cattr |= NVME_CONNECT_DISABLE_SQFLOW;
0471 
0472     data = kzalloc(sizeof(*data), GFP_KERNEL);
0473     if (!data)
0474         return -ENOMEM;
0475 
0476     uuid_copy(&data->hostid, &ctrl->opts->host->id);
0477     data->cntlid = cpu_to_le16(ctrl->cntlid);
0478     strncpy(data->subsysnqn, ctrl->opts->subsysnqn, NVMF_NQN_SIZE);
0479     strncpy(data->hostnqn, ctrl->opts->host->nqn, NVMF_NQN_SIZE);
0480 
0481     ret = __nvme_submit_sync_cmd(ctrl->connect_q, &cmd, &res,
0482             data, sizeof(*data), qid, 1,
0483             BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT);
0484     if (ret) {
0485         nvmf_log_connect_error(ctrl, ret, le32_to_cpu(res.u32),
0486                        &cmd, data);
0487     }
0488     result = le32_to_cpu(res.u32);
0489     if ((result >> 16) & 2) {
0490         /* Authentication required */
0491         ret = nvme_auth_negotiate(ctrl, qid);
0492         if (ret) {
0493             dev_warn(ctrl->device,
0494                  "qid %d: authentication setup failed\n", qid);
0495             ret = NVME_SC_AUTH_REQUIRED;
0496         } else {
0497             ret = nvme_auth_wait(ctrl, qid);
0498             if (ret)
0499                 dev_warn(ctrl->device,
0500                      "qid %u: authentication failed\n", qid);
0501         }
0502     }
0503     kfree(data);
0504     return ret;
0505 }
0506 EXPORT_SYMBOL_GPL(nvmf_connect_io_queue);
0507 
0508 bool nvmf_should_reconnect(struct nvme_ctrl *ctrl)
0509 {
0510     if (ctrl->opts->max_reconnects == -1 ||
0511         ctrl->nr_reconnects < ctrl->opts->max_reconnects)
0512         return true;
0513 
0514     return false;
0515 }
0516 EXPORT_SYMBOL_GPL(nvmf_should_reconnect);
0517 
0518 /**
0519  * nvmf_register_transport() - NVMe Fabrics Library registration function.
0520  * @ops:    Transport ops instance to be registered to the
0521  *      common fabrics library.
0522  *
0523  * API function that registers the type of specific transport fabric
0524  * being implemented to the common NVMe fabrics library. Part of
0525  * the overall init sequence of starting up a fabrics driver.
0526  */
0527 int nvmf_register_transport(struct nvmf_transport_ops *ops)
0528 {
0529     if (!ops->create_ctrl)
0530         return -EINVAL;
0531 
0532     down_write(&nvmf_transports_rwsem);
0533     list_add_tail(&ops->entry, &nvmf_transports);
0534     up_write(&nvmf_transports_rwsem);
0535 
0536     return 0;
0537 }
0538 EXPORT_SYMBOL_GPL(nvmf_register_transport);
0539 
0540 /**
0541  * nvmf_unregister_transport() - NVMe Fabrics Library unregistration function.
0542  * @ops:    Transport ops instance to be unregistered from the
0543  *      common fabrics library.
0544  *
0545  * Fabrics API function that unregisters the type of specific transport
0546  * fabric being implemented from the common NVMe fabrics library.
0547  * Part of the overall exit sequence of unloading the implemented driver.
0548  */
0549 void nvmf_unregister_transport(struct nvmf_transport_ops *ops)
0550 {
0551     down_write(&nvmf_transports_rwsem);
0552     list_del(&ops->entry);
0553     up_write(&nvmf_transports_rwsem);
0554 }
0555 EXPORT_SYMBOL_GPL(nvmf_unregister_transport);
0556 
0557 static struct nvmf_transport_ops *nvmf_lookup_transport(
0558         struct nvmf_ctrl_options *opts)
0559 {
0560     struct nvmf_transport_ops *ops;
0561 
0562     lockdep_assert_held(&nvmf_transports_rwsem);
0563 
0564     list_for_each_entry(ops, &nvmf_transports, entry) {
0565         if (strcmp(ops->name, opts->transport) == 0)
0566             return ops;
0567     }
0568 
0569     return NULL;
0570 }
0571 
0572 static const match_table_t opt_tokens = {
0573     { NVMF_OPT_TRANSPORT,       "transport=%s"      },
0574     { NVMF_OPT_TRADDR,      "traddr=%s"     },
0575     { NVMF_OPT_TRSVCID,     "trsvcid=%s"        },
0576     { NVMF_OPT_NQN,         "nqn=%s"        },
0577     { NVMF_OPT_QUEUE_SIZE,      "queue_size=%d"     },
0578     { NVMF_OPT_NR_IO_QUEUES,    "nr_io_queues=%d"   },
0579     { NVMF_OPT_RECONNECT_DELAY, "reconnect_delay=%d"    },
0580     { NVMF_OPT_CTRL_LOSS_TMO,   "ctrl_loss_tmo=%d"  },
0581     { NVMF_OPT_KATO,        "keep_alive_tmo=%d" },
0582     { NVMF_OPT_HOSTNQN,     "hostnqn=%s"        },
0583     { NVMF_OPT_HOST_TRADDR,     "host_traddr=%s"    },
0584     { NVMF_OPT_HOST_IFACE,      "host_iface=%s"     },
0585     { NVMF_OPT_HOST_ID,     "hostid=%s"     },
0586     { NVMF_OPT_DUP_CONNECT,     "duplicate_connect" },
0587     { NVMF_OPT_DISABLE_SQFLOW,  "disable_sqflow"    },
0588     { NVMF_OPT_HDR_DIGEST,      "hdr_digest"        },
0589     { NVMF_OPT_DATA_DIGEST,     "data_digest"       },
0590     { NVMF_OPT_NR_WRITE_QUEUES, "nr_write_queues=%d"    },
0591     { NVMF_OPT_NR_POLL_QUEUES,  "nr_poll_queues=%d" },
0592     { NVMF_OPT_TOS,         "tos=%d"        },
0593     { NVMF_OPT_FAIL_FAST_TMO,   "fast_io_fail_tmo=%d"   },
0594     { NVMF_OPT_DISCOVERY,       "discovery"     },
0595     { NVMF_OPT_DHCHAP_SECRET,   "dhchap_secret=%s"  },
0596     { NVMF_OPT_DHCHAP_CTRL_SECRET,  "dhchap_ctrl_secret=%s" },
0597     { NVMF_OPT_ERR,         NULL            }
0598 };
0599 
0600 static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
0601         const char *buf)
0602 {
0603     substring_t args[MAX_OPT_ARGS];
0604     char *options, *o, *p;
0605     int token, ret = 0;
0606     size_t nqnlen  = 0;
0607     int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO;
0608     uuid_t hostid;
0609 
0610     /* Set defaults */
0611     opts->queue_size = NVMF_DEF_QUEUE_SIZE;
0612     opts->nr_io_queues = num_online_cpus();
0613     opts->reconnect_delay = NVMF_DEF_RECONNECT_DELAY;
0614     opts->kato = 0;
0615     opts->duplicate_connect = false;
0616     opts->fast_io_fail_tmo = NVMF_DEF_FAIL_FAST_TMO;
0617     opts->hdr_digest = false;
0618     opts->data_digest = false;
0619     opts->tos = -1; /* < 0 == use transport default */
0620 
0621     options = o = kstrdup(buf, GFP_KERNEL);
0622     if (!options)
0623         return -ENOMEM;
0624 
0625     uuid_gen(&hostid);
0626 
0627     while ((p = strsep(&o, ",\n")) != NULL) {
0628         if (!*p)
0629             continue;
0630 
0631         token = match_token(p, opt_tokens, args);
0632         opts->mask |= token;
0633         switch (token) {
0634         case NVMF_OPT_TRANSPORT:
0635             p = match_strdup(args);
0636             if (!p) {
0637                 ret = -ENOMEM;
0638                 goto out;
0639             }
0640             kfree(opts->transport);
0641             opts->transport = p;
0642             break;
0643         case NVMF_OPT_NQN:
0644             p = match_strdup(args);
0645             if (!p) {
0646                 ret = -ENOMEM;
0647                 goto out;
0648             }
0649             kfree(opts->subsysnqn);
0650             opts->subsysnqn = p;
0651             nqnlen = strlen(opts->subsysnqn);
0652             if (nqnlen >= NVMF_NQN_SIZE) {
0653                 pr_err("%s needs to be < %d bytes\n",
0654                     opts->subsysnqn, NVMF_NQN_SIZE);
0655                 ret = -EINVAL;
0656                 goto out;
0657             }
0658             opts->discovery_nqn =
0659                 !(strcmp(opts->subsysnqn,
0660                      NVME_DISC_SUBSYS_NAME));
0661             break;
0662         case NVMF_OPT_TRADDR:
0663             p = match_strdup(args);
0664             if (!p) {
0665                 ret = -ENOMEM;
0666                 goto out;
0667             }
0668             kfree(opts->traddr);
0669             opts->traddr = p;
0670             break;
0671         case NVMF_OPT_TRSVCID:
0672             p = match_strdup(args);
0673             if (!p) {
0674                 ret = -ENOMEM;
0675                 goto out;
0676             }
0677             kfree(opts->trsvcid);
0678             opts->trsvcid = p;
0679             break;
0680         case NVMF_OPT_QUEUE_SIZE:
0681             if (match_int(args, &token)) {
0682                 ret = -EINVAL;
0683                 goto out;
0684             }
0685             if (token < NVMF_MIN_QUEUE_SIZE ||
0686                 token > NVMF_MAX_QUEUE_SIZE) {
0687                 pr_err("Invalid queue_size %d\n", token);
0688                 ret = -EINVAL;
0689                 goto out;
0690             }
0691             opts->queue_size = token;
0692             break;
0693         case NVMF_OPT_NR_IO_QUEUES:
0694             if (match_int(args, &token)) {
0695                 ret = -EINVAL;
0696                 goto out;
0697             }
0698             if (token <= 0) {
0699                 pr_err("Invalid number of IOQs %d\n", token);
0700                 ret = -EINVAL;
0701                 goto out;
0702             }
0703             if (opts->discovery_nqn) {
0704                 pr_debug("Ignoring nr_io_queues value for discovery controller\n");
0705                 break;
0706             }
0707 
0708             opts->nr_io_queues = min_t(unsigned int,
0709                     num_online_cpus(), token);
0710             break;
0711         case NVMF_OPT_KATO:
0712             if (match_int(args, &token)) {
0713                 ret = -EINVAL;
0714                 goto out;
0715             }
0716 
0717             if (token < 0) {
0718                 pr_err("Invalid keep_alive_tmo %d\n", token);
0719                 ret = -EINVAL;
0720                 goto out;
0721             } else if (token == 0 && !opts->discovery_nqn) {
0722                 /* Allowed for debug */
0723                 pr_warn("keep_alive_tmo 0 won't execute keep alives!!!\n");
0724             }
0725             opts->kato = token;
0726             break;
0727         case NVMF_OPT_CTRL_LOSS_TMO:
0728             if (match_int(args, &token)) {
0729                 ret = -EINVAL;
0730                 goto out;
0731             }
0732 
0733             if (token < 0)
0734                 pr_warn("ctrl_loss_tmo < 0 will reconnect forever\n");
0735             ctrl_loss_tmo = token;
0736             break;
0737         case NVMF_OPT_FAIL_FAST_TMO:
0738             if (match_int(args, &token)) {
0739                 ret = -EINVAL;
0740                 goto out;
0741             }
0742 
0743             if (token >= 0)
0744                 pr_warn("I/O fail on reconnect controller after %d sec\n",
0745                     token);
0746             else
0747                 token = -1;
0748 
0749             opts->fast_io_fail_tmo = token;
0750             break;
0751         case NVMF_OPT_HOSTNQN:
0752             if (opts->host) {
0753                 pr_err("hostnqn already user-assigned: %s\n",
0754                        opts->host->nqn);
0755                 ret = -EADDRINUSE;
0756                 goto out;
0757             }
0758             p = match_strdup(args);
0759             if (!p) {
0760                 ret = -ENOMEM;
0761                 goto out;
0762             }
0763             nqnlen = strlen(p);
0764             if (nqnlen >= NVMF_NQN_SIZE) {
0765                 pr_err("%s needs to be < %d bytes\n",
0766                     p, NVMF_NQN_SIZE);
0767                 kfree(p);
0768                 ret = -EINVAL;
0769                 goto out;
0770             }
0771             opts->host = nvmf_host_add(p);
0772             kfree(p);
0773             if (!opts->host) {
0774                 ret = -ENOMEM;
0775                 goto out;
0776             }
0777             break;
0778         case NVMF_OPT_RECONNECT_DELAY:
0779             if (match_int(args, &token)) {
0780                 ret = -EINVAL;
0781                 goto out;
0782             }
0783             if (token <= 0) {
0784                 pr_err("Invalid reconnect_delay %d\n", token);
0785                 ret = -EINVAL;
0786                 goto out;
0787             }
0788             opts->reconnect_delay = token;
0789             break;
0790         case NVMF_OPT_HOST_TRADDR:
0791             p = match_strdup(args);
0792             if (!p) {
0793                 ret = -ENOMEM;
0794                 goto out;
0795             }
0796             kfree(opts->host_traddr);
0797             opts->host_traddr = p;
0798             break;
0799         case NVMF_OPT_HOST_IFACE:
0800             p = match_strdup(args);
0801             if (!p) {
0802                 ret = -ENOMEM;
0803                 goto out;
0804             }
0805             kfree(opts->host_iface);
0806             opts->host_iface = p;
0807             break;
0808         case NVMF_OPT_HOST_ID:
0809             p = match_strdup(args);
0810             if (!p) {
0811                 ret = -ENOMEM;
0812                 goto out;
0813             }
0814             ret = uuid_parse(p, &hostid);
0815             if (ret) {
0816                 pr_err("Invalid hostid %s\n", p);
0817                 ret = -EINVAL;
0818                 kfree(p);
0819                 goto out;
0820             }
0821             kfree(p);
0822             break;
0823         case NVMF_OPT_DUP_CONNECT:
0824             opts->duplicate_connect = true;
0825             break;
0826         case NVMF_OPT_DISABLE_SQFLOW:
0827             opts->disable_sqflow = true;
0828             break;
0829         case NVMF_OPT_HDR_DIGEST:
0830             opts->hdr_digest = true;
0831             break;
0832         case NVMF_OPT_DATA_DIGEST:
0833             opts->data_digest = true;
0834             break;
0835         case NVMF_OPT_NR_WRITE_QUEUES:
0836             if (match_int(args, &token)) {
0837                 ret = -EINVAL;
0838                 goto out;
0839             }
0840             if (token <= 0) {
0841                 pr_err("Invalid nr_write_queues %d\n", token);
0842                 ret = -EINVAL;
0843                 goto out;
0844             }
0845             opts->nr_write_queues = token;
0846             break;
0847         case NVMF_OPT_NR_POLL_QUEUES:
0848             if (match_int(args, &token)) {
0849                 ret = -EINVAL;
0850                 goto out;
0851             }
0852             if (token <= 0) {
0853                 pr_err("Invalid nr_poll_queues %d\n", token);
0854                 ret = -EINVAL;
0855                 goto out;
0856             }
0857             opts->nr_poll_queues = token;
0858             break;
0859         case NVMF_OPT_TOS:
0860             if (match_int(args, &token)) {
0861                 ret = -EINVAL;
0862                 goto out;
0863             }
0864             if (token < 0) {
0865                 pr_err("Invalid type of service %d\n", token);
0866                 ret = -EINVAL;
0867                 goto out;
0868             }
0869             if (token > 255) {
0870                 pr_warn("Clamping type of service to 255\n");
0871                 token = 255;
0872             }
0873             opts->tos = token;
0874             break;
0875         case NVMF_OPT_DISCOVERY:
0876             opts->discovery_nqn = true;
0877             break;
0878         case NVMF_OPT_DHCHAP_SECRET:
0879             p = match_strdup(args);
0880             if (!p) {
0881                 ret = -ENOMEM;
0882                 goto out;
0883             }
0884             if (strlen(p) < 11 || strncmp(p, "DHHC-1:", 7)) {
0885                 pr_err("Invalid DH-CHAP secret %s\n", p);
0886                 ret = -EINVAL;
0887                 goto out;
0888             }
0889             kfree(opts->dhchap_secret);
0890             opts->dhchap_secret = p;
0891             break;
0892         case NVMF_OPT_DHCHAP_CTRL_SECRET:
0893             p = match_strdup(args);
0894             if (!p) {
0895                 ret = -ENOMEM;
0896                 goto out;
0897             }
0898             if (strlen(p) < 11 || strncmp(p, "DHHC-1:", 7)) {
0899                 pr_err("Invalid DH-CHAP secret %s\n", p);
0900                 ret = -EINVAL;
0901                 goto out;
0902             }
0903             kfree(opts->dhchap_ctrl_secret);
0904             opts->dhchap_ctrl_secret = p;
0905             break;
0906         default:
0907             pr_warn("unknown parameter or missing value '%s' in ctrl creation request\n",
0908                 p);
0909             ret = -EINVAL;
0910             goto out;
0911         }
0912     }
0913 
0914     if (opts->discovery_nqn) {
0915         opts->nr_io_queues = 0;
0916         opts->nr_write_queues = 0;
0917         opts->nr_poll_queues = 0;
0918         opts->duplicate_connect = true;
0919     } else {
0920         if (!opts->kato)
0921             opts->kato = NVME_DEFAULT_KATO;
0922     }
0923     if (ctrl_loss_tmo < 0) {
0924         opts->max_reconnects = -1;
0925     } else {
0926         opts->max_reconnects = DIV_ROUND_UP(ctrl_loss_tmo,
0927                         opts->reconnect_delay);
0928         if (ctrl_loss_tmo < opts->fast_io_fail_tmo)
0929             pr_warn("failfast tmo (%d) larger than controller loss tmo (%d)\n",
0930                 opts->fast_io_fail_tmo, ctrl_loss_tmo);
0931     }
0932 
0933     if (!opts->host) {
0934         kref_get(&nvmf_default_host->ref);
0935         opts->host = nvmf_default_host;
0936     }
0937 
0938     uuid_copy(&opts->host->id, &hostid);
0939 
0940 out:
0941     kfree(options);
0942     return ret;
0943 }
0944 
0945 static int nvmf_check_required_opts(struct nvmf_ctrl_options *opts,
0946         unsigned int required_opts)
0947 {
0948     if ((opts->mask & required_opts) != required_opts) {
0949         unsigned int i;
0950 
0951         for (i = 0; i < ARRAY_SIZE(opt_tokens); i++) {
0952             if ((opt_tokens[i].token & required_opts) &&
0953                 !(opt_tokens[i].token & opts->mask)) {
0954                 pr_warn("missing parameter '%s'\n",
0955                     opt_tokens[i].pattern);
0956             }
0957         }
0958 
0959         return -EINVAL;
0960     }
0961 
0962     return 0;
0963 }
0964 
0965 bool nvmf_ip_options_match(struct nvme_ctrl *ctrl,
0966         struct nvmf_ctrl_options *opts)
0967 {
0968     if (!nvmf_ctlr_matches_baseopts(ctrl, opts) ||
0969         strcmp(opts->traddr, ctrl->opts->traddr) ||
0970         strcmp(opts->trsvcid, ctrl->opts->trsvcid))
0971         return false;
0972 
0973     /*
0974      * Checking the local address is rough. In most cases, none is specified
0975      * and the host port is selected by the stack.
0976      *
0977      * Assume no match if:
0978      * -  local address is specified and address is not the same
0979      * -  local address is not specified but remote is, or vice versa
0980      *    (admin using specific host_traddr when it matters).
0981      */
0982     if ((opts->mask & NVMF_OPT_HOST_TRADDR) &&
0983         (ctrl->opts->mask & NVMF_OPT_HOST_TRADDR)) {
0984         if (strcmp(opts->host_traddr, ctrl->opts->host_traddr))
0985             return false;
0986     } else if ((opts->mask & NVMF_OPT_HOST_TRADDR) ||
0987            (ctrl->opts->mask & NVMF_OPT_HOST_TRADDR)) {
0988         return false;
0989     }
0990 
0991     return true;
0992 }
0993 EXPORT_SYMBOL_GPL(nvmf_ip_options_match);
0994 
0995 static int nvmf_check_allowed_opts(struct nvmf_ctrl_options *opts,
0996         unsigned int allowed_opts)
0997 {
0998     if (opts->mask & ~allowed_opts) {
0999         unsigned int i;
1000 
1001         for (i = 0; i < ARRAY_SIZE(opt_tokens); i++) {
1002             if ((opt_tokens[i].token & opts->mask) &&
1003                 (opt_tokens[i].token & ~allowed_opts)) {
1004                 pr_warn("invalid parameter '%s'\n",
1005                     opt_tokens[i].pattern);
1006             }
1007         }
1008 
1009         return -EINVAL;
1010     }
1011 
1012     return 0;
1013 }
1014 
1015 void nvmf_free_options(struct nvmf_ctrl_options *opts)
1016 {
1017     nvmf_host_put(opts->host);
1018     kfree(opts->transport);
1019     kfree(opts->traddr);
1020     kfree(opts->trsvcid);
1021     kfree(opts->subsysnqn);
1022     kfree(opts->host_traddr);
1023     kfree(opts->host_iface);
1024     kfree(opts->dhchap_secret);
1025     kfree(opts->dhchap_ctrl_secret);
1026     kfree(opts);
1027 }
1028 EXPORT_SYMBOL_GPL(nvmf_free_options);
1029 
1030 #define NVMF_REQUIRED_OPTS  (NVMF_OPT_TRANSPORT | NVMF_OPT_NQN)
1031 #define NVMF_ALLOWED_OPTS   (NVMF_OPT_QUEUE_SIZE | NVMF_OPT_NR_IO_QUEUES | \
1032                  NVMF_OPT_KATO | NVMF_OPT_HOSTNQN | \
1033                  NVMF_OPT_HOST_ID | NVMF_OPT_DUP_CONNECT |\
1034                  NVMF_OPT_DISABLE_SQFLOW | NVMF_OPT_DISCOVERY |\
1035                  NVMF_OPT_FAIL_FAST_TMO | NVMF_OPT_DHCHAP_SECRET |\
1036                  NVMF_OPT_DHCHAP_CTRL_SECRET)
1037 
1038 static struct nvme_ctrl *
1039 nvmf_create_ctrl(struct device *dev, const char *buf)
1040 {
1041     struct nvmf_ctrl_options *opts;
1042     struct nvmf_transport_ops *ops;
1043     struct nvme_ctrl *ctrl;
1044     int ret;
1045 
1046     opts = kzalloc(sizeof(*opts), GFP_KERNEL);
1047     if (!opts)
1048         return ERR_PTR(-ENOMEM);
1049 
1050     ret = nvmf_parse_options(opts, buf);
1051     if (ret)
1052         goto out_free_opts;
1053 
1054 
1055     request_module("nvme-%s", opts->transport);
1056 
1057     /*
1058      * Check the generic options first as we need a valid transport for
1059      * the lookup below.  Then clear the generic flags so that transport
1060      * drivers don't have to care about them.
1061      */
1062     ret = nvmf_check_required_opts(opts, NVMF_REQUIRED_OPTS);
1063     if (ret)
1064         goto out_free_opts;
1065     opts->mask &= ~NVMF_REQUIRED_OPTS;
1066 
1067     down_read(&nvmf_transports_rwsem);
1068     ops = nvmf_lookup_transport(opts);
1069     if (!ops) {
1070         pr_info("no handler found for transport %s.\n",
1071             opts->transport);
1072         ret = -EINVAL;
1073         goto out_unlock;
1074     }
1075 
1076     if (!try_module_get(ops->module)) {
1077         ret = -EBUSY;
1078         goto out_unlock;
1079     }
1080     up_read(&nvmf_transports_rwsem);
1081 
1082     ret = nvmf_check_required_opts(opts, ops->required_opts);
1083     if (ret)
1084         goto out_module_put;
1085     ret = nvmf_check_allowed_opts(opts, NVMF_ALLOWED_OPTS |
1086                 ops->allowed_opts | ops->required_opts);
1087     if (ret)
1088         goto out_module_put;
1089 
1090     ctrl = ops->create_ctrl(dev, opts);
1091     if (IS_ERR(ctrl)) {
1092         ret = PTR_ERR(ctrl);
1093         goto out_module_put;
1094     }
1095 
1096     module_put(ops->module);
1097     return ctrl;
1098 
1099 out_module_put:
1100     module_put(ops->module);
1101     goto out_free_opts;
1102 out_unlock:
1103     up_read(&nvmf_transports_rwsem);
1104 out_free_opts:
1105     nvmf_free_options(opts);
1106     return ERR_PTR(ret);
1107 }
1108 
1109 static struct class *nvmf_class;
1110 static struct device *nvmf_device;
1111 static DEFINE_MUTEX(nvmf_dev_mutex);
1112 
1113 static ssize_t nvmf_dev_write(struct file *file, const char __user *ubuf,
1114         size_t count, loff_t *pos)
1115 {
1116     struct seq_file *seq_file = file->private_data;
1117     struct nvme_ctrl *ctrl;
1118     const char *buf;
1119     int ret = 0;
1120 
1121     if (count > PAGE_SIZE)
1122         return -ENOMEM;
1123 
1124     buf = memdup_user_nul(ubuf, count);
1125     if (IS_ERR(buf))
1126         return PTR_ERR(buf);
1127 
1128     mutex_lock(&nvmf_dev_mutex);
1129     if (seq_file->private) {
1130         ret = -EINVAL;
1131         goto out_unlock;
1132     }
1133 
1134     ctrl = nvmf_create_ctrl(nvmf_device, buf);
1135     if (IS_ERR(ctrl)) {
1136         ret = PTR_ERR(ctrl);
1137         goto out_unlock;
1138     }
1139 
1140     seq_file->private = ctrl;
1141 
1142 out_unlock:
1143     mutex_unlock(&nvmf_dev_mutex);
1144     kfree(buf);
1145     return ret ? ret : count;
1146 }
1147 
1148 static void __nvmf_concat_opt_tokens(struct seq_file *seq_file)
1149 {
1150     const struct match_token *tok;
1151     int idx;
1152 
1153     /*
1154      * Add dummy entries for instance and cntlid to
1155      * signal an invalid/non-existing controller
1156      */
1157     seq_puts(seq_file, "instance=-1,cntlid=-1");
1158     for (idx = 0; idx < ARRAY_SIZE(opt_tokens); idx++) {
1159         tok = &opt_tokens[idx];
1160         if (tok->token == NVMF_OPT_ERR)
1161             continue;
1162         seq_puts(seq_file, ",");
1163         seq_puts(seq_file, tok->pattern);
1164     }
1165     seq_puts(seq_file, "\n");
1166 }
1167 
1168 static int nvmf_dev_show(struct seq_file *seq_file, void *private)
1169 {
1170     struct nvme_ctrl *ctrl;
1171 
1172     mutex_lock(&nvmf_dev_mutex);
1173     ctrl = seq_file->private;
1174     if (!ctrl) {
1175         __nvmf_concat_opt_tokens(seq_file);
1176         goto out_unlock;
1177     }
1178 
1179     seq_printf(seq_file, "instance=%d,cntlid=%d\n",
1180             ctrl->instance, ctrl->cntlid);
1181 
1182 out_unlock:
1183     mutex_unlock(&nvmf_dev_mutex);
1184     return 0;
1185 }
1186 
1187 static int nvmf_dev_open(struct inode *inode, struct file *file)
1188 {
1189     /*
1190      * The miscdevice code initializes file->private_data, but doesn't
1191      * make use of it later.
1192      */
1193     file->private_data = NULL;
1194     return single_open(file, nvmf_dev_show, NULL);
1195 }
1196 
1197 static int nvmf_dev_release(struct inode *inode, struct file *file)
1198 {
1199     struct seq_file *seq_file = file->private_data;
1200     struct nvme_ctrl *ctrl = seq_file->private;
1201 
1202     if (ctrl)
1203         nvme_put_ctrl(ctrl);
1204     return single_release(inode, file);
1205 }
1206 
1207 static const struct file_operations nvmf_dev_fops = {
1208     .owner      = THIS_MODULE,
1209     .write      = nvmf_dev_write,
1210     .read       = seq_read,
1211     .open       = nvmf_dev_open,
1212     .release    = nvmf_dev_release,
1213 };
1214 
1215 static struct miscdevice nvmf_misc = {
1216     .minor      = MISC_DYNAMIC_MINOR,
1217     .name           = "nvme-fabrics",
1218     .fops       = &nvmf_dev_fops,
1219 };
1220 
1221 static int __init nvmf_init(void)
1222 {
1223     int ret;
1224 
1225     nvmf_default_host = nvmf_host_default();
1226     if (!nvmf_default_host)
1227         return -ENOMEM;
1228 
1229     nvmf_class = class_create(THIS_MODULE, "nvme-fabrics");
1230     if (IS_ERR(nvmf_class)) {
1231         pr_err("couldn't register class nvme-fabrics\n");
1232         ret = PTR_ERR(nvmf_class);
1233         goto out_free_host;
1234     }
1235 
1236     nvmf_device =
1237         device_create(nvmf_class, NULL, MKDEV(0, 0), NULL, "ctl");
1238     if (IS_ERR(nvmf_device)) {
1239         pr_err("couldn't create nvme-fabrics device!\n");
1240         ret = PTR_ERR(nvmf_device);
1241         goto out_destroy_class;
1242     }
1243 
1244     ret = misc_register(&nvmf_misc);
1245     if (ret) {
1246         pr_err("couldn't register misc device: %d\n", ret);
1247         goto out_destroy_device;
1248     }
1249 
1250     return 0;
1251 
1252 out_destroy_device:
1253     device_destroy(nvmf_class, MKDEV(0, 0));
1254 out_destroy_class:
1255     class_destroy(nvmf_class);
1256 out_free_host:
1257     nvmf_host_put(nvmf_default_host);
1258     return ret;
1259 }
1260 
1261 static void __exit nvmf_exit(void)
1262 {
1263     misc_deregister(&nvmf_misc);
1264     device_destroy(nvmf_class, MKDEV(0, 0));
1265     class_destroy(nvmf_class);
1266     nvmf_host_put(nvmf_default_host);
1267 
1268     BUILD_BUG_ON(sizeof(struct nvmf_common_command) != 64);
1269     BUILD_BUG_ON(sizeof(struct nvmf_connect_command) != 64);
1270     BUILD_BUG_ON(sizeof(struct nvmf_property_get_command) != 64);
1271     BUILD_BUG_ON(sizeof(struct nvmf_property_set_command) != 64);
1272     BUILD_BUG_ON(sizeof(struct nvmf_auth_send_command) != 64);
1273     BUILD_BUG_ON(sizeof(struct nvmf_auth_receive_command) != 64);
1274     BUILD_BUG_ON(sizeof(struct nvmf_connect_data) != 1024);
1275     BUILD_BUG_ON(sizeof(struct nvmf_auth_dhchap_negotiate_data) != 8);
1276     BUILD_BUG_ON(sizeof(struct nvmf_auth_dhchap_challenge_data) != 16);
1277     BUILD_BUG_ON(sizeof(struct nvmf_auth_dhchap_reply_data) != 16);
1278     BUILD_BUG_ON(sizeof(struct nvmf_auth_dhchap_success1_data) != 16);
1279     BUILD_BUG_ON(sizeof(struct nvmf_auth_dhchap_success2_data) != 16);
1280 }
1281 
1282 MODULE_LICENSE("GPL v2");
1283 
1284 module_init(nvmf_init);
1285 module_exit(nvmf_exit);