|  | @@ -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 */
 |