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:
parent
4328ca5a21
commit
96b5475b7a
@ -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. */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user