Reimplement ISP_TSK_MGMT IOCTL via asynchronous request.

I am not sure this code is not completely dead, but it used DMA scratch
are without good reason and asked to be refactored.
This commit is contained in:
Alexander Motin 2016-04-12 12:31:41 +00:00
parent cf4476eb39
commit 53791a95a4

View File

@ -607,9 +607,10 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
nphdl = fct->loopid;
ISP_LOCK(isp);
if (IS_24XX(isp)) {
uint8_t local[QENTRY_LEN];
isp24xx_tmf_t *tmf;
isp24xx_statusreq_t *sp;
void *reqp;
uint8_t resp[QENTRY_LEN];
isp24xx_tmf_t tmf;
isp24xx_statusreq_t sp;
fcparam *fcp = FCPARAM(isp, chan);
fcportdb_t *lp;
int i;
@ -625,39 +626,37 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
ISP_UNLOCK(isp);
break;
}
/* XXX VALIDATE LP XXX */
tmf = (isp24xx_tmf_t *) local;
ISP_MEMZERO(tmf, QENTRY_LEN);
tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
tmf->tmf_header.rqs_entry_count = 1;
tmf->tmf_nphdl = lp->handle;
tmf->tmf_delay = 2;
tmf->tmf_timeout = 4;
tmf->tmf_tidlo = lp->portid;
tmf->tmf_tidhi = lp->portid >> 16;
tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
tmf->tmf_lun[1] = fct->lun & 0xff;
ISP_MEMZERO(&tmf, sizeof(tmf));
tmf.tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
tmf.tmf_header.rqs_entry_count = 1;
tmf.tmf_nphdl = lp->handle;
tmf.tmf_delay = 2;
tmf.tmf_timeout = 4;
tmf.tmf_tidlo = lp->portid;
tmf.tmf_tidhi = lp->portid >> 16;
tmf.tmf_vpidx = ISP_GET_VPIDX(isp, chan);
tmf.tmf_lun[1] = fct->lun & 0xff;
if (fct->lun >= 256) {
tmf->tmf_lun[0] = 0x40 | (fct->lun >> 8);
tmf.tmf_lun[0] = 0x40 | (fct->lun >> 8);
}
switch (fct->action) {
case IPT_CLEAR_ACA:
tmf->tmf_flags = ISP24XX_TMF_CLEAR_ACA;
tmf.tmf_flags = ISP24XX_TMF_CLEAR_ACA;
break;
case IPT_TARGET_RESET:
tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
tmf.tmf_flags = ISP24XX_TMF_TARGET_RESET;
needmarker = 1;
break;
case IPT_LUN_RESET:
tmf->tmf_flags = ISP24XX_TMF_LUN_RESET;
tmf.tmf_flags = ISP24XX_TMF_LUN_RESET;
needmarker = 1;
break;
case IPT_CLEAR_TASK_SET:
tmf->tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET;
tmf.tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET;
needmarker = 1;
break;
case IPT_ABORT_TASK_SET:
tmf->tmf_flags = ISP24XX_TMF_ABORT_TASK_SET;
tmf.tmf_flags = ISP24XX_TMF_ABORT_TASK_SET;
needmarker = 1;
break;
default:
@ -668,36 +667,52 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
ISP_UNLOCK(isp);
break;
}
MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
MBCMD_DEFAULT_TIMEOUT + tmf->tmf_timeout * 1000000);
mbs.param[1] = QENTRY_LEN;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
if (FC_SCRATCH_ACQUIRE(isp, chan)) {
/* Prepare space for response in memory */
memset(resp, 0xff, sizeof(resp));
tmf.tmf_handle = isp_allocate_handle(isp, resp,
ISP_HANDLE_CTRL);
if (tmf.tmf_handle == 0) {
isp_prt(isp, ISP_LOGERR,
"%s: TMF of Chan %d out of handles",
__func__, chan);
ISP_UNLOCK(isp);
retval = ENOMEM;
break;
}
isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
sp = (isp24xx_statusreq_t *) local;
sp->req_completion_status = 1;
retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
FC_SCRATCH_RELEASE(isp, chan);
if (retval || sp->req_completion_status != 0) {
FC_SCRATCH_RELEASE(isp, chan);
/* Send request and wait for response. */
reqp = isp_getrqentry(isp);
if (reqp == NULL) {
isp_prt(isp, ISP_LOGERR,
"%s: TMF of Chan %d out of rqent",
__func__, chan);
isp_destroy_handle(isp, tmf.tmf_handle);
ISP_UNLOCK(isp);
retval = EIO;
break;
}
if (retval == 0) {
if (needmarker) {
fcp->sendmarker = 1;
}
isp_put_24xx_tmf(isp, &tmf, (isp24xx_tmf_t *)reqp);
if (isp->isp_dblev & ISP_LOGDEBUG1)
isp_print_bytes(isp, "IOCB TMF", QENTRY_LEN, reqp);
ISP_SYNC_REQUEST(isp);
if (msleep(resp, &isp->isp_lock, 0, "TMF", 5*hz) == EWOULDBLOCK) {
isp_prt(isp, ISP_LOGERR,
"%s: TMF of Chan %d timed out",
__func__, chan);
isp_destroy_handle(isp, tmf.tmf_handle);
ISP_UNLOCK(isp);
retval = EIO;
break;
}
if (isp->isp_dblev & ISP_LOGDEBUG1)
isp_print_bytes(isp, "IOCB TMF response", QENTRY_LEN, resp);
isp_get_24xx_response(isp, (isp24xx_statusreq_t *)resp, &sp);
if (sp.req_completion_status != 0)
retval = EIO;
else if (needmarker)
fcp->sendmarker = 1;
} else {
MBSINIT(&mbs, 0, MBLOGALL, 0);
if (ISP_CAP_2KLOGIN(isp) == 0) {