From 53791a95a48f5e6f0463e14837d26a065f212f39 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 12 Apr 2016 12:31:41 +0000 Subject: [PATCH] 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. --- sys/dev/isp/isp_freebsd.c | 101 ++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 23ec42a6b6c7..8787d94a643a 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -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) {