1/*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * --- 33 unchanged lines hidden (view full) --- 42 */ 43#ifdef __NetBSD__ 44#include <sys/cdefs.h> 45__KERNEL_RCSID(0, "$NetBSD$"); 46#include <dev/ic/isp_netbsd.h> 47#endif 48#ifdef __FreeBSD__ 49#include <sys/cdefs.h> |
50__FBSDID("$FreeBSD: stable/10/sys/dev/isp/isp.c 290785 2015-11-13 19:42:55Z mav $"); |
51#include <dev/isp/isp_freebsd.h> 52#endif 53#ifdef __OpenBSD__ 54#include <dev/ic/isp_openbsd.h> 55#endif 56#ifdef __linux__ 57#include "isp_linux.h" 58#endif --- 4973 unchanged lines hidden (view full) --- 5032 * Limit our stack depth by sticking with the max likely number 5033 * of completions on a request queue at any one time. 5034 */ 5035#ifndef MAX_REQUESTQ_COMPLETIONS 5036#define MAX_REQUESTQ_COMPLETIONS 32 5037#endif 5038 5039void |
5040isp_intr(ispsoftc_t *isp, uint16_t isr, uint16_t sema, uint16_t info) |
5041{ 5042 XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs; 5043 uint32_t iptr, optr, junk; 5044 int i, nlooked = 0, ndone = 0, continuations_expected = 0; 5045 int etype, last_etype = 0; 5046 5047again: 5048 /* 5049 * Is this a mailbox related interrupt? 5050 * The mailbox semaphore will be nonzero if so. 5051 */ 5052 if (sema) { 5053 fmbox: |
5054 if (info & MBOX_COMMAND_COMPLETE) { |
5055 isp->isp_intmboxc++; 5056 if (isp->isp_mboxbsy) { 5057 int obits = isp->isp_obits; |
5058 isp->isp_mboxtmp[0] = info; |
5059 for (i = 1; i < ISP_NMBOX(isp); i++) { 5060 if ((obits & (1 << i)) == 0) { 5061 continue; 5062 } 5063 isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i)); 5064 } 5065 if (isp->isp_mbxwrk0) { 5066 if (isp_mbox_continue(isp) == 0) { 5067 return; 5068 } 5069 } 5070 MBOX_NOTIFY_COMPLETE(isp); 5071 } else { |
5072 isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", info); |
5073 } 5074 } else { |
5075 i = IS_FC(isp)? isp_parse_async_fc(isp, info) : isp_parse_async(isp, info); |
5076 if (i < 0) { 5077 return; 5078 } 5079 } |
5080 if ((IS_FC(isp) && info != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) { |
5081 goto out; 5082 } 5083 } 5084 5085 /* 5086 * We can't be getting this now. 5087 */ 5088 if (isp->isp_state != ISP_RUNSTATE) { 5089 /* 5090 * This seems to happen to 23XX and 24XX cards- don't know why. 5091 */ 5092 if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) { 5093 goto fmbox; 5094 } |
5095 isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x INFO=%x) " 5096 "when not ready", isr, sema, info); |
5097 /* 5098 * Thank you very much! *Burrrp*! 5099 */ 5100 isp->isp_residx = ISP_READ(isp, isp->isp_respinrp); 5101 isp->isp_resodx = isp->isp_residx; 5102 ISP_WRITE(isp, isp->isp_respoutrp, isp->isp_resodx); 5103 if (IS_24XX(isp)) { 5104 ISP_DISABLE_INTS(isp); 5105 } 5106 goto out; 5107 } 5108 5109#ifdef ISP_TARGET_MODE 5110 /* 5111 * Check for ATIO Queue entries. 5112 */ 5113 if (IS_24XX(isp) && |
5114 (isr == ISPR2HST_ATIO_UPDATE || isr == ISPR2HST_ATIO_RSPQ_UPDATE || 5115 isr == ISPR2HST_ATIO_UPDATE2)) { |
5116 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP); 5117 optr = isp->isp_atioodx; 5118 5119 while (optr != iptr) { 5120 uint8_t qe[QENTRY_LEN]; 5121 isphdr_t *hp; 5122 uint32_t oop; 5123 void *addr; --- 17 unchanged lines hidden (view full) --- 5141 if (isp->isp_atioodx != optr) { 5142 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr); 5143 isp->isp_atioodx = optr; 5144 } 5145 } 5146#endif 5147 5148 /* |
5149 * You *must* read the Response Queue In Pointer 5150 * prior to clearing the RISC interrupt. 5151 * 5152 * Debounce the 2300 if revision less than 2. 5153 */ 5154 if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) { 5155 i = 0; 5156 do { --- 4 unchanged lines hidden (view full) --- 5161 if (iptr != junk) { 5162 isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk); 5163 goto out; 5164 } 5165 } else { 5166 iptr = ISP_READ(isp, isp->isp_respinrp); 5167 } 5168 |
5169 optr = isp->isp_resodx; |
5170 if (optr == iptr && sema == 0) { 5171 /* 5172 * There are a lot of these- reasons unknown- mostly on 5173 * faster Alpha machines. 5174 * 5175 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to 5176 * make sure the old interrupt went away (to avoid 'ringing' 5177 * effects), but that didn't stop this from occurring. --- 7 unchanged lines hidden (view full) --- 5185 } else { 5186 junk = ISP_READ(isp, BIU_ISR); 5187 } 5188 if (optr == iptr) { 5189 if (IS_23XX(isp) || IS_24XX(isp)) { 5190 ; 5191 } else { 5192 sema = ISP_READ(isp, BIU_SEMA); |
5193 info = ISP_READ(isp, OUTMAILBOX0); 5194 if ((sema & 0x3) && (info & 0x8000)) { |
5195 goto again; 5196 } 5197 } 5198 isp->isp_intbogus++; 5199 isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr); 5200 } 5201 } 5202 isp->isp_residx = iptr; --- 3321 unchanged lines hidden --- |