| 
				
			 | 
			
			
				
				@@ -364,7 +364,8 @@ static int undinet_transmit ( struct net_device *netdev, 
			 | 
		
		
	
		
			
			| 
				364
			 | 
			
				364
			 | 
			
			
				
				 /**  
			 | 
		
		
	
		
			
			| 
				365
			 | 
			
				365
			 | 
			
			
				
				  * Poll for received packets 
			 | 
		
		
	
		
			
			| 
				366
			 | 
			
				366
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				367
			 | 
			
				
			 | 
			
			
				
				- * @v netdev	Network device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				367
			 | 
			
			
				
				+ * @v netdev		Network device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				368
			 | 
			
			
				
				+ * @v rx_quota		Maximum number of packets to receive 
			 | 
		
		
	
		
			
			| 
				368
			 | 
			
				369
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				369
			 | 
			
				370
			 | 
			
			
				
				  * Fun, fun, fun.  UNDI drivers don't use polling; they use 
			 | 
		
		
	
		
			
			| 
				370
			 | 
			
				371
			 | 
			
			
				
				  * interrupts.  We therefore cheat and pretend that an interrupt has 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -382,7 +383,7 @@ static int undinet_transmit ( struct net_device *netdev, 
			 | 
		
		
	
		
			
			| 
				382
			 | 
			
				383
			 | 
			
			
				
				  * of installing a genuine interrupt service routine and dealing with 
			 | 
		
		
	
		
			
			| 
				383
			 | 
			
				384
			 | 
			
			
				
				  * the wonderful 8259 Programmable Interrupt Controller.  Joy. 
			 | 
		
		
	
		
			
			| 
				384
			 | 
			
				385
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				385
			 | 
			
				
			 | 
			
			
				
				-static void undinet_poll ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				386
			 | 
			
			
				
				+static void undinet_poll ( struct net_device *netdev, unsigned int rx_quota ) { 
			 | 
		
		
	
		
			
			| 
				386
			 | 
			
				387
			 | 
			
			
				
				 	struct undi_nic *undinic = netdev->priv; 
			 | 
		
		
	
		
			
			| 
				387
			 | 
			
				388
			 | 
			
			
				
				 	struct s_PXENV_UNDI_ISR undi_isr; 
			 | 
		
		
	
		
			
			| 
				388
			 | 
			
				389
			 | 
			
			
				
				 	struct pk_buff *pkb = NULL; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -416,7 +417,7 @@ static void undinet_poll ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				416
			 | 
			
				417
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				417
			 | 
			
				418
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				418
			 | 
			
				419
			 | 
			
			
				
				 	/* Run through the ISR loop */ 
			 | 
		
		
	
		
			
			| 
				419
			 | 
			
				
			 | 
			
			
				
				-	while ( 1 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				420
			 | 
			
			
				
				+	while ( rx_quota ) { 
			 | 
		
		
	
		
			
			| 
				420
			 | 
			
				421
			 | 
			
			
				
				 		if ( ( rc = undinet_call ( undinic, PXENV_UNDI_ISR, &undi_isr, 
			 | 
		
		
	
		
			
			| 
				421
			 | 
			
				422
			 | 
			
			
				
				 					   sizeof ( undi_isr ) ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				422
			 | 
			
				423
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -448,6 +449,7 @@ static void undinet_poll ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				448
			 | 
			
				449
			 | 
			
			
				
				 			if ( pkb_len ( pkb ) == len ) { 
			 | 
		
		
	
		
			
			| 
				449
			 | 
			
				450
			 | 
			
			
				
				 				netdev_rx ( netdev, pkb ); 
			 | 
		
		
	
		
			
			| 
				450
			 | 
			
				451
			 | 
			
			
				
				 				pkb = NULL; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				452
			 | 
			
			
				
				+				--rx_quota; 
			 | 
		
		
	
		
			
			| 
				451
			 | 
			
				453
			 | 
			
			
				
				 			} 
			 | 
		
		
	
		
			
			| 
				452
			 | 
			
				454
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
		
			
			| 
				453
			 | 
			
				455
			 | 
			
			
				
				 		case PXENV_UNDI_ISR_OUT_DONE: 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -480,8 +482,8 @@ static void undinet_poll ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				480
			 | 
			
				482
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				481
			 | 
			
				483
			 | 
			
			
				
				 static int undinet_open ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				482
			 | 
			
				484
			 | 
			
			
				
				 	struct undi_nic *undinic = netdev->priv; 
			 | 
		
		
	
		
			
			| 
				483
			 | 
			
				
			 | 
			
			
				
				-	struct s_PXENV_UNDI_SET_STATION_ADDRESS set_address; 
			 | 
		
		
	
		
			
			| 
				484
			 | 
			
				
			 | 
			
			
				
				-	struct s_PXENV_UNDI_OPEN open; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				485
			 | 
			
			
				
				+	struct s_PXENV_UNDI_SET_STATION_ADDRESS undi_set_address; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				486
			 | 
			
			
				
				+	struct s_PXENV_UNDI_OPEN undi_open; 
			 | 
		
		
	
		
			
			| 
				485
			 | 
			
				487
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				486
			 | 
			
				488
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				487
			 | 
			
				489
			 | 
			
			
				
				 	/* Hook interrupt service routine and enable interrupt */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -494,16 +496,16 @@ static int undinet_open ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				494
			 | 
			
				496
			 | 
			
			
				
				 	 * use it to set the MAC address to the card's permanent value 
			 | 
		
		
	
		
			
			| 
				495
			 | 
			
				497
			 | 
			
			
				
				 	 * anyway. 
			 | 
		
		
	
		
			
			| 
				496
			 | 
			
				498
			 | 
			
			
				
				 	 */ 
			 | 
		
		
	
		
			
			| 
				497
			 | 
			
				
			 | 
			
			
				
				-	memcpy ( set_address.StationAddress, netdev->ll_addr, 
			 | 
		
		
	
		
			
			| 
				498
			 | 
			
				
			 | 
			
			
				
				-		 sizeof ( set_address.StationAddress ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				499
			 | 
			
			
				
				+	memcpy ( undi_set_address.StationAddress, netdev->ll_addr, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				500
			 | 
			
			
				
				+		 sizeof ( undi_set_address.StationAddress ) ); 
			 | 
		
		
	
		
			
			| 
				499
			 | 
			
				501
			 | 
			
			
				
				 	undinet_call ( undinic, PXENV_UNDI_SET_STATION_ADDRESS, 
			 | 
		
		
	
		
			
			| 
				500
			 | 
			
				
			 | 
			
			
				
				-		       &set_address, sizeof ( set_address ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				502
			 | 
			
			
				
				+		       &undi_set_address, sizeof ( undi_set_address ) ); 
			 | 
		
		
	
		
			
			| 
				501
			 | 
			
				503
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				502
			 | 
			
				504
			 | 
			
			
				
				 	/* Open NIC */ 
			 | 
		
		
	
		
			
			| 
				503
			 | 
			
				
			 | 
			
			
				
				-	memset ( &open, 0, sizeof ( open ) ); 
			 | 
		
		
	
		
			
			| 
				504
			 | 
			
				
			 | 
			
			
				
				-	open.PktFilter = ( FLTR_DIRECTED | FLTR_BRDCST ); 
			 | 
		
		
	
		
			
			| 
				505
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_OPEN, &open, 
			 | 
		
		
	
		
			
			| 
				506
			 | 
			
				
			 | 
			
			
				
				-				   sizeof ( open ) ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				505
			 | 
			
			
				
				+	memset ( &undi_open, 0, sizeof ( undi_open ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				506
			 | 
			
			
				
				+	undi_open.PktFilter = ( FLTR_DIRECTED | FLTR_BRDCST ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				507
			 | 
			
			
				
				+	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_OPEN, &undi_open, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				508
			 | 
			
			
				
				+				   sizeof ( undi_open ) ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				507
			 | 
			
				509
			 | 
			
			
				
				 		goto err; 
			 | 
		
		
	
		
			
			| 
				508
			 | 
			
				510
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				509
			 | 
			
				511
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -520,14 +522,31 @@ static int undinet_open ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				520
			 | 
			
				522
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				521
			 | 
			
				523
			 | 
			
			
				
				 static void undinet_close ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				522
			 | 
			
				524
			 | 
			
			
				
				 	struct undi_nic *undinic = netdev->priv; 
			 | 
		
		
	
		
			
			| 
				523
			 | 
			
				
			 | 
			
			
				
				-	struct s_PXENV_UNDI_CLOSE close; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				525
			 | 
			
			
				
				+	struct s_PXENV_UNDI_ISR undi_isr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				526
			 | 
			
			
				
				+	struct s_PXENV_UNDI_CLOSE undi_close; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				527
			 | 
			
			
				
				+	int rc; 
			 | 
		
		
	
		
			
			| 
				524
			 | 
			
				528
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				525
			 | 
			
				529
			 | 
			
			
				
				 	/* Ensure ISR has exited cleanly */ 
			 | 
		
		
	
		
			
			| 
				526
			 | 
			
				
			 | 
			
			
				
				-	while ( undinic->isr_processing ) 
			 | 
		
		
	
		
			
			| 
				527
			 | 
			
				
			 | 
			
			
				
				-		undinet_poll ( netdev ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				530
			 | 
			
			
				
				+	while ( undinic->isr_processing ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				531
			 | 
			
			
				
				+		undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				532
			 | 
			
			
				
				+		if ( ( rc = undinet_call ( undinic, PXENV_UNDI_ISR, &undi_isr, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				533
			 | 
			
			
				
				+					   sizeof ( undi_isr ) ) ) != 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				534
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				535
			 | 
			
			
				
				+		switch ( undi_isr.FuncFlag ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				536
			 | 
			
			
				
				+		case PXENV_UNDI_ISR_OUT_TRANSMIT: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				537
			 | 
			
			
				
				+		case PXENV_UNDI_ISR_OUT_RECEIVE: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				538
			 | 
			
			
				
				+			/* Continue draining */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				539
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				540
			 | 
			
			
				
				+		default: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				541
			 | 
			
			
				
				+			/* Stop processing */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				542
			 | 
			
			
				
				+			undinic->isr_processing = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				543
			 | 
			
			
				
				+			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				544
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				545
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				528
			 | 
			
				546
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				529
			 | 
			
				547
			 | 
			
			
				
				 	/* Close NIC */ 
			 | 
		
		
	
		
			
			| 
				530
			 | 
			
				
			 | 
			
			
				
				-	undinet_call ( undinic, PXENV_UNDI_CLOSE, &close, sizeof ( close ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				548
			 | 
			
			
				
				+	undinet_call ( undinic, PXENV_UNDI_CLOSE, &undi_close, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				549
			 | 
			
			
				
				+		       sizeof ( undi_close ) ); 
			 | 
		
		
	
		
			
			| 
				531
			 | 
			
				550
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				532
			 | 
			
				551
			 | 
			
			
				
				 	/* Disable interrupt and unhook ISR */ 
			 | 
		
		
	
		
			
			| 
				533
			 | 
			
				552
			 | 
			
			
				
				 	disable_irq ( undinic->irq ); 
			 |