From: Mike Christie <[EMAIL PROTECTED]>

This adds lun reset support. It also only supports one
target for now.

Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
---
 usr/fcoe/fcoe_if.c         |    8 ++++
 usr/fcoe/openfc_scst.c     |   36 +++++++++++++++++++
 usr/fcoe/openfc_scst_pkt.h |    2 +
 usr/fcoe/openfc_target.c   |   81 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 126 insertions(+), 1 deletions(-)

diff --git a/usr/fcoe/fcoe_if.c b/usr/fcoe/fcoe_if.c
index 9470f70..28d8140 100644
--- a/usr/fcoe/fcoe_if.c
+++ b/usr/fcoe/fcoe_if.c
@@ -34,6 +34,7 @@
 #include "util.h"
 #include "tgtd.h"
 #include "driver.h"
+#include "target.h"
 
 #include "fc_types.h"
 #include "fc_frame.h"
@@ -46,6 +47,9 @@
 #include "fcoe_def.h"
 
 extern int fcoe_cmd_done(uint64_t nid, int result, struct scsi_cmd *scmd);
+extern int fcoe_tmf_done(struct mgmt_req *mreq);
+extern int fcoe_target_create(struct target *t);
+extern void fcoe_target_destroy(int tid);
 
 static struct openfc_port_operations fcoe_port_ops = {
        .send = fcoe_xmit,
@@ -214,8 +218,12 @@ static int fcoe_init(int index, char *args)
 static struct tgt_driver fcoe = {
        .name                   = "fcoe",
        .use_kernel             = 0,
+       .target_create          = fcoe_target_create,
+       .target_destroy         = fcoe_target_destroy,
        .init                   = fcoe_init,
+
        .cmd_end_notify         = fcoe_cmd_done,
+       .mgmt_end_notify        = fcoe_tmf_done,
        .default_bst            = "rdwr",
 };
 
diff --git a/usr/fcoe/openfc_scst.c b/usr/fcoe/openfc_scst.c
index f24fc28..4e7fa56 100644
--- a/usr/fcoe/openfc_scst.c
+++ b/usr/fcoe/openfc_scst.c
@@ -137,6 +137,7 @@ void openfct_rcv_cmd(struct fc_seq *sp, struct fc_frame 
*fp, void *arg)
                pkt->lun = net64_get((net64_t *) & fcmd->fc_lun);
                memcpy(pkt->lunp, fcmd->fc_lun, 8);
                memcpy(pkt->cdb, fcmd->fc_cdb, 16);
+
                fc_seq_set_recv(sp, openfct_rcv_data, (void *)pkt);
                openfct_process_scsi_cmd(hba, pkt, fcmd);
                break;
@@ -151,11 +152,15 @@ void openfc_scst_completion(void *arg)
        struct fc_scsi_pkt *pkt  = arg;
        struct scsi_cmd *scmd = &pkt->scmd;
 
+       eprintf("pkt->cnt %u\n", pkt->cnt);
+
        if (!(--pkt->cnt)) {
                if (pkt->seq_ptr)
                        fc_seq_exch_complete(pkt->seq_ptr);
                pkt->seq_ptr = NULL;
 
+               if (!(pkt->flags & OPENFC_TMF_PKT))
+                       target_cmd_done(scmd);
                if (scsi_get_in_buffer(scmd))
                        free(scsi_get_in_buffer(scmd));
                if (scsi_get_out_buffer(scmd))
@@ -164,6 +169,37 @@ void openfc_scst_completion(void *arg)
        }
 }
 
+void openfct_scsi_send_tmf_rsp(struct fc_scsi_pkt *pkt, uint8_t rsp)
+{
+       struct fc_seq  *sp = pkt->seq_ptr;
+       struct fc_frame *fp;
+       struct fcp_resp *fc_rp;
+       struct fcp_resp_ext *fc_exrp;
+       struct fcp_resp_rsp_info *fc_rsp_info;
+       unsigned int len;
+
+       len = sizeof(*fc_rp) + sizeof(*fc_exrp) + sizeof(*fc_rsp_info);
+
+       fp = fc_frame_alloc(pkt->openfcp->fcs_port, len);
+       if (!fp)
+               return;
+       pkt->cnt = 1;
+       fp->fr_destructor = openfc_scst_completion;
+       fp->fr_arg = pkt;
+       fc_rp = fc_frame_payload_get(fp, sizeof(*fc_rp));
+       memset(fc_rp, 0, len);
+       sp = fc_seq_start_next(sp);
+
+       fc_rp->fr_flags = SS_RESPONSE_INFO_LEN_VALID;
+       fc_exrp = (struct fcp_resp_ext *) (fc_rp + 1);
+       net32_put(&fc_exrp->fr_rsp_len, sizeof(*fc_rsp_info));
+
+       fc_rsp_info = (struct fcp_resp_rsp_info *) (fc_exrp + 1);
+       fc_rsp_info->rsp_code = rsp;
+
+       fc_seq_send_last(sp, fp, FC_RCTL_DD_CMD_STATUS, FC_TYPE_FCP);
+}
+
 void openfct_scsi_send_status(struct fc_scsi_pkt *pkt)
 {
        struct fc_seq  *sp = pkt->seq_ptr;
diff --git a/usr/fcoe/openfc_scst_pkt.h b/usr/fcoe/openfc_scst_pkt.h
index d7089d0..a63cfd6 100644
--- a/usr/fcoe/openfc_scst_pkt.h
+++ b/usr/fcoe/openfc_scst_pkt.h
@@ -67,6 +67,7 @@ struct openfct_tgt;
 #define OPENFC_CMD_WAIT_FOR_DATA 5
 
 #define OPENFC_SENSE_VALID 1
+#define OPENFC_TMF_PKT 2
 /*
  * Status entry SCSI status bit definitions.
  */
@@ -89,6 +90,7 @@ struct openfct_sess {
 
 struct openfct_tgt {
        u_int32_t       handle;
+       int             tid;
        void           *ha;
        int             status;
        /* Target's flags, serialized by ha->hardware_lock */
diff --git a/usr/fcoe/openfc_target.c b/usr/fcoe/openfc_target.c
index dcecefe..60d3e27 100644
--- a/usr/fcoe/openfc_target.c
+++ b/usr/fcoe/openfc_target.c
@@ -13,6 +13,7 @@
 #include "util.h"
 #include "tgtd.h"
 #include "scsi.h"
+#include "target.h"
 
 #include "fc_types.h"
 #include "fc_port.h"
@@ -30,6 +31,9 @@ extern void openfct_rcv_cmd(struct fc_seq *sp, struct 
fc_frame *fp, void *arg);
 extern void openfct_send_xfer_rdy(struct fc_scsi_pkt *);
 extern void openfct_scsi_send_status(struct fc_scsi_pkt *pkt);
 extern int openfct_scsi_send_data_status(struct fc_scsi_pkt *pkt);
+extern void openfct_scsi_send_tmf_rsp(struct fc_scsi_pkt *pkt, uint8_t rsp);
+
+static struct target *fc_target;
 
 static struct openfct_sess *openfct_find_sess_by_fcid(struct openfct_tgt *tgt,
                                                      u_int32_t fcid)
@@ -61,7 +65,7 @@ int fcoe_cmd_done(uint64_t nid, int result, struct scsi_cmd 
*scmd)
                pkt->residual = scsi_get_in_resid(scmd);
 
                if (scsi_get_result(scmd) != SAM_STAT_GOOD) {
-                       pkt->flags = OPENFC_SENSE_VALID;
+                       pkt->flags |= OPENFC_SENSE_VALID;
                        pkt->rq_result |= SS_SENSE_LEN_VALID;
                        data_sense_flag = 1;
                }
@@ -97,6 +101,54 @@ static int cmd_attr(struct fcp_cmnd *fcmd)
        return attr;
 }
 
+int fcoe_tmf_done(struct mgmt_req *mreq)
+{
+       struct fc_scsi_pkt *pkt;
+       uint8_t rsp;
+
+       dprintf("tmf result %d\n", mreq->result);
+
+       pkt = (struct fc_scsi_pkt *) (unsigned long) mreq->mid;
+       switch (mreq->result) {
+       case 0:
+               rsp = FCP_TMF_CMPL;
+               break;
+       default:
+               /* we do not seem to get enough info to return something else */
+               rsp = FCP_TMF_FAILED;
+       }
+
+       openfct_scsi_send_tmf_rsp(pkt, rsp);
+       return 0;
+}
+
+static int openfct_process_tmf(struct fc_scsi_pkt *fsp, struct fcp_cmnd *fcmd)
+{
+       int fn = 0, err = 0;
+
+       dprintf("tmf cmd %0x\n", fcmd->fc_tm_flags);
+
+       switch (fcmd->fc_tm_flags) {
+       case FCP_TMF_LUN_RESET:
+               fn = LOGICAL_UNIT_RESET;
+               break;
+       default:
+               err = -ENOSYS;
+               eprintf("Unsupported task management function %d.\n",
+                       fcmd->fc_tm_flags);
+       }
+
+       if (!err) {
+               fsp->flags |= OPENFC_TMF_PKT;
+               /* tid is busted - need a target create */
+               target_mgmt_request(fc_target->tid, fsp->fcid,
+                                   (unsigned long ) fsp, fn,
+                                   fcmd->fc_lun, fsp->exid, 0);
+       }
+       return err;
+
+}
+
 int openfct_process_scsi_cmd(struct openfchba_softc *openfcp,
                             struct fc_scsi_pkt *fsp, struct fcp_cmnd *fcmd)
 {
@@ -126,6 +178,10 @@ int openfct_process_scsi_cmd(struct openfchba_softc 
*openfcp,
        }
 
        fsp->tgt = tgt;
+
+       if (fcmd->fc_tm_flags)
+               return openfct_process_tmf(fsp, fcmd);
+
        memcpy(scmd->lun, fsp->lunp, 8);
        scmd->scb = fsp->cdb;
        scmd->tag = fsp->exid;
@@ -302,6 +358,29 @@ static struct fcs_create_args openfct_fcs_args = {
 
 };
 
+/*
+ * We currently only support one target
+ */
+int fcoe_target_create(struct target *t)
+{
+       if (fc_target) {
+               eprintf("Only one fcoe target supported. Currently fcoe tid "
+                       "%u is running\n", fc_target->tid);
+               return -EINVAL;
+       }
+       fc_target = t;
+       return 0;
+}
+
+void fcoe_target_destroy(int tid)
+{
+       if (!fc_target)
+               return;
+       if (fc_target->tid != tid)
+               return;
+       fc_target = NULL;
+}
+
 /**
  * openfct_attach: Called by bus code for each adapter
  */
-- 
1.5.5.1

_______________________________________________
Stgt-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/stgt-devel

Reply via email to