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. 993126448451105fae59de0058c68692aa09aa4c37Mitko Haralanov * 1003126448451105fae59de0058c68692aa09aa4c37Mitko Haralanov * ppd->lflags could be 0 if this is the first time the interrupt 1013126448451105fae59de0058c68692aa09aa4c37Mitko Haralanov * handlers has been called but the link is already up. 102f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 1033126448451105fae59de0058c68692aa09aa4c37Mitko Haralanov if (lstate >= IB_PORT_INIT && 1043126448451105fae59de0058c68692aa09aa4c37Mitko Haralanov (!ppd->lflags || (ppd->lflags & QIBL_LINKDOWN)) && 105f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltstate == IB_PHYSPORTSTATE_LINKUP) { 106f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* transitioned to UP */ 107f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->f_ib_updown(ppd, 1, ibcs)) 108f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto skip_ibchange; /* chip-code handled */ 109f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | 110f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKACTIVE | QIBL_IB_FORCE_NOTIFY)) { 111f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ltstate != IB_PHYSPORTSTATE_LINKUP && 112f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ltstate <= IB_PHYSPORTSTATE_CFG_TRAIN && 113f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_ib_updown(ppd, 0, ibcs)) 114f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell goto skip_ibchange; /* chip-code handled */ 115f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_set_uevent_bits(ppd, _QIB_EVENT_LINKDOWN_BIT); 116f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 117f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 118f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate != IB_PORT_DOWN) { 119f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* lstate is INIT, ARMED, or ACTIVE */ 120f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate != IB_PORT_ACTIVE) { 121f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *ppd->statusp &= ~QIB_STATUS_IB_READY; 122f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_LINKACTIVE) 123f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ev = IB_EVENT_PORT_ERR; 124f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 125f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (lstate == IB_PORT_ARMED) { 126f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKARMED | QIBL_LINKV; 127f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKINIT | 128f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKDOWN | QIBL_LINKACTIVE); 129f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { 130f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKINIT | QIBL_LINKV; 131f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKARMED | 132f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKDOWN | QIBL_LINKACTIVE); 133f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 134f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 135f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* start a 75msec timer to clear symbol errors */ 136f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell mod_timer(&ppd->symerr_clear_timer, 137f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell msecs_to_jiffies(75)); 138b3d5cb2f2067b30da53aa67e42fdd733030fb411Mike Marciniszyn } else if (ltstate == IB_PHYSPORTSTATE_LINKUP && 139b3d5cb2f2067b30da53aa67e42fdd733030fb411Mike Marciniszyn !(ppd->lflags & QIBL_LINKACTIVE)) { 140f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* active, but not active defered */ 141f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_hol_up(ppd); /* useful only for 6120 now */ 142f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *ppd->statusp |= 143f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIB_STATUS_IB_READY | QIB_STATUS_IB_CONF; 144f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_clear_symerror_on_linkup((unsigned long)ppd); 145f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 146f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKACTIVE | QIBL_LINKV; 147f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKINIT | 148f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKDOWN | QIBL_LINKARMED); 149f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 150f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (dd->flags & QIB_HAS_SEND_DMA) 151f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_process_event(ppd, 152f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell qib_sdma_event_e30_go_running); 153f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ev = IB_EVENT_PORT_ACTIVE; 154f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_setextled(ppd, 1); 155f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 156f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else { /* down */ 157f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_LINKACTIVE) 158f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ev = IB_EVENT_PORT_ERR; 159f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&ppd->lflags_lock, flags); 160f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags |= QIBL_LINKDOWN | QIBL_LINKV; 161f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lflags &= ~(QIBL_LINKINIT | 162f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell QIBL_LINKACTIVE | QIBL_LINKARMED); 163f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&ppd->lflags_lock, flags); 164f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell *ppd->statusp &= ~QIB_STATUS_IB_READY; 165f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 166f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 167f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellskip_ibchange: 168f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->lastibcstat = ibcs; 169f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ev) 170f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell signal_ib_event(ppd, ev); 171f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 172f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 173f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 174f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_clear_symerror_on_linkup(unsigned long opaque) 175f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 176f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; 177f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 178f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (ppd->lflags & QIBL_LINKACTIVE) 179f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell return; 180f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 181f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->ibport_data.z_symbol_error_counter = 182f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBSYMBOLERR); 183f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 184f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 185f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell/* 186f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * Handle receive interrupts for user ctxts; this means a user 187f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * process was waiting for a packet to arrive, and didn't want 188f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * to poll. 189f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 190f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_handle_urcv(struct qib_devdata *dd, u64 ctxtr) 191f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 192f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell struct qib_ctxtdata *rcd; 193f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell unsigned long flags; 194f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell int i; 195f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 196f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_lock_irqsave(&dd->uctxt_lock, flags); 197f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell for (i = dd->first_user_ctxt; dd->rcd && i < dd->cfgctxts; i++) { 198f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!(ctxtr & (1ULL << i))) 199f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell continue; 200f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd = dd->rcd[i]; 201f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (!rcd || !rcd->cnt) 202f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell continue; 203f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 204f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (test_and_clear_bit(QIB_CTXT_WAITING_RCV, &rcd->flag)) { 205f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up_interruptible(&rcd->wait); 206f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_INTRAVAIL_DIS, 207f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->ctxt); 208f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } else if (test_and_clear_bit(QIB_CTXT_WAITING_URG, 209f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell &rcd->flag)) { 210f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell rcd->urgent++; 211f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell wake_up_interruptible(&rcd->wait); 212f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 213f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 214f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell spin_unlock_irqrestore(&dd->uctxt_lock, flags); 215f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 216f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 217f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbellvoid qib_bad_intrstatus(struct qib_devdata *dd) 218f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell{ 219f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell static int allbits; 220f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 221f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* separate routine, for better optimization of qib_intr() */ 222f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell 223f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* 224f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * We print the message and disable interrupts, in hope of 225f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell * having a better chance of debugging the problem. 226f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell */ 2277fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 2287fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "Read of chip interrupt status failed disabling interrupts\n"); 229f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (allbits++) { 230f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell /* disable interrupt delivery, something is very wrong */ 231f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (allbits == 2) 232f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_set_intr_state(dd, 0); 233f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell if (allbits == 3) { 2347fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn qib_dev_err(dd, 2357fac33014f54c26bb1b1b4282b27c7988116d639Mike Marciniszyn "2nd bad interrupt status, unregistering interrupts\n"); 236f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags |= QIB_BADINTR; 237f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->flags &= ~QIB_INITTED; 238f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell dd->f_free_irq(dd); 239f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 240f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell } 241f931551bafe1f10ded7f5282e2aa162c267a2e5dRalph Campbell} 242