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:
parent
cf4476eb39
commit
53791a95a4
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user