qib_intr.c revision b3d5cb2f2067b30da53aa67e42fdd733030fb411
1f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 2f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. 3f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * All rights reserved. 4f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. 5f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 6f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * This software is available to you under a choice of one of two 7f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * licenses. You may choose to be licensed under the terms of the GNU 8f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * General Public License (GPL) Version 2, available from the file 9f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * COPYING in the main directory of this source tree, or the 10f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * OpenIB.org BSD license below: 11f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 12f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Redistribution and use in source and binary forms, with or 13f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * without modification, are permitted provided that the following 14f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * conditions are met: 15f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 16f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * - Redistributions of source code must retain the above 17f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * copyright notice, this list of conditions and the following 18f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * disclaimer. 19f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 20f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * - Redistributions in binary form must reproduce the above 21f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * copyright notice, this list of conditions and the following 22f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * disclaimer in the documentation and/or other materials 23f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * provided with the distribution. 24f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * 25f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * SOFTWARE. 33f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 34f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 35f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <linux/pci.h> 36f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include <linux/delay.h> 37f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 38f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include "qib.h" 39f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell#include "qib_common.h" 40f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 41f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 42f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_format_hwmsg - format a single hwerror message 43f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @msg message buffer 44f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @msgl length of message buffer 45f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @hwmsg message to add to message buffer 46f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 47f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void qib_format_hwmsg(char *msg, size_t msgl, const char *hwmsg) 48f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 49f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(msg, "[", msgl); 50f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(msg, hwmsg, msgl); 51f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell strlcat(msg, "]", msgl); 52f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 53f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 54f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/** 55f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * qib_format_hwerrors - format hardware error messages for display 56f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @hwerrs hardware errors bit vector 57f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @hwerrmsgs hardware error descriptions 58f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @nhwerrmsgs number of hwerrmsgs 59f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @msg message buffer 60f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * @msgl message buffer length 61f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 62f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_format_hwerrors(u64 hwerrs, const struct qib_hwerror_msgs *hwerrmsgs, 63f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell size_t nhwerrmsgs, char *msg, size_t msgl) 64f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 65f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 66f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 67f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = 0; i < nhwerrmsgs; i++) 68f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (hwerrs & hwerrmsgs[i].mask) 69f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_format_hwmsg(msg, msgl, hwerrmsgs[i].msg); 70f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 71f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 72f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellstatic void signal_ib_event(struct qib_pportdata *ppd, enum ib_event_type ev) 73f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 74f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct ib_event event; 75f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 76f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 77f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell event.device = &dd->verbs_dev.ibdev; 78f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell event.element.port_num = ppd->port; 79f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell event.event = ev; 80f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ib_dispatch_event(&event); 81f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 82f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 83f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs) 84f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 85f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_devdata *dd = ppd->dd; 86f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 87f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u32 lstate; 88f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell u8 ltstate; 89f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell enum ib_event_type ev = 0; 90f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 91f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell lstate = dd->f_iblink_state(ibcs); /* linkstate */ 92f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltstate = dd->f_ibphys_portstate(ibcs); 93f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 94f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 95f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * If linkstate transitions into INIT from any of the various down 96f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * states, or if it transitions from any of the up (INIT or better) 97f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * states into any of the down states (except link recovery), then 98f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * call the chip-specific code to take appropriate actions. 99f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 100f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) && 101f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltstate == IB_PHYSPORTSTATE_LINKUP) { 102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* transitioned to UP */ 103f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->f_ib_updown(ppd, 1, ibcs)) 104f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto skip_ibchange; /* chip-code handled */ 105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | 106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKACTIVE | QIBL_IB_FORCE_NOTIFY)) { 107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ltstate != IB_PHYSPORTSTATE_LINKUP && 108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltstate <= IB_PHYSPORTSTATE_CFG_TRAIN && 109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_ib_updown(ppd, 0, ibcs)) 110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto skip_ibchange; /* chip-code handled */ 111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_uevent_bits(ppd, _QIB_EVENT_LINKDOWN_BIT); 112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 114f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate != IB_PORT_DOWN) { 115f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* lstate is INIT, ARMED, or ACTIVE */ 116f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate != IB_PORT_ACTIVE) { 117f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *ppd->statusp &= ~QIB_STATUS_IB_READY; 118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_LINKACTIVE) 119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ev = IB_EVENT_PORT_ERR; 120f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 121f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate == IB_PORT_ARMED) { 122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKARMED | QIBL_LINKV; 123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKINIT | 124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKDOWN | QIBL_LINKACTIVE); 125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKINIT | QIBL_LINKV; 127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKARMED | 128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKDOWN | QIBL_LINKACTIVE); 129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* start a 75msec timer to clear symbol errors */ 132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mod_timer(&ppd->symerr_clear_timer, 133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msecs_to_jiffies(75)); 134b3d5cb2f2067b30da53aa67e42fdd733030fb411Mike Marciniszyn } else if (ltstate == IB_PHYSPORTSTATE_LINKUP && 135b3d5cb2f2067b30da53aa67e42fdd733030fb411Mike Marciniszyn !(ppd->lflags & QIBL_LINKACTIVE)) { 136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* active, but not active defered */ 137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_hol_up(ppd); /* useful only for 6120 now */ 138f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *ppd->statusp |= 139f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_STATUS_IB_READY | QIB_STATUS_IB_CONF; 140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_clear_symerror_on_linkup((unsigned long)ppd); 141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKACTIVE | QIBL_LINKV; 143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKINIT | 144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKDOWN | QIBL_LINKARMED); 145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->flags & QIB_HAS_SEND_DMA) 147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_process_event(ppd, 148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_event_e30_go_running); 149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ev = IB_EVENT_PORT_ACTIVE; 150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_setextled(ppd, 1); 151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 152f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { /* down */ 153f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_LINKACTIVE) 154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ev = IB_EVENT_PORT_ERR; 155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKDOWN | QIBL_LINKV; 157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKINIT | 158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKACTIVE | QIBL_LINKARMED); 159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *ppd->statusp &= ~QIB_STATUS_IB_READY; 161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellskip_ibchange: 164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lastibcstat = ibcs; 165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ev) 166f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell signal_ib_event(ppd, ev); 167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_clear_symerror_on_linkup(unsigned long opaque) 171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; 173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_LINKACTIVE) 175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->ibport_data.z_symbol_error_counter = 178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBSYMBOLERR); 179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Handle receive interrupts for user ctxts; this means a user 183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * process was waiting for a packet to arrive, and didn't want 184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to poll. 185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_handle_urcv(struct qib_devdata *dd, u64 ctxtr) 187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_ctxtdata *rcd; 189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->uctxt_lock, flags); 193f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = dd->first_user_ctxt; dd->rcd && i < dd->cfgctxts; i++) { 194f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ctxtr & (1ULL << i))) 195f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell continue; 196f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd = dd->rcd[i]; 197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!rcd || !rcd->cnt) 198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell continue; 199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (test_and_clear_bit(QIB_CTXT_WAITING_RCV, &rcd->flag)) { 201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up_interruptible(&rcd->wait); 202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_INTRAVAIL_DIS, 203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->ctxt); 204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (test_and_clear_bit(QIB_CTXT_WAITING_URG, 205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell &rcd->flag)) { 206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->urgent++; 207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up_interruptible(&rcd->wait); 208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->uctxt_lock, flags); 211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_bad_intrstatus(struct qib_devdata *dd) 214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static int allbits; 216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* separate routine, for better optimization of qib_intr() */ 218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We print the message and disable interrupts, in hope of 221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * having a better chance of debugging the problem. 222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "Read of chip interrupt status failed" 224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell " disabling interrupts\n"); 225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (allbits++) { 226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* disable interrupt delivery, something is very wrong */ 227f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (allbits == 2) 228f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_intr_state(dd, 0); 229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (allbits == 3) { 230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_dev_err(dd, "2nd bad interrupt status, " 231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell "unregistering interrupts\n"); 232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags |= QIB_BADINTR; 233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags &= ~QIB_INITTED; 234f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_free_irq(dd); 235f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 238