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

Alexander Motin mav at FreeBSD.org
Wed Mar 15 14:58:31 UTC 2017


Author: mav
Date: Wed Mar 15 14:58:29 2017
New Revision: 315307
URL: https://svnweb.freebsd.org/changeset/base/315307

Log:
  Refactor interrupt handling.
  
  Instead of single isp_intr() function doing all possible magic, introduce
  four different functions to handle mailbox operation completions, async
  events, response and ATIO queues.  The goal is to isolate different code
  paths to make code more readable, and to make easier support for multiple
  interrupt vectors.  Even oldest hardware in many cases can identify what
  code path it should run on interrupt.  Contemporary hardware can assign
  them to different interrupt vectors.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/isp/isp.c
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_pci.c
  head/sys/dev/isp/isp_sbus.c
  head/sys/dev/isp/ispvar.h

Modified: head/sys/dev/isp/isp.c
==============================================================================
--- head/sys/dev/isp/isp.c	Wed Mar 15 14:44:59 2017	(r315306)
+++ head/sys/dev/isp/isp.c	Wed Mar 15 14:58:29 2017	(r315307)
@@ -416,11 +416,6 @@ isp_reset(ispsoftc_t *isp, int do_load_d
 	}
 
 	/*
-	 * Clear instrumentation
-	 */
-	isp->isp_intcnt = isp->isp_intbogus = 0;
-
-	/*
 	 * Hit the chip over the head with hammer,
 	 * and give it a chance to recover.
 	 */
@@ -4404,7 +4399,7 @@ isp_start(XS_T *xs)
 		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
 	} else if (IS_FC(isp)) {
 		/*
-		 * See comment in isp_intr
+		 * See comment in isp_intr_respq
 		 */
 		/* XS_SET_RESID(xs, 0); */
 
@@ -4911,6 +4906,70 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
  * and the locking will be held throughout this function.
  */
 
+#ifdef	ISP_TARGET_MODE
+void
+isp_intr_atioq(ispsoftc_t *isp)
+{
+	uint8_t qe[QENTRY_LEN];
+	isphdr_t *hp;
+	void *addr;
+	uint32_t iptr, optr, oop;
+
+	iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
+	optr = isp->isp_atioodx;
+	while (optr != iptr) {
+		oop = optr;
+		MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
+		addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
+		isp_get_hdr(isp, addr, (isphdr_t *)qe);
+		hp = (isphdr_t *)qe;
+		switch (hp->rqs_entry_type) {
+		case RQSTYPE_NOTIFY:
+		case RQSTYPE_ATIO:
+			(void) isp_target_notify(isp, addr, &oop);
+			break;
+		default:
+			isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
+			break;
+		}
+		optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
+	}
+	if (isp->isp_atioodx != optr) {
+		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
+		isp->isp_atioodx = optr;
+	}
+}
+#endif
+
+void
+isp_intr_async(ispsoftc_t *isp, uint16_t event)
+{
+
+	if (IS_FC(isp))
+		isp_parse_async_fc(isp, event);
+	else
+		isp_parse_async(isp, event);
+}
+
+void
+isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
+{
+	int i, obits;
+
+	if (!isp->isp_mboxbsy) {
+		isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
+		return;
+	}
+	obits = isp->isp_obits;
+	isp->isp_mboxtmp[0] = mbox0;
+	for (i = 1; i < ISP_NMBOX(isp); i++) {
+		if ((obits & (1 << i)) == 0)
+			continue;
+		isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
+	}
+	MBOX_NOTIFY_COMPLETE(isp);
+}
+
 /*
  * Limit our stack depth by sticking with the max likely number
  * of completions on a request queue at any one time.
@@ -4920,165 +4979,32 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
 #endif
 
 void
-isp_intr(ispsoftc_t *isp, uint16_t isr, uint16_t sema, uint16_t info)
+isp_intr_respq(ispsoftc_t *isp)
 {
 	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
 	uint32_t iptr, optr, junk;
 	int i, nlooked = 0, ndone = 0, continuations_expected = 0;
 	int etype, last_etype = 0;
 
-again:
-	/*
-	 * Is this a mailbox related interrupt?
-	 * The mailbox semaphore will be nonzero if so.
-	 */
-	if (sema) {
- fmbox:
-		if (info & MBOX_COMMAND_COMPLETE) {
-			isp->isp_intmboxc++;
-			if (isp->isp_mboxbsy) {
-				int obits = isp->isp_obits;
-				isp->isp_mboxtmp[0] = info;
-				for (i = 1; i < ISP_NMBOX(isp); i++) {
-					if ((obits & (1 << i)) == 0) {
-						continue;
-					}
-					isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
-				}
-				MBOX_NOTIFY_COMPLETE(isp);
-			} else {
-				isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", info);
-			}
-		} else {
-			if (IS_FC(isp))
-				isp_parse_async_fc(isp, info);
-			else
-				isp_parse_async(isp, info);
-		}
-		if ((IS_FC(isp) && info != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
-			goto out;
-		}
-	}
-
 	/*
 	 * We can't be getting this now.
 	 */
 	if (isp->isp_state != ISP_RUNSTATE) {
-		/*
-		 * This seems to happen to 23XX and 24XX cards- don't know why.
-		 */
-		 if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
-			goto fmbox;
-		}
-		isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x INFO=%x) "
-		    "when not ready", isr, sema, info);
-		/*
-		 * Thank you very much!  *Burrrp*!
-		 */
-		isp->isp_residx = ISP_READ(isp, isp->isp_respinrp);
-		isp->isp_resodx = isp->isp_residx;
-		ISP_WRITE(isp, isp->isp_respoutrp, isp->isp_resodx);
-		if (IS_24XX(isp)) {
-			ISP_DISABLE_INTS(isp);
-		}
-		goto out;
-	}
-
-#ifdef	ISP_TARGET_MODE
-	/*
-	 * Check for ATIO Queue entries.
-	 */
-	if (IS_24XX(isp) &&
-	    (isr == ISPR2HST_ATIO_UPDATE || isr == ISPR2HST_ATIO_RSPQ_UPDATE ||
-	     isr == ISPR2HST_ATIO_UPDATE2)) {
-		iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
-		optr = isp->isp_atioodx;
-
-		while (optr != iptr) {
-			uint8_t qe[QENTRY_LEN];
-			isphdr_t *hp;
-			uint32_t oop;
-			void *addr;
-
-			oop = optr;
-			MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
-			addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
-			isp_get_hdr(isp, addr, (isphdr_t *)qe);
-			hp = (isphdr_t *)qe;
-			switch (hp->rqs_entry_type) {
-			case RQSTYPE_NOTIFY:
-			case RQSTYPE_ATIO:
-				(void) isp_target_notify(isp, addr, &oop);
-				break;
-			default:
-				isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
-				break;
-			}
-			optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
-		}
-		if (isp->isp_atioodx != optr) {
-			ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
-			isp->isp_atioodx = optr;
-		}
+		isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
+		return;
 	}
-#endif
 
-	/*
-	 * You *must* read the Response Queue In Pointer
-	 * prior to clearing the RISC interrupt.
-	 *
-	 * Debounce the 2300 if revision less than 2.
-	 */
+	iptr = ISP_READ(isp, isp->isp_respinrp);
+	/* Debounce the 2300 if revision less than 2. */
 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
-		i = 0;
 		do {
+			junk = iptr;
 			iptr = ISP_READ(isp, isp->isp_respinrp);
-			junk = ISP_READ(isp, isp->isp_respinrp);
-		} while (junk != iptr && ++i < 1000);
-
-		if (iptr != junk) {
-			isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
-			goto out;
-		}
-	} else {
-		iptr = ISP_READ(isp, isp->isp_respinrp);
-	}
-
-	optr = isp->isp_resodx;
-	if (optr == iptr && sema == 0) {
-		/*
-		 * There are a lot of these- reasons unknown- mostly on
-		 * faster Alpha machines.
-		 *
-		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
-		 * make sure the old interrupt went away (to avoid 'ringing'
-		 * effects), but that didn't stop this from occurring.
-		 */
-		if (IS_24XX(isp)) {
-			junk = 0;
-		} else if (IS_23XX(isp)) {
-			ISP_DELAY(100);
-			iptr = ISP_READ(isp, isp->isp_respinrp);
-			junk = ISP_READ(isp, BIU_R2HSTSLO);
-		} else {
-			junk = ISP_READ(isp, BIU_ISR);
-		}
-		if (optr == iptr) {
-			if (IS_23XX(isp) || IS_24XX(isp)) {
-				;
-			} else {
-				sema = ISP_READ(isp, BIU_SEMA);
-				info = ISP_READ(isp, OUTMAILBOX0);
-				if ((sema & 0x3) && (info & 0x8000)) {
-					goto again;
-				}
-			}
-			isp->isp_intbogus++;
-			isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
-		}
+		} while (junk != iptr);
 	}
 	isp->isp_residx = iptr;
 
+	optr = isp->isp_resodx;
 	while (optr != iptr) {
 		uint8_t qe[QENTRY_LEN];
 		ispstatusreq_t *sp = (ispstatusreq_t *) qe;
@@ -5130,9 +5056,6 @@ again:
 			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
 				isp_fastpost_complete(isp, rio->req_handles[i]);
 			}
-			if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
-				isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
-			}
 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
 			last_etype = etype;
 			continue;
@@ -5377,10 +5300,8 @@ again:
 					if (ndone > (MAX_REQUESTQ_COMPLETIONS - continuations_expected - 1)) {
 						/* we'll lose some stats, but that's a small price to pay */
 						for (i = 0; i < ndone; i++) {
-							if (complist[i]) {
-								isp->isp_rsltccmplt++;
+							if (complist[i])
 								isp_done(complist[i]);
-							}
 						}
 						ndone = 0;
 					}
@@ -5453,17 +5374,6 @@ again:
 	if (nlooked) {
 		ISP_WRITE(isp, isp->isp_respoutrp, optr);
 		isp->isp_resodx = optr;
-		if (isp->isp_rscchiwater < ndone)
-			isp->isp_rscchiwater = ndone;
-	}
-
-out:
-
-	if (IS_24XX(isp)) {
-		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
-	} else {
-		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-		ISP_WRITE(isp, BIU_SEMA, 0);
 	}
 
 	for (i = 0; i < ndone; i++) {
@@ -5473,7 +5383,6 @@ out:
 			    ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
 				isp_prt_endcmd(isp, xs);
 			}
-			isp->isp_rsltccmplt++;
 			isp_done(xs);
 		}
 	}
@@ -5666,16 +5575,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_
 		if (h2) {
 			isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
 			isp_fastpost_complete(isp, h2);
-			if (isp->isp_fpcchiwater < 2) {
-				isp->isp_fpcchiwater = 2;
-			}
-		} else {
-			if (isp->isp_fpcchiwater < 1) {
-				isp->isp_fpcchiwater = 1;
-			}
 		}
-	} else {
-		isp->isp_intoasync++;
 	}
 }
 
@@ -5733,19 +5633,16 @@ isp_parse_async_fc(ispsoftc_t *isp, uint
 
 	case ASYNC_CMD_CMPLT:
 		isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
-		if (isp->isp_fpcchiwater < 1) {
-			isp->isp_fpcchiwater = 1;
-		}
 		break;
 
 	case ASYNC_RIOZIO_STALL:
+		isp_intr_respq(isp);
 		break;
 
 	case ASYNC_CTIO_DONE:
 #ifdef	ISP_TARGET_MODE
 		isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) |
 		    ISP_READ(isp, OUTMAILBOX1), mbox);
-		isp->isp_fphccmplt++;
 #else
 		isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
 #endif
@@ -6017,9 +5914,6 @@ isp_parse_async_fc(ispsoftc_t *isp, uint
 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
 		break;
 	}
-	if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
-		isp->isp_intoasync++;
-	}
 }
 
 /*
@@ -6106,11 +6000,9 @@ isp_handle_other_response(ispsoftc_t *is
 	case RQSTYPE_CTIO7:
 	case RQSTYPE_ABTS_RCVD:
 	case RQSTYPE_ABTS_RSP:
-		isp->isp_rsltccmplt++;	/* count as a response completion */
 #ifdef	ISP_TARGET_MODE
-		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
+		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp))
 			return (1);
-		}
 #endif
 		/* FALLTHROUGH */
 	case RQSTYPE_REQUEST:
@@ -6649,7 +6541,6 @@ isp_fastpost_complete(ispsoftc_t *isp, u
 	if (isp->isp_nactive) {
 		isp->isp_nactive--;
 	}
-	isp->isp_fphccmplt++;
 	isp_done(xs);
 }
 

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Wed Mar 15 14:44:59 2017	(r315306)
+++ head/sys/dev/isp/isp_freebsd.c	Wed Mar 15 14:58:29 2017	(r315307)
@@ -512,40 +512,6 @@ ispioctl(struct cdev *dev, u_long c, cad
 		}
 		break;
 	}
-	case ISP_GET_STATS:
-	{
-		isp_stats_t *sp = (isp_stats_t *) addr;
-
-		ISP_MEMZERO(sp, sizeof (*sp));
-		sp->isp_stat_version = ISP_STATS_VERSION;
-		sp->isp_type = isp->isp_type;
-		sp->isp_revision = isp->isp_revision;
-		ISP_LOCK(isp);
-		sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
-		sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
-		sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
-		sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
-		sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
-		sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
-		sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
-		sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
-		ISP_UNLOCK(isp);
-		retval = 0;
-		break;
-	}
-	case ISP_CLR_STATS:
-		ISP_LOCK(isp);
-		isp->isp_intcnt = 0;
-		isp->isp_intbogus = 0;
-		isp->isp_intmboxc = 0;
-		isp->isp_intoasync = 0;
-		isp->isp_rsltccmplt = 0;
-		isp->isp_fphccmplt = 0;
-		isp->isp_rscchiwater = 0;
-		isp->isp_fpcchiwater = 0;
-		ISP_UNLOCK(isp);
-		retval = 0;
-		break;
 	case ISP_FC_GETHINFO:
 	{
 		struct isp_hba_device *hba = (struct isp_hba_device *) addr;
@@ -2829,10 +2795,8 @@ static void
 isp_poll(struct cam_sim *sim)
 {
 	ispsoftc_t *isp = cam_sim_softc(sim);
-	uint16_t isr, sema, info;
 
-	if (ISP_READ_ISR(isp, &isr, &sema, &info))
-		isp_intr(isp, isr, sema, info);
+	ISP_RUN_ISR(isp);
 }
 
 
@@ -2851,9 +2815,7 @@ isp_watchdog(void *arg)
 	 * Hand crank the interrupt code just to be sure the command isn't stuck somewhere.
 	 */
 	if (handle != ISP_HANDLE_FREE) {
-		uint16_t isr, sema, info;
-		if (ISP_READ_ISR(isp, &isr, &sema, &info) != 0)
-			isp_intr(isp, isr, sema, info);
+		ISP_RUN_ISR(isp);
 		ohandle = handle;
 		handle = isp_find_handle(isp, xs);
 	}
@@ -4428,14 +4390,11 @@ isp_mbox_wait_complete(ispsoftc_t *isp, 
 		isp->isp_osinfo.mbox_sleeping = 0;
 	} else {
 		for (t = 0; t < to; t += 100) {
-			uint16_t isr, sema, info;
 			if (isp->isp_osinfo.mboxcmd_done)
 				break;
-			if (ISP_READ_ISR(isp, &isr, &sema, &info)) {
-				isp_intr(isp, isr, sema, info);
-				if (isp->isp_osinfo.mboxcmd_done)
-					break;
-			}
+			ISP_RUN_ISR(isp);
+			if (isp->isp_osinfo.mboxcmd_done)
+				break;
 			ISP_DELAY(100);
 		}
 	}
@@ -4495,14 +4454,9 @@ void
 isp_platform_intr(void *arg)
 {
 	ispsoftc_t *isp = arg;
-	uint16_t isr, sema, info;
 
 	ISP_LOCK(isp);
-	isp->isp_intcnt++;
-	if (ISP_READ_ISR(isp, &isr, &sema, &info))
-		isp_intr(isp, isr, sema, info);
-	else
-		isp->isp_intbogus++;
+	ISP_RUN_ISR(isp);
 	ISP_UNLOCK(isp);
 }
 

Modified: head/sys/dev/isp/isp_pci.c
==============================================================================
--- head/sys/dev/isp/isp_pci.c	Wed Mar 15 14:44:59 2017	(r315306)
+++ head/sys/dev/isp/isp_pci.c	Wed Mar 15 14:58:29 2017	(r315307)
@@ -61,9 +61,9 @@ static uint32_t isp_pci_rd_reg_2400(isps
 static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t);
 static uint32_t isp_pci_rd_reg_2600(ispsoftc_t *, int);
 static void isp_pci_wr_reg_2600(ispsoftc_t *, int, uint32_t);
-static int isp_pci_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
-static int isp_pci_rd_isr_2300(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
-static int isp_pci_rd_isr_2400(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
+static void isp_pci_run_isr(ispsoftc_t *);
+static void isp_pci_run_isr_2300(ispsoftc_t *);
+static void isp_pci_run_isr_2400(ispsoftc_t *);
 static int isp_pci_mbxdma(ispsoftc_t *);
 static void isp_pci_mbxdmafree(ispsoftc_t *);
 static int isp_pci_dmasetup(ispsoftc_t *, XS_T *, void *);
@@ -71,7 +71,7 @@ static int isp_pci_irqsetup(ispsoftc_t *
 static void isp_pci_dumpregs(ispsoftc_t *, const char *);
 
 static struct ispmdvec mdvec = {
-	isp_pci_rd_isr,
+	isp_pci_run_isr,
 	isp_pci_rd_reg,
 	isp_pci_wr_reg,
 	isp_pci_mbxdma,
@@ -84,7 +84,7 @@ static struct ispmdvec mdvec = {
 };
 
 static struct ispmdvec mdvec_1080 = {
-	isp_pci_rd_isr,
+	isp_pci_run_isr,
 	isp_pci_rd_reg_1080,
 	isp_pci_wr_reg_1080,
 	isp_pci_mbxdma,
@@ -97,7 +97,7 @@ static struct ispmdvec mdvec_1080 = {
 };
 
 static struct ispmdvec mdvec_12160 = {
-	isp_pci_rd_isr,
+	isp_pci_run_isr,
 	isp_pci_rd_reg_1080,
 	isp_pci_wr_reg_1080,
 	isp_pci_mbxdma,
@@ -110,7 +110,7 @@ static struct ispmdvec mdvec_12160 = {
 };
 
 static struct ispmdvec mdvec_2100 = {
-	isp_pci_rd_isr,
+	isp_pci_run_isr,
 	isp_pci_rd_reg,
 	isp_pci_wr_reg,
 	isp_pci_mbxdma,
@@ -121,7 +121,7 @@ static struct ispmdvec mdvec_2100 = {
 };
 
 static struct ispmdvec mdvec_2200 = {
-	isp_pci_rd_isr,
+	isp_pci_run_isr,
 	isp_pci_rd_reg,
 	isp_pci_wr_reg,
 	isp_pci_mbxdma,
@@ -132,7 +132,7 @@ static struct ispmdvec mdvec_2200 = {
 };
 
 static struct ispmdvec mdvec_2300 = {
-	isp_pci_rd_isr_2300,
+	isp_pci_run_isr_2300,
 	isp_pci_rd_reg,
 	isp_pci_wr_reg,
 	isp_pci_mbxdma,
@@ -143,7 +143,7 @@ static struct ispmdvec mdvec_2300 = {
 };
 
 static struct ispmdvec mdvec_2400 = {
-	isp_pci_rd_isr_2400,
+	isp_pci_run_isr_2400,
 	isp_pci_rd_reg_2400,
 	isp_pci_wr_reg_2400,
 	isp_pci_mbxdma,
@@ -154,7 +154,7 @@ static struct ispmdvec mdvec_2400 = {
 };
 
 static struct ispmdvec mdvec_2500 = {
-	isp_pci_rd_isr_2400,
+	isp_pci_run_isr_2400,
 	isp_pci_rd_reg_2400,
 	isp_pci_wr_reg_2400,
 	isp_pci_mbxdma,
@@ -165,7 +165,7 @@ static struct ispmdvec mdvec_2500 = {
 };
 
 static struct ispmdvec mdvec_2600 = {
-	isp_pci_rd_isr_2400,
+	isp_pci_run_isr_2400,
 	isp_pci_rd_reg_2600,
 	isp_pci_wr_reg_2600,
 	isp_pci_mbxdma,
@@ -1066,35 +1066,27 @@ isp_pci_detach(device_t dev)
 #define	B2R4(isp, off)		bus_read_4((isp)->isp_regs2, (off))
 #define	B2W4(isp, off, v)	bus_write_4((isp)->isp_regs2, (off), (v))
 
-static ISP_INLINE int
-isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp)
+static ISP_INLINE uint16_t
+isp_pci_rd_debounced(ispsoftc_t *isp, int off)
 {
-	uint32_t val0, val1;
-	int i = 0;
+	uint16_t val, prev;
 
+	val = BXR2(isp, IspVirt2Off(isp, off));
 	do {
-		val0 = BXR2(isp, IspVirt2Off(isp, off));
-		val1 = BXR2(isp, IspVirt2Off(isp, off));
-	} while (val0 != val1 && ++i < 1000);
-	if (val0 != val1) {
-		return (1);
-	}
-	*rp = val0;
-	return (0);
+		prev = val;
+		val = BXR2(isp, IspVirt2Off(isp, off));
+	} while (val != prev);
+	return (val);
 }
 
-static int
-isp_pci_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_pci_run_isr(ispsoftc_t *isp)
 {
-	uint16_t isr, sema;
+	uint16_t isr, sema, info;
 
 	if (IS_2100(isp)) {
-		if (isp_pci_rd_debounced(isp, BIU_ISR, &isr)) {
-		    return (0);
-		}
-		if (isp_pci_rd_debounced(isp, BIU_SEMA, &sema)) {
-		    return (0);
-		}
+		isr = isp_pci_rd_debounced(isp, BIU_ISR);
+		sema = isp_pci_rd_debounced(isp, BIU_SEMA);
 	} else {
 		isr = BXR2(isp, IspVirt2Off(isp, BIU_ISR));
 		sema = BXR2(isp, IspVirt2Off(isp, BIU_SEMA));
@@ -1102,59 +1094,61 @@ isp_pci_rd_isr(ispsoftc_t *isp, uint16_t
 	isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
 	isr &= INT_PENDING_MASK(isp);
 	sema &= BIU_SEMA_LOCK;
-	if (isr == 0 && sema == 0) {
-		return (0);
-	}
-	*isrp = isr;
-	if ((*semap = sema) != 0) {
-		if (IS_2100(isp)) {
-			if (isp_pci_rd_debounced(isp, OUTMAILBOX0, info)) {
-				return (0);
-			}
-		} else {
-			*info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
-		}
-	}
-	return (1);
+	if (isr == 0 && sema == 0)
+		return;
+	if (sema != 0) {
+		if (IS_2100(isp))
+			info = isp_pci_rd_debounced(isp, OUTMAILBOX0);
+		else
+			info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
+		if (info & MBOX_COMMAND_COMPLETE)
+			isp_intr_mbox(isp, info);
+		else
+			isp_intr_async(isp, info);
+		if (!IS_FC(isp) && isp->isp_state == ISP_RUNSTATE)
+			isp_intr_respq(isp);
+	} else
+		isp_intr_respq(isp);
+	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+	if (sema)
+		ISP_WRITE(isp, BIU_SEMA, 0);
 }
 
-static int
-isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_pci_run_isr_2300(ispsoftc_t *isp)
 {
 	uint32_t hccr, r2hisr;
+	uint16_t isr, info;
 
-	if ((BXR2(isp, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT) == 0) {
-		*isrp = 0;
-		return (0);
-	}
+	if ((BXR2(isp, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT) == 0)
+		return;
 	r2hisr = BXR4(isp, IspVirt2Off(isp, BIU_R2HSTSLO));
 	isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
-	if ((r2hisr & BIU_R2HST_INTR) == 0) {
-		*isrp = 0;
-		return (0);
-	}
-	switch ((*isrp = r2hisr & BIU_R2HST_ISTAT_MASK)) {
+	if ((r2hisr & BIU_R2HST_INTR) == 0)
+		return;
+	isr = r2hisr & BIU_R2HST_ISTAT_MASK;
+	info = r2hisr >> 16;
+	switch (isr) {
 	case ISPR2HST_ROM_MBX_OK:
 	case ISPR2HST_ROM_MBX_FAIL:
 	case ISPR2HST_MBX_OK:
 	case ISPR2HST_MBX_FAIL:
+		isp_intr_mbox(isp, info);
+		break;
 	case ISPR2HST_ASYNC_EVENT:
-		*semap = 1;
+		isp_intr_async(isp, info);
 		break;
 	case ISPR2HST_RIO_16:
-		*info = ASYNC_RIO16_1;
-		*semap = 1;
-		return (1);
+		isp_intr_async(isp, ASYNC_RIO16_1);
+		break;
 	case ISPR2HST_FPOST:
-		*info = ASYNC_CMD_CMPLT;
-		*semap = 1;
-		return (1);
+		isp_intr_async(isp, ASYNC_CMD_CMPLT);
+		break;
 	case ISPR2HST_FPOST_CTIO:
-		*info = ASYNC_CTIO_DONE;
-		*semap = 1;
-		return (1);
+		isp_intr_async(isp, ASYNC_CTIO_DONE);
+		break;
 	case ISPR2HST_RSPQ_UPDATE:
-		*semap = 0;
+		isp_intr_respq(isp);
 		break;
 	default:
 		hccr = ISP_READ(isp, HCCR);
@@ -1165,45 +1159,52 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uin
 		} else {
 			isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
 		}
-		return (0);
 	}
-	*info = (r2hisr >> 16);
-	return (1);
+	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+	ISP_WRITE(isp, BIU_SEMA, 0);
 }
 
-static int
-isp_pci_rd_isr_2400(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_pci_run_isr_2400(ispsoftc_t *isp)
 {
 	uint32_t r2hisr;
+	uint16_t isr, info;
 
 	r2hisr = BXR4(isp, IspVirt2Off(isp, BIU2400_R2HSTSLO));
 	isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
-	if ((r2hisr & BIU_R2HST_INTR) == 0) {
-		*isrp = 0;
-		return (0);
-	}
-	switch ((*isrp = r2hisr & BIU_R2HST_ISTAT_MASK)) {
+	if ((r2hisr & BIU_R2HST_INTR) == 0)
+		return;
+	isr = r2hisr & BIU_R2HST_ISTAT_MASK;
+	info = (r2hisr >> 16);
+	switch (isr) {
 	case ISPR2HST_ROM_MBX_OK:
 	case ISPR2HST_ROM_MBX_FAIL:
 	case ISPR2HST_MBX_OK:
 	case ISPR2HST_MBX_FAIL:
+		isp_intr_mbox(isp, info);
+		break;
 	case ISPR2HST_ASYNC_EVENT:
-		*semap = 1;
+		isp_intr_async(isp, info);
 		break;
 	case ISPR2HST_RSPQ_UPDATE:
+		isp_intr_respq(isp);
+		break;
 	case ISPR2HST_RSPQ_UPDATE2:
-	case ISPR2HST_ATIO_UPDATE:
+#ifdef	ISP_TARGET_MODE
 	case ISPR2HST_ATIO_RSPQ_UPDATE:
+#endif
+		isp_intr_respq(isp);
+		/* FALLTHROUGH */
+#ifdef	ISP_TARGET_MODE
+	case ISPR2HST_ATIO_UPDATE:
 	case ISPR2HST_ATIO_UPDATE2:
-		*semap = 0;
+		isp_intr_atioq(isp);
+#endif
 		break;
 	default:
-		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
 		isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
-		return (0);
 	}
-	*info = (r2hisr >> 16);
-	return (1);
+	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
 }
 
 static uint32_t

Modified: head/sys/dev/isp/isp_sbus.c
==============================================================================
--- head/sys/dev/isp/isp_sbus.c	Wed Mar 15 14:44:59 2017	(r315306)
+++ head/sys/dev/isp/isp_sbus.c	Wed Mar 15 14:58:29 2017	(r315307)
@@ -53,14 +53,14 @@ __FBSDID("$FreeBSD$");
 
 static uint32_t isp_sbus_rd_reg(ispsoftc_t *, int);
 static void isp_sbus_wr_reg(ispsoftc_t *, int, uint32_t);
-static int isp_sbus_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
+static void isp_sbus_run_isr(ispsoftc_t *);
 static int isp_sbus_mbxdma(ispsoftc_t *);
 static void isp_sbus_mbxdmafree(ispsoftc_t *);
 static int isp_sbus_dmasetup(ispsoftc_t *, XS_T *, void *);
 static void isp_sbus_dumpregs(ispsoftc_t *, const char *);
 
 static struct ispmdvec mdvec = {
-	isp_sbus_rd_isr,
+	isp_sbus_run_isr,
 	isp_sbus_rd_reg,
 	isp_sbus_wr_reg,
 	isp_sbus_mbxdma,
@@ -344,23 +344,31 @@ isp_sbus_detach(device_t dev)
 
 #define	BXR2(isp, off)		bus_read_2((isp)->isp_regs, (off))
 
-static int
-isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
+static void
+isp_sbus_run_isr(ispsoftc_t *isp)
 {
-	uint16_t isr, sema;
+	uint16_t isr, sema, info;
 
 	isr = BXR2(isp, IspVirt2Off(isp, BIU_ISR));
 	sema = BXR2(isp, IspVirt2Off(isp, BIU_SEMA));
 	isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
 	isr &= INT_PENDING_MASK(isp);
 	sema &= BIU_SEMA_LOCK;
-	if (isr == 0 && sema == 0) {
-		return (0);
-	}
-	*isrp = isr;
-	if ((*semap = sema) != 0)
-		*info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
-	return (1);
+	if (isr == 0 && sema == 0)
+		return;
+	if (sema != 0) {
+		info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
+		if (info & MBOX_COMMAND_COMPLETE)
+			isp_intr_mbox(isp, info);
+		else
+			isp_intr_async(isp, info);
+		if (isp->isp_state == ISP_RUNSTATE)
+			isp_intr_respq(isp);
+	} else
+		isp_intr_respq(isp);
+	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+	if (sema)
+		ISP_WRITE(isp, BIU_SEMA, 0);
 }
 
 static uint32_t

Modified: head/sys/dev/isp/ispvar.h
==============================================================================
--- head/sys/dev/isp/ispvar.h	Wed Mar 15 14:44:59 2017	(r315306)
+++ head/sys/dev/isp/ispvar.h	Wed Mar 15 14:58:29 2017	(r315307)
@@ -58,7 +58,7 @@
  */
 typedef struct ispsoftc ispsoftc_t;
 struct ispmdvec {
-	int		(*dv_rd_isr) (ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
+	void		(*dv_run_isr) (ispsoftc_t *);
 	uint32_t	(*dv_rd_reg) (ispsoftc_t *, int);
 	void		(*dv_wr_reg) (ispsoftc_t *, int, uint32_t);
 	int		(*dv_mbxdma) (ispsoftc_t *);
@@ -85,8 +85,8 @@ struct ispmdvec {
  * Macros to access ISP registers through bus specific layers-
  * mostly wrappers to vector through the mdvec structure.
  */
-#define	ISP_READ_ISR(isp, isrp, semap, info)	\
-	(*(isp)->isp_mdvec->dv_rd_isr)(isp, isrp, semap, info)
+#define	ISP_RUN_ISR(isp)	\
+	(*(isp)->isp_mdvec->dv_run_isr)(isp)
 
 #define	ISP_READ(isp, reg)	\
 	(*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg))
@@ -544,18 +544,6 @@ struct ispsoftc {
 	uint32_t		isp_rqstoutrp;	/* register for REQOUTP */
 	uint32_t		isp_respinrp;	/* register for RESINP */
 	uint32_t		isp_respoutrp;	/* register for RESOUTP */
-
-	/*
-	 * Instrumentation
-	 */
-	uint64_t		isp_intcnt;		/* total int count */
-	uint64_t		isp_intbogus;		/* spurious int count */
-	uint64_t		isp_intmboxc;		/* mbox completions */
-	uint64_t		isp_intoasync;		/* other async */
-	uint64_t		isp_rsltccmplt;		/* CMDs on result q */
-	uint64_t		isp_fphccmplt;		/* CMDs via fastpost */
-	uint16_t		isp_rscchiwater;
-	uint16_t		isp_fpcchiwater;
 	NANOTIME_T		isp_init_time;		/* time were last initialized */
 
 	/*
@@ -813,12 +801,13 @@ void isp_shutdown(ispsoftc_t *);
 
 /*
  * Internal Interrupt Service Routine
- *
- * The outer layers do the spade work to get the appropriate status register,
- * semaphore register and first mailbox register (if appropriate). This also
- * means that most spurious/bogus interrupts not for us can be filtered first.
  */
-void isp_intr(ispsoftc_t *, uint16_t, uint16_t, uint16_t);
+#ifdef	ISP_TARGET_MODE
+void isp_intr_atioq(ispsoftc_t *);
+#endif
+void isp_intr_async(ispsoftc_t *, uint16_t event);
+void isp_intr_mbox(ispsoftc_t *, uint16_t mbox0);
+void isp_intr_respq(ispsoftc_t *);
 
 
 /*


More information about the svn-src-head mailing list