Pass task management response information from CTL through CAM to isp(4),

utilizing previously unused arg field of struct ccb_notify_acknowledge.

This makes new QUERY TASK, QUERY TASK SET and QUERY ASYNC EVENT requests
really functional for CAM target mode drivers.
This commit is contained in:
Alexander Motin 2016-05-20 10:26:12 +00:00
parent 4328ca5a21
commit 96b5475b7a
3 changed files with 49 additions and 6 deletions

View File

@ -1087,7 +1087,17 @@ struct ccb_notify_acknowledge {
u_int tag_id; /* Tag for immediate notify */
u_int seq_id; /* Tar for target of notify */
u_int initiator_id; /* Initiator Identifier */
u_int arg; /* Function specific */
u_int arg; /* Response information */
/*
* Lower byte of arg is one of RESPONSE CODE values defined below
* (subset of response codes from SPL-4 and FCP-4 specifications),
* upper 3 bytes is code-specific ADDITIONAL RESPONSE INFORMATION.
*/
#define CAM_RSP_TMF_COMPLETE 0x00
#define CAM_RSP_TMF_REJECTED 0x04
#define CAM_RSP_TMF_FAILED 0x05
#define CAM_RSP_TMF_SUCCEEDED 0x08
#define CAM_RSP_TMF_INCORRECT_LUN 0x09
};
/* HBA engine structures. */

View File

@ -1552,6 +1552,7 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
/*
* Queue this back down to the SIM as an immediate notify.
*/
done_ccb->ccb_h.status = CAM_REQ_INPROG;
done_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
xpt_action(done_ccb);
break;
@ -2041,6 +2042,28 @@ ctlfe_done(union ctl_io *io)
*/
ccb->ccb_h.status = CAM_REQ_INPROG;
ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
switch (io->taskio.task_status) {
case CTL_TASK_FUNCTION_COMPLETE:
ccb->cna2.arg = CAM_RSP_TMF_COMPLETE;
break;
case CTL_TASK_FUNCTION_SUCCEEDED:
ccb->cna2.arg = CAM_RSP_TMF_SUCCEEDED;
ccb->ccb_h.flags |= CAM_SEND_STATUS;
break;
case CTL_TASK_FUNCTION_REJECTED:
ccb->cna2.arg = CAM_RSP_TMF_REJECTED;
ccb->ccb_h.flags |= CAM_SEND_STATUS;
break;
case CTL_TASK_LUN_DOES_NOT_EXIST:
ccb->cna2.arg = CAM_RSP_TMF_INCORRECT_LUN;
ccb->ccb_h.flags |= CAM_SEND_STATUS;
break;
case CTL_TASK_FUNCTION_NOT_SUPPORTED:
ccb->cna2.arg = CAM_RSP_TMF_FAILED;
ccb->ccb_h.flags |= CAM_SEND_STATUS;
break;
}
ccb->cna2.arg |= scsi_3btoul(io->taskio.task_resp) << 8;
xpt_action(ccb);
} else if (io->io_hdr.flags & CTL_FLAG_STATUS_SENT) {
if (softc->flags & CTLFE_LUN_WILDCARD) {

View File

@ -856,7 +856,7 @@ static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
static void isp_handle_platform_ctio(ispsoftc_t *, void *);
static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *);
static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
@ -2761,7 +2761,7 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
}
static int
isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp)
isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp, uint32_t rsp)
{
if (isp->isp_state != ISP_RUNSTATE) {
@ -2796,6 +2796,15 @@ isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp)
cto->ct_oxid = aep->at_hdr.ox_id;
cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1;
cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT;
if (rsp != 0) {
cto->ct_scsi_status |= (FCP_RSPLEN_VALID << 8);
cto->rsp.m1.ct_resplen = 4;
ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
cto->rsp.m1.ct_resp[0] = rsp & 0xff;
cto->rsp.m1.ct_resp[1] = (rsp >> 8) & 0xff;
cto->rsp.m1.ct_resp[2] = (rsp >> 16) & 0xff;
cto->rsp.m1.ct_resp[3] = (rsp >> 24) & 0xff;
}
return (isp_target_put_entry(isp, &local));
}
@ -3642,7 +3651,8 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
xpt_done(ccb);
break;
}
if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt)) {
if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt,
(ccb->ccb_h.flags & CAM_SEND_STATUS) ? ccb->cna2.arg : 0)) {
rls_lun_statep(isp, tptr);
cam_freeze_devq(ccb->ccb_h.path);
cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
@ -4408,11 +4418,11 @@ changed:
/*
* This is device arrival/departure notification
*/
isp_handle_platform_target_notify_ack(isp, notify);
isp_handle_platform_target_notify_ack(isp, notify, 0);
break;
default:
isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
isp_handle_platform_target_notify_ack(isp, notify);
isp_handle_platform_target_notify_ack(isp, notify, 0);
break;
}
break;