[Stgt-devel] [PATCH 2/2] fcoe: add lu reset support
michaelc at cs.wisc.edu
michaelc
Wed Jul 23 10:24:50 CEST 2008
From: Mike Christie <michaelc at cs.wisc.edu>
This adds lun reset support. It also only supports one
target for now.
Signed-off-by: Mike Christie <michaelc at cs.wisc.edu>
---
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
More information about the stgt
mailing list