# HG changeset patch
# Parent a7ba4e6eae2c9086c0b9876494165bf21ad1f405
rathaxes: rewrite the {create,destroy}_device functions in the e1000 sample

diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
--- a/rathaxes/samples/e1000/e1000.blt
+++ b/rathaxes/samples/e1000/e1000.blt
@@ -1,4 +1,4 @@
-with e1000, Ethernet, Socket, PCI, LKM, Log
+with e1000, Ethernet, Socket, PCI, LKM, Log, Builtin
 {
     template type   e1000::RxDescriptor()
     {
@@ -288,7 +288,7 @@
             {
                 int                         bars;
                 unsigned char /* __iomem */ *ioaddr;
-                int                         irq;
+                unsigned int                irq;
 
                 /* we can't use the Rathaxes type here (#8) */
                 //${e1000::RxRing}    rx_ring;
@@ -298,8 +298,11 @@
             };
         }
 
-        chunk   ::init()
+        chunk   ::init(Builtin::number bars, Builtin::number ioaddr, Builtin::number irq)
         {
+            ${self}->bars = ${bars};
+            ${self}->ioaddr = ${ioaddr};
+            ${self}->irq = irq;
         }
 
         map
@@ -479,40 +482,16 @@
 
     template sequence   e1000::create_device()
     {
-        chunk Ethernet::create_device(PCI::AbstractDevice pdev, Ethernet::Device rtx_ether_ctx)
+        chunk Ethernet::create_device(Ethernet::Device rtx_ether_ctx,
+                                      Builtin::number bars,
+                                      Builtin::number ioaddr,
+                                      Builtin::number irq)
         {
-            /*
-             * PCI init stuff:
-             *
-             * Some of that code should certainly be moved in the PCI/Ethernet
-             * blts, also at some point maybe we could do that completely
-             * automatically in the PCI/Ethernet blts.
-             */
+            /* XXX: Use the rathaxes type directly here (#51): */
+            struct rtx_e1000_ctx *hw_ctx = &${rtx_ether_ctx}->hw_ctx;
+            ${cast local.hw_ctx as e1000::Context};
 
-            /*
-             * We could have used an init function here but since we can't init
-             * all the fields at once (see, ioaddr) and cannot call a C
-             * function within a placeholder (${}), it wasn't really worth it.
-             */
-            ${rtx_ether_ctx}->hw_ctx.bars = pci_select_bars(${pdev}, IORESOURCE_MEM);
-            ${rtx_ether_ctx}->hw_ctx.irq = ${pdev}->irq;
-
-            if (pci_enable_device_mem(${pdev}))
-                ${Log::info("e1000::create: pci_enable_device_mem failed")};
-            if (pci_request_selected_regions(${pdev}, ${rtx_ether_ctx}->hw_ctx.bars, ${config.name}))
-                ${Log::info("e1000::create: pci_request_selected_regions failed")};
-            if (${config.set_master})
-                pci_set_master(${pdev});
-
-            /* 0 here is for BAR_0: */
-            ${rtx_ether_ctx}->hw_ctx.ioaddr = pci_ioremap_bar(${pdev}, 0);
-            if (!${rtx_ether_ctx}->hw_ctx.ioaddr)
-                ${Log::info("e1000::create: pci_ioremap_bar failed")};
-
-            /*
-             * The really device specific algorithm starts here (so it should
-             * certainly be written in the frontend):
-             */
+            ${local.hw_ctx.init(bars, ioaddr, irq)};
 
             /* Reset the card */
             rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_CTRL, E1000_CMD_RST);
@@ -533,6 +512,7 @@
                 ${rtx_ether_ctx}->net_dev->dev_addr[i * 2 + 1] = (value >> 8) & 0xff;
             }
 
+            /* XXX: use ${rtx_ether_ctx.set_mac_address()}; : */
             memcpy(${rtx_ether_ctx}->net_dev->perm_addr,
                    ${rtx_ether_ctx}->net_dev->dev_addr,
                    ${rtx_ether_ctx}->net_dev->addr_len);
diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti
--- a/rathaxes/samples/e1000/e1000.rti
+++ b/rathaxes/samples/e1000/e1000.rti
@@ -1,8 +1,5 @@
 interface e1000 : Socket, Ethernet, PCI, LKM, Builtin
 {
-    /* XXX: This should be in pci.rti, also maybe we need a bool type */
-    required variable   Builtin::symbol set_master;
-
     required variable   Builtin::number rx_ring_size;
     required variable   Builtin::number tx_ring_size;
     required variable   Builtin::number rx_buffer_len;
@@ -12,7 +9,8 @@
     {
         chunk       Ethernet::SubContext();
         method      decl();
-        method      init();
+        /* XXX: used types: */
+        method      init(Builtin::number, Builtin::number, Builtin::number);
     }
 
     provided type   RxDescriptor
diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt
--- a/rathaxes/samples/e1000/ethernet.blt
+++ b/rathaxes/samples/e1000/ethernet.blt
@@ -111,6 +111,13 @@
             ${self}->net_dev = ${net_dev};
         }
 
+        chunk set_mac_address(Builtin::number addr)
+        {
+            memcpy(${self}->net_dev->perm_addr,
+                   ${self}->net_dev->dev_addr,
+                   ${self}->net_dev->addr_len);
+        }
+
         map
         {
         }
@@ -249,9 +256,26 @@
             /* Initialize our context held by the net_device structure */
             ${rtx_ether_ctx.init(local.net_dev, pdev)};
 
+            /* XXX: The following code should probably part of PCI:: */
+
             pci_set_drvdata(${pdev}, net_dev);
 
-            ${pointcut Ethernet::create_device(pdev, local.rtx_ether_ctx)};
+            int bars = pci_select_bars(${pdev}, IORESOURCE_MEM);
+
+            if (pci_enable_device_mem(${pdev}))
+                ${Log::info("pci_enable_device_mem failed")};
+            if (pci_request_selected_regions(${pdev}, bars, ${config.name}))
+                ${Log::info("pci_request_selected_regions failed")};
+            if (${config.set_master})
+                pci_set_master(${pdev});
+
+            /* 0 here is for BAR_0: */
+            unsigned char /* __iomem */ *ioaddr = pci_ioremap_bar(${pdev}, 0);
+            if (!ioaddr)
+                ${Log::info("pci_ioremap_bar failed")};
+
+            unsigned int irq = net_dev->irq;
+            ${pointcut Ethernet::create_device(local.rtx_ether_ctx, local.bars, local.ioaddr, local.irq)};
         }
 
         /* This chunk should be removed (see #26) */
diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti
--- a/rathaxes/samples/e1000/ethernet.rti
+++ b/rathaxes/samples/e1000/ethernet.rti
@@ -1,5 +1,8 @@
-interface Ethernet : Socket, PCI, LKM
+interface Ethernet : Socket, PCI, LKM, Builtin
 {
+    /* XXX: This should be in pci.rti, also maybe we need a bool type */
+    required variable   Builtin::symbol set_master;
+
     required variable   Builtin::string ifname;
 
      provided type   ProtocolId
@@ -22,6 +25,8 @@
         chunk       LKM::includes();
         method      decl();
         method      init(Ethernet::AbstractDevice, PCI::AbstractDevice);
+        method      set_mac_address(Builtin::number);
+
         pointcut    Ethernet::SubContext();
     }
 
@@ -54,7 +59,10 @@
         provided chunk  LKM::data();
         provided chunk  PCI::pci_probe_hook(PCI::AbstractDevice);
 
-        provided pointcut   Ethernet::create_device(PCI::AbstractDevice, Ethernet::Device);
+        provided pointcut   Ethernet::create_device(Ethernet::Device,
+                                                    Builtin::number,
+                                                    Builtin::number,
+                                                    Builtin::number);
     }
 
     provided sequence   exit()
