Browse Source

[undi] Work around broken UNDI polling behaviour in winBoot/i

Some dumb NBPs (e.g. emBoot's winBoot/i) never call PXENV_UNDI_ISR
with FuncFlag=PXENV_UNDI_ISR_START; they just sit in a tight polling
loop merrily violating the PXE spec with repeated calls to
PXENV_UNDI_ISR_IN_PROCESS.  Force a extra calls to netdev_poll() to
cope with these out-of-spec clients.
tags/v0.9.4
Michael Brown 16 years ago
parent
commit
f6f6f626f7
1 changed files with 17 additions and 3 deletions
  1. 17
    3
      src/interface/pxe/pxe_undi.c

+ 17
- 3
src/interface/pxe/pxe_undi.c View File

@@ -221,7 +221,7 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
221 221
 		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
222 222
 		return PXENV_EXIT_FAILURE;
223 223
 	}
224
-	DBG ( " %s", ( net_protocol ? net_protocol->name : "UNKNOWN" ) );
224
+	DBG ( " %s", ( net_protocol ? net_protocol->name : "RAW" ) );
225 225
 
226 226
 	/* Calculate total packet length */
227 227
 	copy_from_real ( &tbd, undi_transmit->TBD.segment,
@@ -264,6 +264,7 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
264 264
 					 pxe_netdev->ll_protocol->ll_addr_len );
265 265
 			ll_dest = destaddr;
266 266
 		} else {
267
+			DBG ( " BCAST" );
267 268
 			ll_dest = pxe_netdev->ll_protocol->ll_broadcast;
268 269
 		}
269 270
 		rc = net_tx ( iobuf, pxe_netdev, net_protocol, ll_dest );
@@ -559,13 +560,25 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
559 560
 		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
560 561
 		break;
561 562
 	case PXENV_UNDI_ISR_IN_PROCESS :
563
+		DBG ( " PROCESS" );
564
+		/* Fall through */
562 565
 	case PXENV_UNDI_ISR_IN_GET_NEXT :
563
-		DBG ( " PROCESS/GET_NEXT" );
566
+		DBG ( " GET_NEXT" );
567
+
568
+		/* Some dumb NBPs (e.g. emBoot's winBoot/i) never call
569
+		 * PXENV_UNDI_ISR with FuncFlag=PXENV_UNDI_ISR_START;
570
+		 * they just sit in a tight polling loop merrily
571
+		 * violating the PXE spec with repeated calls to
572
+		 * PXENV_UNDI_ISR_IN_PROCESS.  Force extra polls to
573
+		 * cope with these out-of-spec clients.
574
+		 */
575
+		netdev_poll ( pxe_netdev );
564 576
 
565 577
 		/* If we have not yet marked a TX as complete, and the
566 578
 		 * netdev TX queue is empty, report the TX completion.
567 579
 		 */
568 580
 		if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) {
581
+			DBG ( " TXC" );
569 582
 			undi_tx_count--;
570 583
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT;
571 584
 			break;
@@ -574,6 +587,7 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
574 587
 		/* Remove first packet from netdev RX queue */
575 588
 		iobuf = netdev_rx_dequeue ( pxe_netdev );
576 589
 		if ( ! iobuf ) {
590
+			DBG ( " DONE" );
577 591
 			/* No more packets remaining */
578 592
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
579 593
 			/* Re-enable interrupts */
@@ -583,7 +597,7 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
583 597
 
584 598
 		/* Copy packet to base memory buffer */
585 599
 		len = iob_len ( iobuf );
586
-		DBG ( " RECEIVE %zd", len );
600
+		DBG ( " RX %zd", len );
587 601
 		if ( len > sizeof ( basemem_packet ) ) {
588 602
 			/* Should never happen */
589 603
 			len = sizeof ( basemem_packet );

Loading…
Cancel
Save