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
 		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
221
 		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
222
 		return PXENV_EXIT_FAILURE;
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
 	/* Calculate total packet length */
226
 	/* Calculate total packet length */
227
 	copy_from_real ( &tbd, undi_transmit->TBD.segment,
227
 	copy_from_real ( &tbd, undi_transmit->TBD.segment,
264
 					 pxe_netdev->ll_protocol->ll_addr_len );
264
 					 pxe_netdev->ll_protocol->ll_addr_len );
265
 			ll_dest = destaddr;
265
 			ll_dest = destaddr;
266
 		} else {
266
 		} else {
267
+			DBG ( " BCAST" );
267
 			ll_dest = pxe_netdev->ll_protocol->ll_broadcast;
268
 			ll_dest = pxe_netdev->ll_protocol->ll_broadcast;
268
 		}
269
 		}
269
 		rc = net_tx ( iobuf, pxe_netdev, net_protocol, ll_dest );
270
 		rc = net_tx ( iobuf, pxe_netdev, net_protocol, ll_dest );
559
 		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
560
 		undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS;
560
 		break;
561
 		break;
561
 	case PXENV_UNDI_ISR_IN_PROCESS :
562
 	case PXENV_UNDI_ISR_IN_PROCESS :
563
+		DBG ( " PROCESS" );
564
+		/* Fall through */
562
 	case PXENV_UNDI_ISR_IN_GET_NEXT :
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
 		/* If we have not yet marked a TX as complete, and the
577
 		/* If we have not yet marked a TX as complete, and the
566
 		 * netdev TX queue is empty, report the TX completion.
578
 		 * netdev TX queue is empty, report the TX completion.
567
 		 */
579
 		 */
568
 		if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) {
580
 		if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) {
581
+			DBG ( " TXC" );
569
 			undi_tx_count--;
582
 			undi_tx_count--;
570
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT;
583
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT;
571
 			break;
584
 			break;
574
 		/* Remove first packet from netdev RX queue */
587
 		/* Remove first packet from netdev RX queue */
575
 		iobuf = netdev_rx_dequeue ( pxe_netdev );
588
 		iobuf = netdev_rx_dequeue ( pxe_netdev );
576
 		if ( ! iobuf ) {
589
 		if ( ! iobuf ) {
590
+			DBG ( " DONE" );
577
 			/* No more packets remaining */
591
 			/* No more packets remaining */
578
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
592
 			undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE;
579
 			/* Re-enable interrupts */
593
 			/* Re-enable interrupts */
583
 
597
 
584
 		/* Copy packet to base memory buffer */
598
 		/* Copy packet to base memory buffer */
585
 		len = iob_len ( iobuf );
599
 		len = iob_len ( iobuf );
586
-		DBG ( " RECEIVE %zd", len );
600
+		DBG ( " RX %zd", len );
587
 		if ( len > sizeof ( basemem_packet ) ) {
601
 		if ( len > sizeof ( basemem_packet ) ) {
588
 			/* Should never happen */
602
 			/* Should never happen */
589
 			len = sizeof ( basemem_packet );
603
 			len = sizeof ( basemem_packet );

Loading…
Cancel
Save