diff options
Diffstat (limited to 'drivers/char/ip2/ip2main.c')
-rw-r--r-- | drivers/char/ip2/ip2main.c | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 2124dce38f2b..e04e66cf2c68 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -752,7 +752,7 @@ retry: | |||
752 | continue; | 752 | continue; |
753 | rc = request_irq( ip2config.irq[i], ip2_interrupt, | 753 | rc = request_irq( ip2config.irq[i], ip2_interrupt, |
754 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | 754 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), |
755 | pcName, (void *)&pcName); | 755 | pcName, i2BoardPtrTable[i]); |
756 | if (rc) { | 756 | if (rc) { |
757 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); | 757 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); |
758 | ip2config.irq[i] = CIR_POLL; | 758 | ip2config.irq[i] = CIR_POLL; |
@@ -1166,12 +1166,37 @@ ip2_interrupt_bh(struct work_struct *work) | |||
1166 | /* */ | 1166 | /* */ |
1167 | /* */ | 1167 | /* */ |
1168 | /******************************************************************************/ | 1168 | /******************************************************************************/ |
1169 | static irqreturn_t | 1169 | static void |
1170 | ip2_interrupt(int irq, void *dev_id) | 1170 | ip2_irq_work(i2eBordStrPtr pB) |
1171 | { | ||
1172 | #ifdef USE_IQI | ||
1173 | if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) { | ||
1174 | // Disable his interrupt (will be enabled when serviced) | ||
1175 | // This is mostly to protect from reentrancy. | ||
1176 | iiDisableMailIrq(pB); | ||
1177 | |||
1178 | // Park the board on the immediate queue for processing. | ||
1179 | schedule_work(&pB->tqueue_interrupt); | ||
1180 | |||
1181 | // Make sure the immediate queue is flagged to fire. | ||
1182 | } | ||
1183 | #else | ||
1184 | |||
1185 | // We are using immediate servicing here. This sucks and can | ||
1186 | // cause all sorts of havoc with ppp and others. The failsafe | ||
1187 | // check on iiSendPendingMail could also throw a hairball. | ||
1188 | |||
1189 | i2ServiceBoard( pB ); | ||
1190 | |||
1191 | #endif /* USE_IQI */ | ||
1192 | } | ||
1193 | |||
1194 | static void | ||
1195 | ip2_polled_interrupt(void) | ||
1171 | { | 1196 | { |
1172 | int i; | 1197 | int i; |
1173 | i2eBordStrPtr pB; | 1198 | i2eBordStrPtr pB; |
1174 | int handled = 0; | 1199 | const int irq = 0; |
1175 | 1200 | ||
1176 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); | 1201 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); |
1177 | 1202 | ||
@@ -1183,32 +1208,28 @@ ip2_interrupt(int irq, void *dev_id) | |||
1183 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards | 1208 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards |
1184 | 1209 | ||
1185 | if ( pB && (pB->i2eUsingIrq == irq) ) { | 1210 | if ( pB && (pB->i2eUsingIrq == irq) ) { |
1186 | handled = 1; | 1211 | ip2_irq_work(pB); |
1187 | #ifdef USE_IQI | 1212 | } |
1213 | } | ||
1188 | 1214 | ||
1189 | if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) { | 1215 | ++irq_counter; |
1190 | // Disable his interrupt (will be enabled when serviced) | ||
1191 | // This is mostly to protect from reentrancy. | ||
1192 | iiDisableMailIrq(pB); | ||
1193 | 1216 | ||
1194 | // Park the board on the immediate queue for processing. | 1217 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); |
1195 | schedule_work(&pB->tqueue_interrupt); | 1218 | } |
1196 | 1219 | ||
1197 | // Make sure the immediate queue is flagged to fire. | 1220 | static irqreturn_t |
1198 | } | 1221 | ip2_interrupt(int irq, void *dev_id) |
1199 | #else | 1222 | { |
1200 | // We are using immediate servicing here. This sucks and can | 1223 | i2eBordStrPtr pB = dev_id; |
1201 | // cause all sorts of havoc with ppp and others. The failsafe | 1224 | |
1202 | // check on iiSendPendingMail could also throw a hairball. | 1225 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq ); |
1203 | i2ServiceBoard( pB ); | 1226 | |
1204 | #endif /* USE_IQI */ | 1227 | ip2_irq_work(pB); |
1205 | } | ||
1206 | } | ||
1207 | 1228 | ||
1208 | ++irq_counter; | 1229 | ++irq_counter; |
1209 | 1230 | ||
1210 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); | 1231 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); |
1211 | return IRQ_RETVAL(handled); | 1232 | return IRQ_HANDLED; |
1212 | } | 1233 | } |
1213 | 1234 | ||
1214 | /******************************************************************************/ | 1235 | /******************************************************************************/ |
@@ -1231,7 +1252,7 @@ ip2_poll(unsigned long arg) | |||
1231 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. | 1252 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. |
1232 | // It will NOT poll boards handled by hard interrupts. | 1253 | // It will NOT poll boards handled by hard interrupts. |
1233 | // The issue of queued BH interrups is handled in ip2_interrupt(). | 1254 | // The issue of queued BH interrups is handled in ip2_interrupt(). |
1234 | ip2_interrupt(0, NULL); | 1255 | ip2_polled_interrupt(); |
1235 | 1256 | ||
1236 | PollTimer.expires = POLL_TIMEOUT; | 1257 | PollTimer.expires = POLL_TIMEOUT; |
1237 | add_timer( &PollTimer ); | 1258 | add_timer( &PollTimer ); |