diff packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c @ 121:6bd9d475ed4b ecos-sw-2000-09-04

Merge from eCos master repository on 2000-09-04-20:50:20-BST
author jlarmour
date Mon, 04 Sep 2000 20:24:12 +0000
parents bd1a71e3e476
children 0ec04793409a
line wrap: on
line diff
--- a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
+++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
@@ -408,6 +408,7 @@ ETH_DRV_SC(ebsa285_sc0,
            i82559_can_send,
            i82559_send,
            i82559_recv,
+           i82559_deliver,
            i82559_poll,
            i82559_int_vector);
 
@@ -429,6 +430,7 @@ ETH_DRV_SC(ebsa285_sc1,
            i82559_can_send,
            i82559_send,
            i82559_recv,
+           i82559_deliver,
            i82559_poll,
            i82559_int_vector);
 
@@ -1134,7 +1136,7 @@ static void ResetRxRing(struct i82559* p
 
 // ------------------------------------------------------------------------
 //
-//  Function : PacketRxReady        (Called from DSR)
+//  Function : PacketRxReady        (Called from delivery thread)
 //
 // ------------------------------------------------------------------------
 static void PacketRxReady(struct i82559* p_i82559)
@@ -1395,8 +1397,8 @@ static void TxMachine(struct i82559* p_i
     tx_descriptor_active = p_i82559->tx_descriptor_active;
     ioaddr = p_i82559->io_address;  
     
-    // See if the CU is idle when we think it isn't:
-    // (Recovers from a dropped interrupt)
+    // See if the CU is idle when we think it isn't; this is the only place
+    // tx_descriptor_active is advanced. (Also recovers from a dropped intr)
     if ( p_i82559->tx_in_progress ) {
         cyg_uint16 status;
         status = INW(ioaddr + SCBStatus);
@@ -1435,7 +1437,7 @@ static void TxMachine(struct i82559* p_i
 
 // ------------------------------------------------------------------------
 //
-//  Function : TxDone          (Called from DSR)
+//  Function : TxDone          (Called from delivery thread)
 //
 // This returns Tx's from the Tx Machine to the stack (ie. reports
 // completion) - allowing for missed interrupts, and so on.
@@ -1607,6 +1609,9 @@ i82559_send(struct eth_drv_sc *sc,
             tx_descriptor_add = 0;
         p_i82559->tx_descriptor_add = tx_descriptor_add;
 
+        // From this instant, interrupts can advance the world and start,
+        // even complete, this tx request...
+
         if ( p_i82559->tx_descriptor_remove == tx_descriptor_add )
             p_i82559->tx_queue_full = 1;
     }
@@ -1618,11 +1623,17 @@ i82559_send(struct eth_drv_sc *sc,
 
     // Check that either:
     //     tx is already active, there is other stuff queued,
-    // OR  this tx just added is the current active one.
-    CYG_ASSERT( (p_i82559->tx_in_progress == 1) ||
-       ((p_i82559->tx_descriptor_add-1) == p_i82559->tx_descriptor_active)
-    || ((0 == p_i82559->tx_descriptor_add) &&
-        ((MAX_TX_DESCRIPTORS-1) == p_i82559->tx_descriptor_active)),
+    // OR  this tx just added is the current active one
+    // OR  this tx just added is already complete
+    CYG_ASSERT(
+        // The machine is busy:
+        (p_i82559->tx_in_progress == 1) ||
+        // or: The machine is idle and this just added is the next one
+        (((p_i82559->tx_descriptor_add-1) == p_i82559->tx_descriptor_active)
+         || ((0 == p_i82559->tx_descriptor_add) &&
+             ((MAX_TX_DESCRIPTORS-1) == p_i82559->tx_descriptor_active))) ||
+        // or: This tx is already complete
+        (p_i82559->tx_descriptor_add == p_i82559->tx_descriptor_active),
                 "Active/add mismatch" );
 
     // Advance TxMachine atomically
@@ -1732,10 +1743,23 @@ static cyg_uint32 eth_mux_isr(cyg_vector
 
 // ------------------------------------------------------------------------
 
+static 
 void eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
 {
     struct i82559* p_i82559 = (struct i82559 *)data;
-
+    struct cyg_netdevtab_entry *ndp =
+        (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+    struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+    // but here, it must be a *sc:
+    eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+}
+
+// ------------------------------------------------------------------------
+// This is called from the function below (used to be uni-DSR)
+static inline void
+uni_deliver(struct i82559* p_i82559)
+{
     // First pass any rx data up the stack
     PacketRxReady(p_i82559);
 
@@ -1745,17 +1769,18 @@ void eth_dsr(cyg_vector_t vector, cyg_uc
 
 
 // ------------------------------------------------------------------------
-void eth_mux_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+void i82559_deliver(struct eth_drv_sc *sc)
 {
+    struct i82559* p_i82559;
     int device_index = mux_device_index;
-    struct i82559* p_i82559;
+
+    // Since this must mux both devices, the incoming arg is ignored.
 
     mux_device_index ^= 1; // look at the other one first next time.
-                           // (non-atomicity wrt IRQ does not matter)
     do {
         p_i82559 = &i82559[device_index];
         if ( p_i82559->active )
-            eth_dsr( vector, count, (cyg_addrword_t)p_i82559 );
+            uni_deliver( p_i82559 );
         device_index ^= 1;
     } while ( device_index == mux_device_index );
 }
@@ -1777,10 +1802,13 @@ void i82559_poll(struct eth_drv_sc *sc)
 
     // As it happens, this driver always requests the DSR to be called:
     (void)eth_mux_isr( CYGNUM_HAL_INTERRUPT_PCI_IRQ, (cyg_addrword_t)p_i82559 );
-    eth_mux_dsr( CYGNUM_HAL_INTERRUPT_PCI_IRQ, 1, (cyg_addrword_t)p_i82559 );
+
+    i82559_deliver( NULL /* arg is not used */ );
 }
 
-// Determine interrupt vector used by a device
+// ------------------------------------------------------------------------
+// Determine interrupt vector used by a device - for attaching GDB stubs
+// packet handler.
 int
 i82559_int_vector(struct eth_drv_sc *sc)
 {
@@ -1879,9 +1907,9 @@ pci_init_find_82559s( void )
                     cyg_drv_interrupt_create(
                         CYGNUM_HAL_INTERRUPT_PCI_IRQ,
                         0,              // Priority - unused
-                        0,              // Data item passed to ISR (not used)
+                        (CYG_ADDRWORD)p_i82559,// Data item passed to ISR and DSR
                         eth_mux_isr,    // ISR
-                        eth_mux_dsr,    // DSR
+                        eth_dsr,        // DSR
                         &mux_interrupt_handle,
                         &mux_interrupt_object );