svn commit: r297856 - head/sys/dev/isp

Alexander Motin mav at FreeBSD.org
Tue Apr 12 12:31:43 UTC 2016


Author: mav
Date: Tue Apr 12 12:31:41 2016
New Revision: 297856
URL: https://svnweb.freebsd.org/changeset/base/297856

Log:
  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.

Modified:
  head/sys/dev/isp/isp_freebsd.c

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Tue Apr 12 11:48:54 2016	(r297855)
+++ head/sys/dev/isp/isp_freebsd.c	Tue Apr 12 12:31:41 2016	(r297856)
@@ -607,9 +607,10 @@ ispioctl(struct cdev *dev, u_long c, cad
 		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, cad
 				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, cad
 				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) {


More information about the svn-src-head mailing list