changeset 2102:ede282e6434e

* src/if_dm9000.c, include/dm9000_info.h: Support interrupts. * cdl/davicom_dm9000_eth_drivers.cdl (CYGPKG_DEVS_ETH_DAVICOM_DM9000_CFLAGS_ADD): Need _KERNEL and __ECOS defined for non-stand-alone builds.
author asl
date Mon, 07 Nov 2005 17:15:06 +0000
parents b3747ba64a2d
children 9169038683a3
files packages/devs/eth/davicom/dm9000/current/ChangeLog packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c
diffstat 4 files changed, 54 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/eth/davicom/dm9000/current/ChangeLog
+++ b/packages/devs/eth/davicom/dm9000/current/ChangeLog
@@ -1,3 +1,10 @@
+2005-11-07  David Vrabel <dvrabel@arcom.com>
+
+	* src/if_dm9000.c, include/dm9000_info.h: Support interrupts.
+	* cdl/davicom_dm9000_eth_drivers.cdl
+	(CYGPKG_DEVS_ETH_DAVICOM_DM9000_CFLAGS_ADD): Need _KERNEL and
+	__ECOS defined for non-stand-alone builds.
+
 2005-10-25  David Vrabel <dvrabel@arcom.com>
 
 	* src/if_dm9000.c (eeprom_read, eeprom_write, eeprom_reload):
--- a/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl
+++ b/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl
@@ -94,7 +94,7 @@ cdl_package CYGPKG_DEVS_ETH_DAVICOM_DM90
             display "Additional compiler flags"
             flavor  data
             no_define
-            default_value { "" }
+            default_value { "-D_KERNEL -D__ECOS" }
             description   "
                 This option modifies the set of compiler flags for
                 building the Davicom DM9000 ethernet driver package.
--- a/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h
+++ b/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h
@@ -61,9 +61,14 @@ struct dm9000 {
     unsigned long txkey;
     volatile unsigned char *io_addr;  // addr register
     volatile unsigned char *io_data;  // data register
+    cyg_vector_t interrupt;           // Interrupt vector used by controller
     int (*read_data)(struct dm9000 *p, cyg_uint8 *dest);
     int (*write_data)(struct dm9000 *p, cyg_uint8 *src);
     int buswidth;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+    cyg_handle_t  interrupt_handle;
+    cyg_interrupt interrupt_object;
+#endif
 };
 
 #define CYGDAT_DEVS_ETH_DESCRIPTION "Davicom DM9000 Ethernet"
--- a/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c
+++ b/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c
@@ -53,6 +53,7 @@
 #include <pkgconf/system.h>
 #include <pkgconf/io_eth_drivers.h>
 #include <pkgconf/devs_eth_davicom_dm9000.h>
+
 #include <cyg/infra/cyg_type.h>
 #include <cyg/infra/cyg_ass.h>
 #include <cyg/hal/hal_arch.h>
@@ -447,6 +448,19 @@ static int initialize_nic(struct dm9000 
     return 1;
 }
 
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32 dm9000_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+    cyg_drv_interrupt_mask(priv->interrupt);
+    cyg_drv_interrupt_acknowledge(priv->interrupt);
+
+    return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+#endif
+
 
 // ------------------------------------------------------------------------
 //
@@ -480,6 +494,19 @@ dm9000_init(struct cyg_netdevtab_entry *
     if (id != 0x90000A46)
 	return 0;
 
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+    cyg_drv_interrupt_create(priv->interrupt,
+                             0,
+                             (cyg_addrword_t)sc,
+                             dm9000_isr,
+                             eth_drv_dsr,
+                             &priv->interrupt_handle,
+                             &priv->interrupt_object);
+    cyg_drv_interrupt_attach(priv->interrupt_handle);
+    cyg_drv_interrupt_acknowledge(priv->interrupt);
+    cyg_drv_interrupt_unmask(priv->interrupt);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+
     for (i = 0; i < 64; i++)
 	u16tab[i] = eeprom_read(priv, i);
 
@@ -683,6 +710,9 @@ dm9000_send(struct eth_drv_sc *sc,
     save_len = total_len;
     tail_extra = 0;
 
+    /* Disable all interrupts */
+    putreg(priv, DM_IMR, IMR_PAR);
+
     HAL_WRITE_UINT8(priv->io_addr, DM_MWCMD);
 
     while (total_len > 0) {
@@ -734,6 +764,9 @@ dm9000_send(struct eth_drv_sc *sc,
     putreg(priv, DM_TXPLH, save_len >> 8);
 
     putreg(priv, DM_TCR, TCR_TXREQ);
+
+    /* Re-enable interrupt */
+    putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
 }
 
 // ------------------------------------------------------------------------
@@ -853,7 +886,13 @@ dm9000_poll(struct eth_drv_sc *sc)
 static void
 dm9000_deliver(struct eth_drv_sc *sc)
 {
+    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
     dm9000_poll(sc);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+    cyg_drv_interrupt_unmask(priv->interrupt);
+#endif
 }
 
 // ------------------------------------------------------------------------
@@ -864,10 +903,9 @@ dm9000_deliver(struct eth_drv_sc *sc)
 static int
 dm9000_int_vector(struct eth_drv_sc *sc)
 {
-    struct dm9000 *priv;
-    priv = (struct dm9000 *)sc->driver_private;
+    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
 
-    return -1;
+    return priv->interrupt;
 }