/*
 * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
 * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/pci.h>
#include <linux/delay.h>

#include "ipath_kernel.h"
#include "ipath_verbs.h"
#include "ipath_common.h"


/*
 * Called when we might have an error that is specific to a particular
 * PIO buffer, and may need to cancel that buffer, so it can be re-used.
 */
void ipath_disarm_senderrbufs(struct ipath_devdata *dd)
{
	u32 piobcnt;
	unsigned long sbuf[4];
	/*
	 * it's possible that sendbuffererror could have bits set; might
	 * have already done this as a result of hardware error handling
	 */
	piobcnt = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
	/* read these before writing errorclear */
	sbuf[0] = ipath_read_kreg64(
		dd, dd->ipath_kregs->kr_sendbuffererror);
	sbuf[1] = ipath_read_kreg64(
		dd, dd->ipath_kregs->kr_sendbuffererror + 1);
	if (piobcnt > 128)
		sbuf[2] = ipath_read_kreg64(
			dd, dd->ipath_kregs->kr_sendbuffererror + 2);
	if (piobcnt > 192)
		sbuf[3] = ipath_read_kreg64(
			dd, dd->ipath_kregs->kr_sendbuffererror + 3);
	else
		sbuf[3] = 0;

	if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
		int i;
		if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG) &&
			dd->ipath_lastcancel > jiffies) {
			__IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
					  "SendbufErrs %lx %lx", sbuf[0],
					  sbuf[1]);
			if (ipath_debug & __IPATH_PKTDBG && piobcnt > 128)
				printk(" %lx %lx ", sbuf[2], sbuf[3]);
			printk("\n");
		}

		for (i = 0; i < piobcnt; i++)
			if (test_bit(i, sbuf))
				ipath_disarm_piobufs(dd, i, 1);
		/* ignore armlaunch errs for a bit */
		dd->ipath_lastcancel = jiffies+3;
	}
}


/* These are all rcv-related errors which we want to count for stats */
#define E_SUM_PKTERRS \
	(INFINIPATH_E_RHDRLEN | INFINIPATH_E_RBADTID | \
	 INFINIPATH_E_RBADVERSION | INFINIPATH_E_RHDR | \
	 INFINIPATH_E_RLONGPKTLEN | INFINIPATH_E_RSHORTPKTLEN | \
	 INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RMINPKTLEN | \
	 INFINIPATH_E_RFORMATERR | INFINIPATH_E_RUNSUPVL | \
	 INFINIPATH_E_RUNEXPCHAR | INFINIPATH_E_REBP)

/* These are all send-related errors which we want to count for stats */
#define E_SUM_ERRS \
	(INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM | \
	 INFINIPATH_E_SDROPPEDDATAPKT | INFINIPATH_E_SDROPPEDSMPPKT | \
	 INFINIPATH_E_SMAXPKTLEN | INFINIPATH_E_SUNSUPVL | \
	 INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SPKTLEN | \
	 INFINIPATH_E_INVALIDADDR)

/*
 * this is similar to E_SUM_ERRS, but can't ignore armlaunch, don't ignore
 * errors not related to freeze and cancelling buffers.  Can't ignore
 * armlaunch because could get more while still cleaning up, and need
 * to cancel those as they happen.
 */
#define E_SPKT_ERRS_IGNORE \
	 (INFINIPATH_E_SDROPPEDDATAPKT | INFINIPATH_E_SDROPPEDSMPPKT | \
	 INFINIPATH_E_SMAXPKTLEN | INFINIPATH_E_SMINPKTLEN | \
	 INFINIPATH_E_SPKTLEN)

/*
 * these are errors that can occur when the link changes state while
 * a packet is being sent or received.  This doesn't cover things
 * like EBP or VCRC that can be the result of a sending having the
 * link change state, so we receive a "known bad" packet.
 */
#define E_SUM_LINK_PKTERRS \
	(INFINIPATH_E_SDROPPEDDATAPKT | INFINIPATH_E_SDROPPEDSMPPKT | \
	 INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SPKTLEN | \
	 INFINIPATH_E_RSHORTPKTLEN | INFINIPATH_E_RMINPKTLEN | \
	 INFINIPATH_E_RUNEXPCHAR)

static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs)
{
	u64 ignore_this_time = 0;

	ipath_disarm_senderrbufs(dd);
	if ((errs & E_SUM_LINK_PKTERRS) &&
	    !(dd->ipath_flags & IPATH_LINKACTIVE)) {
		/*
		 * This can happen when SMA is trying to bring the link
		 * up, but the IB link changes state at the "wrong" time.
		 * The IB logic then complains that the packet isn't
		 * valid.  We don't want to confuse people, so we just
		 * don't print them, except at debug
		 */
		ipath_dbg("Ignoring packet errors %llx, because link not "
			  "ACTIVE\n", (unsigned long long) errs);
		ignore_this_time = errs & E_SUM_LINK_PKTERRS;
	}

	return ignore_this_time;
}

/* generic hw error messages... */
#define INFINIPATH_HWE_TXEMEMPARITYERR_MSG(a) \
	{ \
		.mask = ( INFINIPATH_HWE_TXEMEMPARITYERR_##a <<    \
			  INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT ),   \
		.msg = "TXE " #a " Memory Parity"	     \
	}
#define INFINIPATH_HWE_RXEMEMPARITYERR_MSG(a) \
	{ \
		.mask = ( INFINIPATH_HWE_RXEMEMPARITYERR_##a <<    \
			  INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT ),   \
		.msg = "RXE " #a " Memory Parity"	     \
	}

static const struct ipath_hwerror_msgs ipath_generic_hwerror_msgs[] = {
	INFINIPATH_HWE_MSG(IBCBUSFRSPCPARITYERR, "IPATH2IB Parity"),
	INFINIPATH_HWE_MSG(IBCBUSTOSPCPARITYERR, "IB2IPATH Parity"),

	INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOBUF),
	INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOPBC),
	INFINIPATH_HWE_TXEMEMPARITYERR_MSG(PIOLAUNCHFIFO),

	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(RCVBUF),
	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(LOOKUPQ),
	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(EAGERTID),
	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(EXPTID),
	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(FLAGBUF),
	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(DATAINFO),
	INFINIPATH_HWE_RXEMEMPARITYERR_MSG(HDRINFO),
};

/**
 * ipath_format_hwmsg - format a single hwerror message
 * @msg message buffer
 * @msgl length of message buffer
 * @hwmsg message to add to message buffer
 */
static void ipath_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
{
	strlcat(msg, "[", msgl);
	strlcat(msg, hwmsg, msgl);
	strlcat(msg, "]", msgl);
}

/**
 * ipath_format_hwerrors - format hardware error messages for display
 * @hwerrs hardware errors bit vector
 * @hwerrmsgs hardware error descriptions
 * @nhwerrmsgs number of hwerrmsgs
 * @msg message buffer
 * @msgl message buffer length
 */
void ipath_format_hwerrors(u64 hwerrs,
			   const struct ipath_hwerror_msgs *hwerrmsgs,
			   size_t nhwerrmsgs,
			   char *msg, size_t msgl)
{
	int i;
	const int glen =
	    sizeof(ipath_generic_hwerror_msgs) /
	    sizeof(ipath_generic_hwerror_msgs[0]);

	for (i=0; i<glen; i++) {
		if (hwerrs & ipath_generic_hwerror_msgs[i].mask) {
			ipath_format_hwmsg(msg, msgl,
					   ipath_generic_hwerror_msgs[i].msg);
		}
	}

	for (i=0; i<nhwerrmsgs; i++) {
		if (hwerrs & hwerrmsgs[i].mask) {
			ipath_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
		}
	}
}

/* return the strings for the most common link states */
static char *ib_linkstate(struct ipath_devdata *dd, u64 ibcs)
{
	char *ret;
	u32 state;

	state = ipath_ib_state(dd, ibcs);
	if (state == dd->ib_init)
		ret = "Init";
	else if (state == dd->ib_arm)
		ret = "Arm";
	else if (state == dd->ib_active)
		ret = "Active";
	else
		ret = "Down";
	return ret;
}

void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev)
{
	struct ib_event event;

	event.device = &dd->verbs_dev->ibdev;
	event.element.port_num = 1;
	event.event = ev;
	ib_dispatch_event(&event);
}

static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
				     ipath_err_t errs)
{
	u32 ltstate, lstate, ibstate, lastlstate;
	u32 init = dd->ib_init;
	u32 arm = dd->ib_arm;
	u32 active = dd->ib_active;
	const u64 ibcs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus);

	lstate = ipath_ib_linkstate(dd, ibcs); /* linkstate */
	ibstate = ipath_ib_state(dd, ibcs);
	/* linkstate at last interrupt */
	lastlstate = ipath_ib_linkstate(dd, dd->ipath_lastibcstat);
	ltstate = ipath_ib_linktrstate(dd, ibcs); /* linktrainingtate */

	/*
	 * Since going into a recovery state causes the link state to go
	 * down and since recovery is transitory, it is better if we "miss"
	 * ever seeing the link training state go into recovery (i.e.,
	 * ignore this transition for link state special handling purposes)
	 * without even updating ipath_lastibcstat.
	 */
	if ((ltstate == INFINIPATH_IBCS_LT_STATE_RECOVERRETRAIN) ||
	    (ltstate == INFINIPATH_IBCS_LT_STATE_RECOVERWAITRMT) ||
	    (ltstate == INFINIPATH_IBCS_LT_STATE_RECOVERIDLE))
		goto done;

	/*
	 * if linkstate transitions into INIT from any of the various down
	 * states, or if it transitions from any of the up (INIT or better)
	 * states into any of the down states (except link recovery), then
	 * call the chip-specific code to take appropriate actions.
	 */
	if (lstate >= INFINIPATH_IBCS_L_STATE_INIT &&
		lastlstate == INFINIPATH_IBCS_L_STATE_DOWN) {
		/* transitioned to UP */
		if (dd->ipath_f_ib_updown(dd, 1, ibcs)) {
			/* link came up, so we must no longer be disabled */
			dd->ipath_flags &= ~IPATH_IB_LINK_DISABLED;
			ipath_cdbg(LINKVERB, "LinkUp handled, skipped\n");
			goto skip_ibchange; /* chip-code handled */
		}
	} else if ((lastlstate >= INFINIPATH_IBCS_L_STATE_INIT ||
		(dd->ipath_flags & IPATH_IB_FORCE_NOTIFY)) &&
		ltstate <= INFINIPATH_IBCS_LT_STATE_CFGWAITRMT &&
		ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) {
		int handled;
		handled = dd->ipath_f_ib_updown(dd, 0, ibcs);
		dd->ipath_flags &= ~IPATH_IB_FORCE_NOTIFY;
		if (handled) {
			ipath_cdbg(LINKVERB, "LinkDown handled, skipped\n");
			goto skip_ibchange; /* chip-code handled */
		}
	}

	/*
	 * Significant enough to always print and get into logs, if it was
	 * unexpected.  If it was a requested state change, we'll have
	 * already cleared the flags, so we won't print this warning
	 */
	if ((ibstate != arm && ibstate != active) &&
	    (dd->ipath_flags & (IPATH_LINKARMED | IPATH_LINKACTIVE))) {
		dev_info(&dd->pcidev->dev, "Link state changed from %s "
			 "to %s\n", (dd->ipath_flags & IPATH_LINKARMED) ?
			 "ARM" : "ACTIVE", ib_linkstate(dd, ibcs));
	}

	if (ltstate == INFINIPATH_IBCS_LT_STATE_POLLACTIVE ||
	    ltstate == INFINIPATH_IBCS_LT_STATE_POLLQUIET) {
		u32 lastlts;
		lastlts = ipath_ib_linktrstate(dd, dd->ipath_lastibcstat);
		/*
		 * Ignore cycling back and forth from Polling.Active to
		 * Polling.Quiet while waiting for the other end of the link
		 * to come up, except to try and decide if we are connected
		 * to a live IB device or not.  We will cycle back and
		 * forth between them if no cable is plugged in, the other
		 * device is powered off or disabled, etc.
		 */
		if (lastlts == INFINIPATH_IBCS_LT_STATE_POLLACTIVE ||
		    lastlts == INFINIPATH_IBCS_LT_STATE_POLLQUIET) {
			if (!(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) &&
			     (++dd->ipath_ibpollcnt == 40)) {
				dd->ipath_flags |= IPATH_NOCABLE;
				*dd->ipath_statusp |=
					IPATH_STATUS_IB_NOCABLE;
				ipath_cdbg(LINKVERB, "Set NOCABLE\n");
			}
			ipath_cdbg(LINKVERB, "POLL change to %s (%x)\n",
				ipath_ibcstatus_str[ltstate], ibstate);
			goto skip_ibchange;
		}
	}

	dd->ipath_ibpollcnt = 0; /* not poll*, now */
	ipath_stats.sps_iblink++;

	if (ibstate != init && dd->ipath_lastlinkrecov && ipath_linkrecovery) {
		u64 linkrecov;
		linkrecov = ipath_snap_cntr(dd,
			dd->ipath_cregs->cr_iblinkerrrecovcnt);
		if (linkrecov != dd->ipath_lastlinkrecov) {
			ipath_dbg("IB linkrecov up %Lx (%s %s) recov %Lu\n",
				(unsigned long long) ibcs,
				ib_linkstate(dd, ibcs),
				ipath_ibcstatus_str[ltstate],
				(unsigned long long) linkrecov);
			/* and no more until active again */
			dd->ipath_lastlinkrecov = 0;
			ipath_set_linkstate(dd, IPATH_IB_LINKDOWN);
			goto skip_ibchange;
		}
	}

	if (ibstate == init || ibstate == arm || ibstate == active) {
		*dd->ipath_statusp &= ~IPATH_STATUS_IB_NOCABLE;
		if (ibstate == init || ibstate == arm) {
			*dd->ipath_statusp &= ~IPATH_STATUS_IB_READY;
			if (dd->ipath_flags & IPATH_LINKACTIVE)
				signal_ib_event(dd, IB_EVENT_PORT_ERR);
		}
		if (ibstate == arm) {
			dd->ipath_flags |= IPATH_LINKARMED;
			dd->ipath_flags &= ~(IPATH_LINKUNK |
				IPATH_LINKINIT | IPATH_LINKDOWN |
				IPATH_LINKACTIVE | IPATH_NOCABLE);
			ipath_hol_down(dd);
		} else  if (ibstate == init) {
			/*
			 * set INIT and DOWN.  Down is checked by
			 * most of the other code, but INIT is
			 * useful to know in a few places.
			 */
			dd->ipath_flags |= IPATH_LINKINIT |
				IPATH_LINKDOWN;
			dd->ipath_flags &= ~(IPATH_LINKUNK |
				IPATH_LINKARMED | IPATH_LINKACTIVE |
				IPATH_NOCABLE);
			ipath_hol_down(dd);
		} else {  /* active */
			dd->ipath_lastlinkrecov = ipath_snap_cntr(dd,
				dd->ipath_cregs->cr_iblinkerrrecovcnt);
			*dd->ipath_statusp |=
				IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF;
			dd->ipath_flags |= IPATH_LINKACTIVE;
			dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT
				| IPATH_LINKDOWN | IPATH_LINKARMED |
				IPATH_NOCABLE);
			if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
				ipath_restart_sdma(dd);
			signal_ib_event(dd, IB_EVENT_PORT_ACTIVE);
			/* LED active not handled in chip _f_updown */
			dd->ipath_f_setextled(dd, lstate, ltstate);
			ipath_hol_up(dd);
		}

		/*
		 * print after we've already done the work, so as not to
		 * delay the state changes and notifications, for debugging
		 */
		if (lstate == lastlstate)
			ipath_cdbg(LINKVERB, "Unchanged from last: %s "
				"(%x)\n", ib_linkstate(dd, ibcs), ibstate);
		else
			ipath_cdbg(VERBOSE, "Unit %u: link up to %s %s (%x)\n",
				  dd->ipath_unit, ib_linkstate(dd, ibcs),
				  ipath_ibcstatus_str[ltstate],  ibstate);
	} else { /* down */
		if (dd->ipath_flags & IPATH_LINKACTIVE)
			signal_ib_event(dd, IB_EVENT_PORT_ERR);
		dd->ipath_flags |= IPATH_LINKDOWN;
		dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT
				     | IPATH_LINKACTIVE |
				     IPATH_LINKARMED);
		*dd->ipath_statusp &= ~IPATH_STATUS_IB_READY;
		dd->ipath_lli_counter = 0;

		if (lastlstate != INFINIPATH_IBCS_L_STATE_DOWN)
			ipath_cdbg(VERBOSE, "Unit %u link state down "
				   "(state 0x%x), from %s\n",
				   dd->ipath_unit, lstate,
				   ib_linkstate(dd, dd->ipath_lastibcstat));
		else
			ipath_cdbg(LINKVERB, "Unit %u link state changed "
				   "to %s (0x%x) from down (%x)\n",
				   dd->ipath_unit,
				   ipath_ibcstatus_str[ltstate],
				   ibstate, lastlstate);
	}

skip_ibchange:
	dd->ipath_lastibcstat = ibcs;
done:
	return;
}

static void handle_supp_msgs(struct ipath_devdata *dd,
			     unsigned supp_msgs, char *msg, u32 msgsz)
{
	/*
	 * Print the message unless it's ibc status change only, which
	 * happens so often we never want to count it.
	 */
	if (dd->ipath_lasterror & ~INFINIPATH_E_IBSTATUSCHANGED) {
		int iserr;
		ipath_err_t mask;
		iserr = ipath_decode_err(dd, msg, msgsz,
					 dd->ipath_lasterror &
					 ~INFINIPATH_E_IBSTATUSCHANGED);

		mask = INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL |
			INFINIPATH_E_PKTERRS | INFINIPATH_E_SDMADISABLED;

		/* if we're in debug, then don't mask SDMADISABLED msgs */
		if (ipath_debug & __IPATH_DBG)
			mask &= ~INFINIPATH_E_SDMADISABLED;

		if (dd->ipath_lasterror & ~mask)
			ipath_dev_err(dd, "Suppressed %u messages for "
				      "fast-repeating errors (%s) (%llx)\n",
				      supp_msgs, msg,
				      (unsigned long long)
				      dd->ipath_lasterror);
		else {
			/*
			 * rcvegrfull and rcvhdrqfull are "normal", for some
			 * types of processes (mostly benchmarks) that send
			 * huge numbers of messages, while not processing
			 * them. So only complain about these at debug
			 * level.
			 */
			if (iserr)
				ipath_dbg("Suppressed %u messages for %s\n",
					  supp_msgs, msg);
			else
				ipath_cdbg(ERRPKT,
					"Suppressed %u messages for %s\n",
					  supp_msgs, msg);
		}
	}
}

static unsigned handle_frequent_errors(struct ipath_devdata *dd,
				       ipath_err_t errs, char *msg,
				       u32 msgsz, int *noprint)
{
	unsigned long nc;
	static unsigned long nextmsg_time;
	static unsigned nmsgs, supp_msgs;

	/*
	 * Throttle back "fast" messages to no more than 10 per 5 seconds.
	 * This isn't perfect, but it's a reasonable heuristic. If we get
	 * more than 10, give a 6x longer delay.
	 */
	nc = jiffies;
	if (nmsgs > 10) {
		if (time_before(nc, nextmsg_time)) {
			*noprint = 1;
			if (!supp_msgs++)
				nextmsg_time = nc + HZ * 3;
		}
		else if (supp_msgs) {
			handle_supp_msgs(dd, supp_msgs, msg, msgsz);
			supp_msgs = 0;
			nmsgs = 0;
		}
	}
	else if (!nmsgs++ || time_after(nc, nextmsg_time))
		nextmsg_time = nc + HZ / 2;

	return supp_msgs;
}

static void handle_sdma_errors(struct ipath_devdata *dd, ipath_err_t errs)
{
	unsigned long flags;
	int expected;

	if (ipath_debug & __IPATH_DBG) {
		char msg[128];
		ipath_decode_err(dd, msg, sizeof msg, errs &
			INFINIPATH_E_SDMAERRS);
		ipath_dbg("errors %lx (%s)\n", (unsigned long)errs, msg);
	}
	if (ipath_debug & __IPATH_VERBDBG) {
		unsigned long tl, hd, status, lengen;
		tl = ipath_read_kreg64(dd, dd->ipath_kregs->kr_senddmatail);
		hd = ipath_read_kreg64(dd, dd->ipath_kregs->kr_senddmahead);
		status = ipath_read_kreg64(dd
			, dd->ipath_kregs->kr_senddmastatus);
		lengen = ipath_read_kreg64(dd,
			dd->ipath_kregs->kr_senddmalengen);
		ipath_cdbg(VERBOSE, "sdma tl 0x%lx hd 0x%lx status 0x%lx "
			"lengen 0x%lx\n", tl, hd, status, lengen);
	}

	spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
	__set_bit(IPATH_SDMA_DISABLED, &dd->ipath_sdma_status);
	expected = test_bit(IPATH_SDMA_ABORTING, &dd->ipath_sdma_status);
	spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
	if (!expected)
		ipath_cancel_sends(dd, 1);
}

static void handle_sdma_intr(struct ipath_devdata *dd, u64 istat)
{
	unsigned long flags;
	int expected;

	if ((istat & INFINIPATH_I_SDMAINT) &&
	    !test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
		ipath_sdma_intr(dd);

	if (istat & INFINIPATH_I_SDMADISABLED) {
		expected = test_bit(IPATH_SDMA_ABORTING,
			&dd->ipath_sdma_status);
		ipath_dbg("%s SDmaDisabled intr\n",
			expected ? "expected" : "unexpected");
		spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
		__set_bit(IPATH_SDMA_DISABLED, &dd->ipath_sdma_status);
		spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
		if (!expected)
			ipath_cancel_sends(dd, 1);
		if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
			tasklet_hi_schedule(&dd->ipath_sdma_abort_task);
	}
}

static int handle_hdrq_full(struct ipath_devdata *dd)
{
	int chkerrpkts = 0;
	u32 hd, tl;
	u32 i;

	ipath_stats.sps_hdrqfull++;
	for (i = 0; i < dd->ipath_cfgports; i++) {
		struct ipath_portdata *pd = dd->ipath_pd[i];

		if (i == 0) {
			/*
			 * For kernel receive queues, we just want to know
			 * if there are packets in the queue that we can
			 * process.
			 */
			if (pd->port_head != ipath_get_hdrqtail(pd))
				chkerrpkts |= 1 << i;
			continue;
		}

		/* Skip if user context is not open */
		if (!pd || !pd->port_cnt)
			continue;

		/* Don't report the same point multiple times. */
		if (dd->ipath_flags & IPATH_NODMA_RTAIL)
			tl = ipath_read_ureg32(dd, ur_rcvhdrtail, i);
		else
			tl = ipath_get_rcvhdrtail(pd);
		if (tl == pd->port_lastrcvhdrqtail)
			continue;

		hd = ipath_read_ureg32(dd, ur_rcvhdrhead, i);
		if (hd == (tl + 1) || (!hd && tl == dd->ipath_hdrqlast)) {
			pd->port_lastrcvhdrqtail = tl;
			pd->port_hdrqfull++;
			/* flush hdrqfull so that poll() sees it */
			wmb();
			wake_up_interruptible(&pd->port_wait);
		}
	}

	return chkerrpkts;
}

static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
{
	char msg[128];
	u64 ignore_this_time = 0;
	u64 iserr = 0;
	int chkerrpkts = 0, noprint = 0;
	unsigned supp_msgs;
	int log_idx;

	/*
	 * don't report errors that are masked, either at init
	 * (not set in ipath_errormask), or temporarily (set in
	 * ipath_maskederrs)
	 */
	errs &= dd->ipath_errormask & ~dd->ipath_maskederrs;

	supp_msgs = handle_frequent_errors(dd, errs, msg, (u32)sizeof msg,
		&noprint);

	/* do these first, they are most important */
	if (errs & INFINIPATH_E_HARDWARE) {
		/* reuse same msg buf */
		dd->ipath_f_handle_hwerrors(dd, msg, sizeof msg);
	} else {
		u64 mask;
		for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx) {
			mask = dd->ipath_eep_st_masks[log_idx].errs_to_log;
			if (errs & mask)
				ipath_inc_eeprom_err(dd, log_idx, 1);
		}
	}

	if (errs & INFINIPATH_E_SDMAERRS)
		handle_sdma_errors(dd, errs);

	if (!noprint && (errs & ~dd->ipath_e_bitsextant))
		ipath_dev_err(dd, "error interrupt with unknown errors "
			      "%llx set\n", (unsigned long long)
			      (errs & ~dd->ipath_e_bitsextant));

	if (errs & E_SUM_ERRS)
		ignore_this_time = handle_e_sum_errs(dd, errs);
	else if ((errs & E_SUM_LINK_PKTERRS) &&
	    !(dd->ipath_flags & IPATH_LINKACTIVE)) {
		/*
		 * This can happen when SMA is trying to bring the link
		 * up, but the IB link changes state at the "wrong" time.
		 * The IB logic then complains that the packet isn't
		 * valid.  We don't want to confuse people, so we just
		 * don't print them, except at debug
		 */
		ipath_dbg("Ignoring packet errors %llx, because link not "
			  "ACTIVE\n", (unsigned long long) errs);
		ignore_this_time = errs & E_SUM_LINK_PKTERRS;
	}

	if (supp_msgs == 250000) {
		int s_iserr;
		/*
		 * It's not entirely reasonable assuming that the errors set
		 * in the last clear period are all responsible for the
		 * problem, but the alternative is to assume it's the only
		 * ones on this particular interrupt, which also isn't great
		 */
		dd->ipath_maskederrs |= dd->ipath_lasterror | errs;

		dd->ipath_errormask &= ~dd->ipath_maskederrs;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
				 dd->ipath_errormask);
		s_iserr = ipath_decode_err(dd, msg, sizeof msg,
					   dd->ipath_maskederrs);

		if (dd->ipath_maskederrs &
		    ~(INFINIPATH_E_RRCVEGRFULL |
		      INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS))
			ipath_dev_err(dd, "Temporarily disabling "
			    "error(s) %llx reporting; too frequent (%s)\n",
				(unsigned long long) dd->ipath_maskederrs,
				msg);
		else {
			/*
			 * rcvegrfull and rcvhdrqfull are "normal",
			 * for some types of processes (mostly benchmarks)
			 * that send huge numbers of messages, while not
			 * processing them.  So only complain about
			 * these at debug level.
			 */
			if (s_iserr)
				ipath_dbg("Temporarily disabling reporting "
				    "too frequent queue full errors (%s)\n",
				    msg);
			else
				ipath_cdbg(ERRPKT,
				    "Temporarily disabling reporting too"
				    " frequent packet errors (%s)\n",
				    msg);
		}

		/*
		 * Re-enable the masked errors after around 3 minutes.  in
		 * ipath_get_faststats().  If we have a series of fast
		 * repeating but different errors, the interval will keep
		 * stretching out, but that's OK, as that's pretty
		 * catastrophic.
		 */
		dd->ipath_unmasktime = jiffies + HZ * 180;
	}

	ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, errs);
	if (ignore_this_time)
		errs &= ~ignore_this_time;
	if (errs & ~dd->ipath_lasterror) {
		errs &= ~dd->ipath_lasterror;
		/* never suppress duplicate hwerrors or ibstatuschange */
		dd->ipath_lasterror |= errs &
			~(INFINIPATH_E_HARDWARE |
			  INFINIPATH_E_IBSTATUSCHANGED);
	}

	if (errs & INFINIPATH_E_SENDSPECIALTRIGGER) {
		dd->ipath_spectriggerhit++;
		ipath_dbg("%lu special trigger hits\n",
			dd->ipath_spectriggerhit);
	}

	/* likely due to cancel; so suppress message unless verbose */
	if ((errs & (INFINIPATH_E_SPKTLEN | INFINIPATH_E_SPIOARMLAUNCH)) &&
		dd->ipath_lastcancel > jiffies) {
		/* armlaunch takes precedence; it often causes both. */
		ipath_cdbg(VERBOSE,
			"Suppressed %s error (%llx) after sendbuf cancel\n",
			(errs &  INFINIPATH_E_SPIOARMLAUNCH) ?
			"armlaunch" : "sendpktlen", (unsigned long long)errs);
		errs &= ~(INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SPKTLEN);
	}

	if (!errs)
		return 0;

	if (!noprint) {
		ipath_err_t mask;
		/*
		 * The ones we mask off are handled specially below
		 * or above.  Also mask SDMADISABLED by default as it
		 * is too chatty.
		 */
		mask = INFINIPATH_E_IBSTATUSCHANGED |
			INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL |
			INFINIPATH_E_HARDWARE | INFINIPATH_E_SDMADISABLED;

		/* if we're in debug, then don't mask SDMADISABLED msgs */
		if (ipath_debug & __IPATH_DBG)
			mask &= ~INFINIPATH_E_SDMADISABLED;

		ipath_decode_err(dd, msg, sizeof msg, errs & ~mask);
	} else
		/* so we don't need if (!noprint) at strlcat's below */
		*msg = 0;

	if (errs & E_SUM_PKTERRS) {
		ipath_stats.sps_pkterrs++;
		chkerrpkts = 1;
	}
	if (errs & E_SUM_ERRS)
		ipath_stats.sps_errs++;

	if (errs & (INFINIPATH_E_RICRC | INFINIPATH_E_RVCRC)) {
		ipath_stats.sps_crcerrs++;
		chkerrpkts = 1;
	}
	iserr = errs & ~(E_SUM_PKTERRS | INFINIPATH_E_PKTERRS);


	/*
	 * We don't want to print these two as they happen, or we can make
	 * the situation even worse, because it takes so long to print
	 * messages to serial consoles.  Kernel ports get printed from
	 * fast_stats, no more than every 5 seconds, user ports get printed
	 * on close
	 */
	if (errs & INFINIPATH_E_RRCVHDRFULL)
		chkerrpkts |= handle_hdrq_full(dd);
	if (errs & INFINIPATH_E_RRCVEGRFULL) {
		struct ipath_portdata *pd = dd->ipath_pd[0];

		/*
		 * since this is of less importance and not likely to
		 * happen without also getting hdrfull, only count
		 * occurrences; don't check each port (or even the kernel
		 * vs user)
		 */
		ipath_stats.sps_etidfull++;
		if (pd->port_head != ipath_get_hdrqtail(pd))
			chkerrpkts |= 1;
	}

	/*
	 * do this before IBSTATUSCHANGED, in case both bits set in a single
	 * interrupt; we want the STATUSCHANGE to "win", so we do our
	 * internal copy of state machine correctly
	 */
	if (errs & INFINIPATH_E_RIBLOSTLINK) {
		/*
		 * force through block below
		 */
		errs |= INFINIPATH_E_IBSTATUSCHANGED;
		ipath_stats.sps_iblink++;
		dd->ipath_flags |= IPATH_LINKDOWN;
		dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT
				     | IPATH_LINKARMED | IPATH_LINKACTIVE);
		*dd->ipath_statusp &= ~IPATH_STATUS_IB_READY;

		ipath_dbg("Lost link, link now down (%s)\n",
			ipath_ibcstatus_str[ipath_read_kreg64(dd,
			dd->ipath_kregs->kr_ibcstatus) & 0xf]);
	}
	if (errs & INFINIPATH_E_IBSTATUSCHANGED)
		handle_e_ibstatuschanged(dd, errs);

	if (errs & INFINIPATH_E_RESET) {
		if (!noprint)
			ipath_dev_err(dd, "Got reset, requires re-init "
				      "(unload and reload driver)\n");
		dd->ipath_flags &= ~IPATH_INITTED;	/* needs re-init */
		/* mark as having had error */
		*dd->ipath_statusp |= IPATH_STATUS_HWERROR;
		*dd->ipath_statusp &= ~IPATH_STATUS_IB_CONF;
	}

	if (!noprint && *msg) {
		if (iserr)
			ipath_dev_err(dd, "%s error\n", msg);
	}
	if (dd->ipath_state_wanted & dd->ipath_flags) {
		ipath_cdbg(VERBOSE, "driver wanted state %x, iflags now %x, "
			   "waking\n", dd->ipath_state_wanted,
			   dd->ipath_flags);
		wake_up_interruptible(&ipath_state_wait);
	}

	return chkerrpkts;
}

/*
 * try to cleanup as much as possible for anything that might have gone
 * wrong while in freeze mode, such as pio buffers being written by user
 * processes (causing armlaunch), send errors due to going into freeze mode,
 * etc., and try to avoid causing extra interrupts while doing so.
 * Forcibly update the in-memory pioavail register copies after cleanup
 * because the chip won't do it while in freeze mode (the register values
 * themselves are kept correct).
 * Make sure that we don't lose any important interrupts by using the chip
 * feature that says that writing 0 to a bit in *clear that is set in
 * *status will cause an interrupt to be generated again (if allowed by
 * the *mask value).
 */
void ipath_clear_freeze(struct ipath_devdata *dd)
{
	/* disable error interrupts, to avoid confusion */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL);

	/* also disable interrupts; errormask is sometimes overwriten */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL);

	ipath_cancel_sends(dd, 1);

	/* clear the freeze, and be sure chip saw it */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
			 dd->ipath_control);
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);

	/* force in-memory update now we are out of freeze */
	ipath_force_pio_avail_update(dd);

	/*
	 * force new interrupt if any hwerr, error or interrupt bits are
	 * still set, and clear "safe" send packet errors related to freeze
	 * and cancelling sends.  Re-enable error interrupts before possible
	 * force of re-interrupt on pending interrupts.
	 */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, 0ULL);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear,
		E_SPKT_ERRS_IGNORE);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
		dd->ipath_errormask);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, -1LL);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL);
}


/* this is separate to allow for better optimization of ipath_intr() */

static noinline void ipath_bad_intr(struct ipath_devdata *dd, u32 *unexpectp)
{
	/*
	 * sometimes happen during driver init and unload, don't want
	 * to process any interrupts at that point
	 */

	/* this is just a bandaid, not a fix, if something goes badly
	 * wrong */
	if (++*unexpectp > 100) {
		if (++*unexpectp > 105) {
			/*
			 * ok, we must be taking somebody else's interrupts,
			 * due to a messed up mptable and/or PIRQ table, so
			 * unregister the interrupt.  We've seen this during
			 * linuxbios development work, and it may happen in
			 * the future again.
			 */
			if (dd->pcidev && dd->ipath_irq) {
				ipath_dev_err(dd, "Now %u unexpected "
					      "interrupts, unregistering "
					      "interrupt handler\n",
					      *unexpectp);
				ipath_dbg("free_irq of irq %d\n",
					  dd->ipath_irq);
				dd->ipath_f_free_irq(dd);
			}
		}
		if (ipath_read_ireg(dd, dd->ipath_kregs->kr_intmask)) {
			ipath_dev_err(dd, "%u unexpected interrupts, "
				      "disabling interrupts completely\n",
				      *unexpectp);
			/*
			 * disable all interrupts, something is very wrong
			 */
			ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask,
					 0ULL);
		}
	} else if (*unexpectp > 1)
		ipath_dbg("Interrupt when not ready, should not happen, "
			  "ignoring\n");
}

static noinline void ipath_bad_regread(struct ipath_devdata *dd)
{
	static int allbits;

	/* separate routine, for better optimization of ipath_intr() */

	/*
	 * We print the message and disable interrupts, in hope of
	 * having a better chance of debugging the problem.
	 */
	ipath_dev_err(dd,
		      "Read of interrupt status failed (all bits set)\n");
	if (allbits++) {
		/* disable all interrupts, something is very wrong */
		ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL);
		if (allbits == 2) {
			ipath_dev_err(dd, "Still bad interrupt status, "
				      "unregistering interrupt\n");
			dd->ipath_f_free_irq(dd);
		} else if (allbits > 2) {
			if ((allbits % 10000) == 0)
				printk(".");
		} else
			ipath_dev_err(dd, "Disabling interrupts, "
				      "multiple errors\n");
	}
}

static void handle_layer_pioavail(struct ipath_devdata *dd)
{
	unsigned long flags;
	int ret;

	ret = ipath_ib_piobufavail(dd->verbs_dev);
	if (ret > 0)
		goto set;

	return;
set:
	spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
	dd->ipath_sendctrl |= INFINIPATH_S_PIOINTBUFAVAIL;
	ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
			 dd->ipath_sendctrl);
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
	spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
}

/*
 * Handle receive interrupts for user ports; this means a user
 * process was waiting for a packet to arrive, and didn't want
 * to poll
 */
static void handle_urcv(struct ipath_devdata *dd, u64 istat)
{
	u64 portr;
	int i;
	int rcvdint = 0;

	/*
	 * test_and_clear_bit(IPATH_PORT_WAITING_RCV) and
	 * test_and_clear_bit(IPATH_PORT_WAITING_URG) below
	 * would both like timely updates of the bits so that
	 * we don't pass them by unnecessarily.  the rmb()
	 * here ensures that we see them promptly -- the
	 * corresponding wmb()'s are in ipath_poll_urgent()
	 * and ipath_poll_next()...
	 */
	rmb();
	portr = ((istat >> dd->ipath_i_rcvavail_shift) &
		 dd->ipath_i_rcvavail_mask) |
		((istat >> dd->ipath_i_rcvurg_shift) &
		 dd->ipath_i_rcvurg_mask);
	for (i = 1; i < dd->ipath_cfgports; i++) {
		struct ipath_portdata *pd = dd->ipath_pd[i];

		if (portr & (1 << i) && pd && pd->port_cnt) {
			if (test_and_clear_bit(IPATH_PORT_WAITING_RCV,
					       &pd->port_flag)) {
				clear_bit(i + dd->ipath_r_intravail_shift,
					  &dd->ipath_rcvctrl);
				wake_up_interruptible(&pd->port_wait);
				rcvdint = 1;
			} else if (test_and_clear_bit(IPATH_PORT_WAITING_URG,
						      &pd->port_flag)) {
				pd->port_urgent++;
				wake_up_interruptible(&pd->port_wait);
			}
		}
	}
	if (rcvdint) {
		/* only want to take one interrupt, so turn off the rcv
		 * interrupt for all the ports that we set the rcv_waiting
		 * (but never for kernel port)
		 */
		ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
				 dd->ipath_rcvctrl);
	}
}

irqreturn_t ipath_intr(int irq, void *data)
{
	struct ipath_devdata *dd = data;
	u64 istat, chk0rcv = 0;
	ipath_err_t estat = 0;
	irqreturn_t ret;
	static unsigned unexpected = 0;
	u64 kportrbits;

	ipath_stats.sps_ints++;

	if (dd->ipath_int_counter != (u32) -1)
		dd->ipath_int_counter++;

	if (!(dd->ipath_flags & IPATH_PRESENT)) {
		/*
		 * This return value is not great, but we do not want the
		 * interrupt core code to remove our interrupt handler
		 * because we don't appear to be handling an interrupt
		 * during a chip reset.
		 */
		return IRQ_HANDLED;
	}

	/*
	 * this needs to be flags&initted, not statusp, so we keep
	 * taking interrupts even after link goes down, etc.
	 * Also, we *must* clear the interrupt at some point, or we won't
	 * take it again, which can be real bad for errors, etc...
	 */

	if (!(dd->ipath_flags & IPATH_INITTED)) {
		ipath_bad_intr(dd, &unexpected);
		ret = IRQ_NONE;
		goto bail;
	}

	istat = ipath_read_ireg(dd, dd->ipath_kregs->kr_intstatus);

	if (unlikely(!istat)) {
		ipath_stats.sps_nullintr++;
		ret = IRQ_NONE; /* not our interrupt, or already handled */
		goto bail;
	}
	if (unlikely(istat == -1)) {
		ipath_bad_regread(dd);
		/* don't know if it was our interrupt or not */
		ret = IRQ_NONE;
		goto bail;
	}

	if (unexpected)
		unexpected = 0;

	if (unlikely(istat & ~dd->ipath_i_bitsextant))
		ipath_dev_err(dd,
			      "interrupt with unknown interrupts %Lx set\n",
			      (unsigned long long)
			      istat & ~dd->ipath_i_bitsextant);
	else if (istat & ~INFINIPATH_I_ERROR) /* errors do own printing */
		ipath_cdbg(VERBOSE, "intr stat=0x%Lx\n",
			(unsigned long long) istat);

	if (istat & INFINIPATH_I_ERROR) {
		ipath_stats.sps_errints++;
		estat = ipath_read_kreg64(dd,
					  dd->ipath_kregs->kr_errorstatus);
		if (!estat)
			dev_info(&dd->pcidev->dev, "error interrupt (%Lx), "
				 "but no error bits set!\n",
				 (unsigned long long) istat);
		else if (estat == -1LL)
			/*
			 * should we try clearing all, or hope next read
			 * works?
			 */
			ipath_dev_err(dd, "Read of error status failed "
				      "(all bits set); ignoring\n");
		else
			chk0rcv |= handle_errors(dd, estat);
	}

	if (istat & INFINIPATH_I_GPIO) {
		/*
		 * GPIO interrupts fall in two broad classes:
		 * GPIO_2 indicates (on some HT4xx boards) that a packet
		 *        has arrived for Port 0. Checking for this
		 *        is controlled by flag IPATH_GPIO_INTR.
		 * GPIO_3..5 on IBA6120 Rev2 and IBA6110 Rev4 chips indicate
		 *        errors that we need to count. Checking for this
		 *        is controlled by flag IPATH_GPIO_ERRINTRS.
		 */
		u32 gpiostatus;
		u32 to_clear = 0;

		gpiostatus = ipath_read_kreg32(
			dd, dd->ipath_kregs->kr_gpio_status);
		/* First the error-counter case. */
		if ((gpiostatus & IPATH_GPIO_ERRINTR_MASK) &&
		    (dd->ipath_flags & IPATH_GPIO_ERRINTRS)) {
			/* want to clear the bits we see asserted. */
			to_clear |= (gpiostatus & IPATH_GPIO_ERRINTR_MASK);

			/*
			 * Count appropriately, clear bits out of our copy,
			 * as they have been "handled".
			 */
			if (gpiostatus & (1 << IPATH_GPIO_RXUVL_BIT)) {
				ipath_dbg("FlowCtl on UnsupVL\n");
				dd->ipath_rxfc_unsupvl_errs++;
			}
			if (gpiostatus & (1 << IPATH_GPIO_OVRUN_BIT)) {
				ipath_dbg("Overrun Threshold exceeded\n");
				dd->ipath_overrun_thresh_errs++;
			}
			if (gpiostatus & (1 << IPATH_GPIO_LLI_BIT)) {
				ipath_dbg("Local Link Integrity error\n");
				dd->ipath_lli_errs++;
			}
			gpiostatus &= ~IPATH_GPIO_ERRINTR_MASK;
		}
		/* Now the Port0 Receive case */
		if ((gpiostatus & (1 << IPATH_GPIO_PORT0_BIT)) &&
		    (dd->ipath_flags & IPATH_GPIO_INTR)) {
			/*
			 * GPIO status bit 2 is set, and we expected it.
			 * clear it and indicate in p0bits.
			 * This probably only happens if a Port0 pkt
			 * arrives at _just_ the wrong time, and we
			 * handle that by seting chk0rcv;
			 */
			to_clear |= (1 << IPATH_GPIO_PORT0_BIT);
			gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT);
			chk0rcv = 1;
		}
		if (gpiostatus) {
			/*
			 * Some unexpected bits remain. If they could have
			 * caused the interrupt, complain and clear.
			 * To avoid repetition of this condition, also clear
			 * the mask. It is almost certainly due to error.
			 */
			const u32 mask = (u32) dd->ipath_gpio_mask;

			if (mask & gpiostatus) {
				ipath_dbg("Unexpected GPIO IRQ bits %x\n",
				  gpiostatus & mask);
				to_clear |= (gpiostatus & mask);
				dd->ipath_gpio_mask &= ~(gpiostatus & mask);
				ipath_write_kreg(dd,
					dd->ipath_kregs->kr_gpio_mask,
					dd->ipath_gpio_mask);
			}
		}
		if (to_clear) {
			ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
					(u64) to_clear);
		}
	}

	/*
	 * Clear the interrupt bits we found set, unless they are receive
	 * related, in which case we already cleared them above, and don't
	 * want to clear them again, because we might lose an interrupt.
	 * Clear it early, so we "know" know the chip will have seen this by
	 * the time we process the queue, and will re-interrupt if necessary.
	 * The processor itself won't take the interrupt again until we return.
	 */
	ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);

	/*
	 * Handle kernel receive queues before checking for pio buffers
	 * available since receives can overflow; piobuf waiters can afford
	 * a few extra cycles, since they were waiting anyway, and user's
	 * waiting for receive are at the bottom.
	 */
	kportrbits = (1ULL << dd->ipath_i_rcvavail_shift) |
		(1ULL << dd->ipath_i_rcvurg_shift);
	if (chk0rcv || (istat & kportrbits)) {
		istat &= ~kportrbits;
		ipath_kreceive(dd->ipath_pd[0]);
	}

	if (istat & ((dd->ipath_i_rcvavail_mask << dd->ipath_i_rcvavail_shift) |
		     (dd->ipath_i_rcvurg_mask << dd->ipath_i_rcvurg_shift)))
		handle_urcv(dd, istat);

	if (istat & (INFINIPATH_I_SDMAINT | INFINIPATH_I_SDMADISABLED))
		handle_sdma_intr(dd, istat);

	if (istat & INFINIPATH_I_SPIOBUFAVAIL) {
		unsigned long flags;

		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
		dd->ipath_sendctrl &= ~INFINIPATH_S_PIOINTBUFAVAIL;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
				 dd->ipath_sendctrl);
		ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
		spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);

		/* always process; sdma verbs uses PIO for acks and VL15  */
		handle_layer_pioavail(dd);
	}

	ret = IRQ_HANDLED;

bail:
	return ret;
}
