]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/target/loopback/tcm_loop.c
tcm_loop: Implement transport offline
[karo-tx-linux.git] / drivers / target / loopback / tcm_loop.c
index 21b49f3517235753318313c86b81aaae11ed9ee0..a00ad27940b77cb4cca53b6930e6a7541e7f2429 100644 (file)
@@ -178,7 +178,10 @@ static void tcm_loop_submission_work(struct work_struct *work)
                set_host_byte(sc, DID_NO_CONNECT);
                goto out_done;
        }
-
+       if (tl_tpg->tl_transport_status == TCM_TRANSPORT_OFFLINE) {
+               set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
+               goto out_done;
+       }
        tl_nexus = tl_hba->tl_nexus;
        if (!tl_nexus) {
                scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
@@ -1064,8 +1067,56 @@ check_newline:
 
 TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
 
+static ssize_t tcm_loop_tpg_show_transport_status(
+       struct se_portal_group *se_tpg,
+       char *page)
+{
+       struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
+                       struct tcm_loop_tpg, tl_se_tpg);
+       const char *status = NULL;
+       ssize_t ret = -EINVAL;
+
+       switch (tl_tpg->tl_transport_status) {
+       case TCM_TRANSPORT_ONLINE:
+               status = "online";
+               break;
+       case TCM_TRANSPORT_OFFLINE:
+               status = "offline";
+               break;
+       default:
+               break;
+       }
+
+       if (status)
+               ret = snprintf(page, PAGE_SIZE, "%s\n", status);
+
+       return ret;
+}
+
+static ssize_t tcm_loop_tpg_store_transport_status(
+       struct se_portal_group *se_tpg,
+       const char *page,
+       size_t count)
+{
+       struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
+                       struct tcm_loop_tpg, tl_se_tpg);
+
+       if (!strncmp(page, "online", 6)) {
+               tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
+               return count;
+       }
+       if (!strncmp(page, "offline", 7)) {
+               tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE;
+               return count;
+       }
+       return -EINVAL;
+}
+
+TF_TPG_BASE_ATTR(tcm_loop, transport_status, S_IRUGO | S_IWUSR);
+
 static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
        &tcm_loop_tpg_nexus.attr,
+       &tcm_loop_tpg_transport_status.attr,
        NULL,
 };