nvme: use blk_execute_rq() for passthrough commands
[linux-2.6-microblaze.git] / drivers / nvme / host / tcp.c
index 34f4b34..12acfe0 100644 (file)
@@ -123,6 +123,7 @@ struct nvme_tcp_ctrl {
        struct blk_mq_tag_set   admin_tag_set;
        struct sockaddr_storage addr;
        struct sockaddr_storage src_addr;
+       struct net_device       *ndev;
        struct nvme_ctrl        ctrl;
 
        struct work_struct      err_work;
@@ -1455,6 +1456,20 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
                }
        }
 
+       if (nctrl->opts->mask & NVMF_OPT_HOST_IFACE) {
+               char *iface = nctrl->opts->host_iface;
+               sockptr_t optval = KERNEL_SOCKPTR(iface);
+
+               ret = sock_setsockopt(queue->sock, SOL_SOCKET, SO_BINDTODEVICE,
+                                     optval, strlen(iface));
+               if (ret) {
+                       dev_err(nctrl->device,
+                         "failed to bind to interface %s queue %d err %d\n",
+                         iface, qid, ret);
+                       goto err_sock;
+               }
+       }
+
        queue->hdr_digest = nctrl->opts->hdr_digest;
        queue->data_digest = nctrl->opts->data_digest;
        if (queue->hdr_digest || queue->data_digest) {
@@ -1559,7 +1574,7 @@ static int nvme_tcp_start_queue(struct nvme_ctrl *nctrl, int idx)
        int ret;
 
        if (idx)
-               ret = nvmf_connect_io_queue(nctrl, idx, false);
+               ret = nvmf_connect_io_queue(nctrl, idx);
        else
                ret = nvmf_connect_admin_queue(nctrl);
 
@@ -1973,11 +1988,13 @@ static int nvme_tcp_setup_ctrl(struct nvme_ctrl *ctrl, bool new)
                return ret;
 
        if (ctrl->icdoff) {
+               ret = -EOPNOTSUPP;
                dev_err(ctrl->device, "icdoff is not supported!\n");
                goto destroy_admin;
        }
 
-       if (!(ctrl->sgls & ((1 << 0) | (1 << 1)))) {
+       if (!nvme_ctrl_sgl_supported(ctrl)) {
+               ret = -EOPNOTSUPP;
                dev_err(ctrl->device, "Mandatory sgls are not supported!\n");
                goto destroy_admin;
        }
@@ -2515,6 +2532,16 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
                }
        }
 
+       if (opts->mask & NVMF_OPT_HOST_IFACE) {
+               ctrl->ndev = dev_get_by_name(&init_net, opts->host_iface);
+               if (!ctrl->ndev) {
+                       pr_err("invalid interface passed: %s\n",
+                              opts->host_iface);
+                       ret = -ENODEV;
+                       goto out_free_ctrl;
+               }
+       }
+
        if (!opts->duplicate_connect && nvme_tcp_existing_controller(opts)) {
                ret = -EALREADY;
                goto out_free_ctrl;
@@ -2571,7 +2598,7 @@ static struct nvmf_transport_ops nvme_tcp_transport = {
                          NVMF_OPT_HOST_TRADDR | NVMF_OPT_CTRL_LOSS_TMO |
                          NVMF_OPT_HDR_DIGEST | NVMF_OPT_DATA_DIGEST |
                          NVMF_OPT_NR_WRITE_QUEUES | NVMF_OPT_NR_POLL_QUEUES |
-                         NVMF_OPT_TOS,
+                         NVMF_OPT_TOS | NVMF_OPT_HOST_IFACE,
        .create_ctrl    = nvme_tcp_create_ctrl,
 };