|
@@ -253,16 +253,24 @@ static void undinet_poll ( struct net_device *netdev ) {
|
253
|
253
|
int rc;
|
254
|
254
|
|
255
|
255
|
if ( ! undinic->isr_processing ) {
|
256
|
|
- /* If interrupts are supported, then do nothing unless
|
257
|
|
- * the ISR has been triggered.
|
|
256
|
+ /* Allow interrupt to occur. Do this even if
|
|
257
|
+ * interrupts are not known to be supported, since
|
|
258
|
+ * some cards erroneously report that they do not
|
|
259
|
+ * support interrupts.
|
258
|
260
|
*/
|
259
|
|
- if ( undinic->irq_supported && ( ! undinet_isr_triggered() ) ){
|
|
261
|
+ if ( ! undinet_isr_triggered() ) {
|
260
|
262
|
/* Allow interrupt to occur */
|
261
|
263
|
__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
|
262
|
264
|
"nop\n\t"
|
263
|
265
|
"nop\n\t"
|
264
|
266
|
"cli\n\t" ) : : );
|
265
|
|
- return;
|
|
267
|
+
|
|
268
|
+ /* If interrupts are known to be supported,
|
|
269
|
+ * then do nothing on this poll; wait for the
|
|
270
|
+ * interrupt to be triggered.
|
|
271
|
+ */
|
|
272
|
+ if ( undinic->irq_supported )
|
|
273
|
+ return;
|
266
|
274
|
}
|
267
|
275
|
|
268
|
276
|
/* Start ISR processing */
|
|
@@ -361,8 +369,8 @@ static int undinet_open ( struct net_device *netdev ) {
|
361
|
369
|
struct s_PXENV_UNDI_OPEN undi_open;
|
362
|
370
|
int rc;
|
363
|
371
|
|
364
|
|
- /* Hook interrupt service routine and enable interrupt if supported */
|
365
|
|
- if ( undinic->irq_supported ) {
|
|
372
|
+ /* Hook interrupt service routine and enable interrupt if applicable */
|
|
373
|
+ if ( undinic->irq ) {
|
366
|
374
|
undinet_hook_isr ( undinic->irq );
|
367
|
375
|
enable_irq ( undinic->irq );
|
368
|
376
|
send_eoi ( undinic->irq );
|
|
@@ -431,8 +439,8 @@ static void undinet_close ( struct net_device *netdev ) {
|
431
|
439
|
pxeparent_call ( undinet_entry, PXENV_UNDI_CLOSE,
|
432
|
440
|
&undi_close, sizeof ( undi_close ) );
|
433
|
441
|
|
434
|
|
- /* Disable interrupt and unhook ISR if supported */
|
435
|
|
- if ( undinic->irq_supported ) {
|
|
442
|
+ /* Disable interrupt and unhook ISR if applicable */
|
|
443
|
+ if ( undinic->irq ) {
|
436
|
444
|
disable_irq ( undinic->irq );
|
437
|
445
|
undinet_unhook_isr ( undinic->irq );
|
438
|
446
|
}
|
|
@@ -532,8 +540,14 @@ int undinet_probe ( struct undi_device *undi ) {
|
532
|
540
|
goto err_undi_get_information;
|
533
|
541
|
memcpy ( netdev->hw_addr, undi_info.PermNodeAddress, ETH_ALEN );
|
534
|
542
|
undinic->irq = undi_info.IntNumber;
|
535
|
|
- DBGC ( undinic, "UNDINIC %p has MAC address %s\n",
|
536
|
|
- undinic, eth_ntoa ( netdev->hw_addr ) );
|
|
543
|
+ if ( undinic->irq > IRQ_MAX ) {
|
|
544
|
+ DBGC ( undinic, "UNDINIC %p has invalid IRQ %d\n",
|
|
545
|
+ undinic, undinic->irq );
|
|
546
|
+ rc = -EINVAL;
|
|
547
|
+ goto err_bad_irq;
|
|
548
|
+ }
|
|
549
|
+ DBGC ( undinic, "UNDINIC %p has MAC address %s and IRQ %d\n",
|
|
550
|
+ undinic, eth_ntoa ( netdev->hw_addr ), undinic->irq );
|
537
|
551
|
|
538
|
552
|
/* Get interface information */
|
539
|
553
|
memset ( &undi_iface, 0, sizeof ( undi_iface ) );
|
|
@@ -544,17 +558,10 @@ int undinet_probe ( struct undi_device *undi ) {
|
544
|
558
|
DBGC ( undinic, "UNDINIC %p has type %s, speed %d, flags %08x\n",
|
545
|
559
|
undinic, undi_iface.IfaceType, undi_iface.LinkSpeed,
|
546
|
560
|
undi_iface.ServiceFlags );
|
547
|
|
- if ( undi_iface.ServiceFlags & SUPPORTED_IRQ ) {
|
548
|
|
- if ( undinic->irq > IRQ_MAX ) {
|
549
|
|
- DBGC ( undinic, "UNDINIC %p has invalid IRQ %d\n",
|
550
|
|
- undinic, undinic->irq );
|
551
|
|
- rc = -EINVAL;
|
552
|
|
- goto err_bad_irq;
|
553
|
|
- }
|
|
561
|
+ if ( undi_iface.ServiceFlags & SUPPORTED_IRQ )
|
554
|
562
|
undinic->irq_supported = 1;
|
555
|
|
- DBGC ( undinic, "UNDINIC %p uses IRQ %d\n",
|
556
|
|
- undinic, undinic->irq );
|
557
|
|
- }
|
|
563
|
+ DBGC ( undinic, "UNDINIC %p using %s mode\n", undinic,
|
|
564
|
+ ( undinic->irq_supported ? "interrupt" : "polling" ) );
|
558
|
565
|
if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot",
|
559
|
566
|
sizeof ( undi_iface.IfaceType ) ) == 0 ) {
|
560
|
567
|
DBGC ( undinic, "UNDINIC %p Etherboot 5.4 workaround enabled\n",
|
|
@@ -573,8 +580,8 @@ int undinet_probe ( struct undi_device *undi ) {
|
573
|
580
|
return 0;
|
574
|
581
|
|
575
|
582
|
err_register:
|
576
|
|
- err_bad_irq:
|
577
|
583
|
err_undi_get_iface_info:
|
|
584
|
+ err_bad_irq:
|
578
|
585
|
err_undi_get_information:
|
579
|
586
|
err_undi_initialize:
|
580
|
587
|
/* Shut down UNDI stack */
|