changeset 38:f43900ad7e66

Fold All The Patches on the LKM Sample
author Louis Opter <louis@lse.epitech.net>
date Sun, 08 Jan 2012 01:51:34 +0100
parents 9433dec37a52
children d761c8c625d3
files e1000_rework_without_explicit_call.patch ethernet_rework_without_explicit_call.patch pci_rework_without_explicit_call.patch rathaxes_add_a_linux_lkm.patch rathaxes_add_lkm_ethernet_sample.patch rathaxes_start_to_implement_pci_stuff_in_the_lkm.patch rathaxes_start_to_implement_sk_buff_in_the_lkm.patch rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch series
diffstat 9 files changed, 741 insertions(+), 1720 deletions(-) [+]
line wrap: on
line diff
--- a/e1000_rework_without_explicit_call.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-# HG changeset patch
-# Parent 1cfa6a46c673fae191ce982e2ebd471f9a53ee90
-rathaxes: initialize the e1000 sepcific code in an elegant implicit way
-
-diff -r 1cfa6a46c673 rathaxes/samples/lkm/e1000.blt
---- a/rathaxes/samples/lkm/e1000.blt	Sun Jan 08 01:01:14 2012 +0100
-+++ b/rathaxes/samples/lkm/e1000.blt	Sun Jan 08 01:02:13 2012 +0100
-@@ -27,9 +27,9 @@
-         }
-     }
- 
--    template sequence   e1000::create()
-+    template sequence   e1000::create_device()
-     {
--        chunk ::CALL
-+        chunk Ethernet::create_device()
-         {
-             rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM);
-             if (pci_enable_device_mem(pdev))
-@@ -54,18 +54,25 @@
-                 ${Log::info("e1000::create: pci_ioremap_bar failed")};
-             }
-         }
-+
-+        chunk ::CALL
-+        {
-+        }
-     }
- 
--    template sequence   e1000::destroy()
-+    template sequence   e1000::destroy_device()
-     {
--        chunk ::CALL
-+        chunk   Ethernet::destroy_device
-         {
-             // XXX: add a check in order to avoid freeing none allocated
-             // resources.
-             struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev);
-             iounmap(rtx_ether_ctx->hw_ctx.ioaddr);
-             pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars);
--            pci_release_region(pdev, 0);
-+        }
-+
-+        chunk   ::CALL
-+        {
-         }
-     }
- }
-diff -r 1cfa6a46c673 rathaxes/samples/lkm/e1000.rti
---- a/rathaxes/samples/lkm/e1000.rti	Sun Jan 08 01:01:14 2012 +0100
-+++ b/rathaxes/samples/lkm/e1000.rti	Sun Jan 08 01:02:13 2012 +0100
-@@ -3,13 +3,15 @@
-     provided type   e1000::Context;
- 
-     /* Not sure if we need the argument */
--    provided sequence   e1000::create()
-+    provided sequence   e1000::create_device()
-     {
-+        provided chunk  Ethernet::create_device;
-         provided chunk  ::CALL;
-     }
- 
--    provided sequence   e1000::destroy()
-+    provided sequence   e1000::destroy_device()
-     {
-+        provided chunk  Ethernet::destroy_device;
-         provided chunk  ::CALL;
-     }
- }
-diff -r 1cfa6a46c673 rathaxes/samples/lkm/ethernet.blt
---- a/rathaxes/samples/lkm/ethernet.blt	Sun Jan 08 01:01:14 2012 +0100
-+++ b/rathaxes/samples/lkm/ethernet.blt	Sun Jan 08 01:02:13 2012 +0100
-@@ -173,6 +173,7 @@
-             /* same problem as above with ${pdev} */
-             //pci_set_drvdata(${pdev}, net_dev);
-             pci_set_drvdata(pdev, net_dev);
-+            ${pointcut Ethernet::create_device};
-         }
- 
-         chunk   ::CALL
-@@ -186,6 +187,8 @@
-         {
-             struct net_device *net_dev = pci_get_drvdata(pdev);
- 
-+            ${pointcut Ethernet::destroy_device};
-+
-             unregister_netdev(net_dev);
-             /*
-              * If we had some cleanup todo with struct rtx_ether_ctx we would
-diff -r 1cfa6a46c673 rathaxes/samples/lkm/ethernet.rti
---- a/rathaxes/samples/lkm/ethernet.rti	Sun Jan 08 01:01:14 2012 +0100
-+++ b/rathaxes/samples/lkm/ethernet.rti	Sun Jan 08 01:02:13 2012 +0100
-@@ -33,6 +33,8 @@
-         provided chunk  LKM::data;
-         provided chunk  PCI::pci_probe_hook;
-         provided chunk  ::CALL;
-+
-+        provided pointcut   Ethernet::create_device;
-     }
- 
-     /* Likely extends PCI::remove */
-@@ -40,5 +42,7 @@
-     {
-         provided chunk  ::CALL;
-         provided chunk  PCI::pci_remove_hook;
-+
-+        provided pointcut   Ethernet::destroy_device;
-     }
- }
-diff -r 1cfa6a46c673 rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx	Sun Jan 08 01:01:14 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rtx	Sun Jan 08 01:02:13 2012 +0100
-@@ -20,30 +20,14 @@
-         Log::info("We have one packet to transmit!");
-     }
- 
--//    PCI::probe(PCI::Device dev)
--//    {
--//        Log::info("Probe the device");
--//        Ethernet::init(dev);
--//        e1000::create();
--//    }
--
--//    PCI::remove(PCI::Device dev)
--//    {
--//        Log::info("Remove the pci device");
--//        e1000::destroy();
--//        Ethernet::exit(dev);
--//    }
--
-     LKM::init()
-     {
-         Log::info("Hello this is LKM");
--        // PCI::register();
-     }
- 
-     LKM::exit()
-     {
-         Log::info("Good bye this was LKM");
--        // PCI::unregister();
-     }
- }
- 
--- a/ethernet_rework_without_explicit_call.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-# HG changeset patch
-# Parent 4920b3a97ad6f031437c63ca3ae756678fde92a3
-rathaxes: initialize the ethernet subsystem in an elegant implicit way
-
-diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/e1000.blt
---- a/rathaxes/samples/lkm/e1000.blt	Sat Jan 07 23:09:24 2012 +0100
-+++ b/rathaxes/samples/lkm/e1000.blt	Sun Jan 08 00:13:22 2012 +0100
-@@ -62,7 +62,6 @@
-         {
-             // XXX: add a check in order to avoid freeing none allocated
-             // resources.
--            struct net_device *net_dev = pci_get_drvdata(pdev);
-             struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev);
-             iounmap(rtx_ether_ctx->hw_ctx.ioaddr);
-             pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars);
-diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/ethernet.blt
---- a/rathaxes/samples/lkm/ethernet.blt	Sat Jan 07 23:09:24 2012 +0100
-+++ b/rathaxes/samples/lkm/ethernet.blt	Sun Jan 08 00:13:22 2012 +0100
-@@ -125,7 +125,7 @@
-             };
-         }
- 
--        chunk ::CALL
-+        chunk PCI::pci_probe_hook()
-         {
-             /*
-              * This typedef is needed to workaround a bug in CNorm __std__
-@@ -174,12 +174,18 @@
-             //pci_set_drvdata(${pdev}, net_dev);
-             pci_set_drvdata(pdev, net_dev);
-         }
-+
-+        chunk   ::CALL
-+        {
-+        }
-     }
- 
-     template sequence   Ethernet::exit(PCI::Device pdev)
-     {
--        chunk ::CALL
-+        chunk   PCI::pci_remove_hook()
-         {
-+            struct net_device *net_dev = pci_get_drvdata(pdev);
-+
-             unregister_netdev(net_dev);
-             /*
-              * If we had some cleanup todo with struct rtx_ether_ctx we would
-@@ -187,5 +193,10 @@
-              */
-             free_netdev(net_dev);
-         }
-+
-+        chunk ::CALL
-+        {
-+        }
-     }
- }
-+
-diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/ethernet.rti
---- a/rathaxes/samples/lkm/ethernet.rti	Sat Jan 07 23:09:24 2012 +0100
-+++ b/rathaxes/samples/lkm/ethernet.rti	Sun Jan 08 00:13:22 2012 +0100
-@@ -28,10 +28,10 @@
-         provided chunk  LKM::code;
-     }
- 
--    /* Kinda extends PCI::probe */
-     provided sequence   Ethernet::init(PCI::Device)
-     {
-         provided chunk  LKM::data;
-+        provided chunk  PCI::pci_probe_hook;
-         provided chunk  ::CALL;
-     }
- 
-@@ -39,5 +39,6 @@
-     provided sequence   Ethernet::exit(PCI::Device)
-     {
-         provided chunk  ::CALL;
-+        provided chunk  PCI::pci_remove_hook;
-     }
- }
-diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 23:09:24 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rtx	Sun Jan 08 00:13:22 2012 +0100
-@@ -20,19 +20,19 @@
-         Log::info("We have one packet to transmit!");
-     }
- 
--    PCI::probe(PCI::Device dev)
--    {
--        Log::info("Probe the device");
--        Ethernet::init(dev);
--        e1000::create();
--    }
-+//    PCI::probe(PCI::Device dev)
-+//    {
-+//        Log::info("Probe the device");
-+//        Ethernet::init(dev);
-+//        e1000::create();
-+//    }
- 
--    PCI::remove(PCI::Device dev)
--    {
--        Log::info("Remove the pci device");
--        e1000::destroy();
--        Ethernet::exit(dev);
--    }
-+//    PCI::remove(PCI::Device dev)
-+//    {
-+//        Log::info("Remove the pci device");
-+//        e1000::destroy();
-+//        Ethernet::exit(dev);
-+//    }
- 
-     LKM::init()
-     {
-diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/pci.blt
---- a/rathaxes/samples/lkm/pci.blt	Sat Jan 07 23:09:24 2012 +0100
-+++ b/rathaxes/samples/lkm/pci.blt	Sun Jan 08 00:13:22 2012 +0100
-@@ -53,7 +53,7 @@
-                 if (err < 0)
-                     goto fail;
- 
--                ${pointcut ::IMPLEMENTATION};
-+                ${pointcut PCI::pci_probe_hook};
- 
-                 return 0;
- 
-@@ -61,6 +61,10 @@
-                     return err;
-             }
-         }
-+
-+        chunk   ::CALL
-+        {
-+        }
-     }
- 
-     template sequence   PCI::remove(PCI::Device pdev)
-@@ -74,11 +78,15 @@
-         {
-             static void rtx_pci_remove(struct pci_dev *pdev)
-             {
--                ${pointcut ::IMPLEMENTATION};
-+                ${pointcut PCI::pci_remove_hook};
- 
-                 pci_disable_device(pdev);
-             }
-         }
-+
-+        chunk   ::CALL()
-+        {
-+        }
-     }
- 
-     template sequence   PCI::register()
-diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/pci.rti
---- a/rathaxes/samples/lkm/pci.rti	Sat Jan 07 23:09:24 2012 +0100
-+++ b/rathaxes/samples/lkm/pci.rti	Sun Jan 08 00:13:22 2012 +0100
-@@ -23,15 +23,19 @@
-         provided chunk  LKM::deinit_bus_hook;
-     }
- 
--    required sequence   PCI::probe(PCI::Device)
-+    provided sequence   PCI::probe(PCI::Device)
-     {
-         provided chunk  LKM::prototypes;
-         provided chunk  LKM::code;
-+
-+        provided pointcut   PCI::pci_probe_hook;
-     }
- 
--    required sequence   PCI::remove(PCI::Device)
-+    provided sequence   PCI::remove(PCI::Device)
-     {
-         provided chunk  LKM::prototypes;
-         provided chunk  LKM::code;
-+
-+        provided pointcut   PCI::pci_remove_hook;
-     }
- }
--- a/pci_rework_without_explicit_call.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-# HG changeset patch
-# Parent c5c98e265bb4cf5c3a9d775e56d6599ca73a4c73
-rathaxes: initialize the pci bus in an elegant implicit way
-
-diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/lkm.blt
---- a/rathaxes/samples/lkm/lkm.blt	Sat Jan 07 22:45:07 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.blt	Sat Jan 07 23:09:24 2012 +0100
-@@ -33,6 +33,7 @@
-             static int __attribute__((__section__(".init.text")))  rtx_module_init(void)
-             {
-                 ${pointcut ::IMPLEMENTATION};
-+                ${pointcut LKM::init_bus_hook};
- 
-                 return 0;
-             }
-@@ -48,6 +49,7 @@
-             static void __attribute__((__section__(".exit.text")))   rtx_module_exit(void)
-             {
-                 ${pointcut ::IMPLEMENTATION};
-+                ${pointcut LKM::deinit_bus_hook};
-             }
- 
-             module_exit(rtx_module_exit);
-diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/lkm.rti
---- a/rathaxes/samples/lkm/lkm.rti	Sat Jan 07 22:45:07 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rti	Sat Jan 07 23:09:24 2012 +0100
-@@ -12,12 +12,14 @@
- 
-     required sequence   LKM::init()
-     {
--        provided chunk  LKM::includes;
--        provided chunk  LKM::code;
-+        provided chunk      LKM::includes;
-+        provided chunk      LKM::code;
-+        provided pointcut   LKM::init_bus_hook;
-     }
- 
-     required sequence   LKM::exit()
-     {
--        provided chunk  LKM::code;
-+        provided chunk      LKM::code;
-+        provided pointcut   LKM::deinit_bus_hook;
-     }
- }
-diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 22:45:07 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 23:09:24 2012 +0100
-@@ -37,13 +37,13 @@
-     LKM::init()
-     {
-         Log::info("Hello this is LKM");
--        PCI::register();
-+        // PCI::register();
-     }
- 
-     LKM::exit()
-     {
-         Log::info("Good bye this was LKM");
--        PCI::unregister();
-+        // PCI::unregister();
-     }
- }
- 
-diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/pci.blt
---- a/rathaxes/samples/lkm/pci.blt	Sat Jan 07 22:45:07 2012 +0100
-+++ b/rathaxes/samples/lkm/pci.blt	Sat Jan 07 23:09:24 2012 +0100
-@@ -102,7 +102,7 @@
-             };
-         }
- 
--        chunk ::CALL
-+        chunk LKM::init_bus_hook()
-         {
-             /*
-              * So how do we use the return value in the parent context?
-@@ -116,13 +116,22 @@
-                  return error;
-             }
-         }
-+
-+        chunk ::CALL()
-+        {
-+            // no implementation, we just need to instrument the lkm::bus_hook
-+        }
-     }
- 
-     template sequence   PCI::unregister()
-     {
--        chunk ::CALL
-+        chunk   LKM::deinit_bus_hook()
-         {
-             pci_unregister_driver(&rtx_pci_driver);
-         }
-+
-+        chunk ::CALL
-+        {
-+        }
-     }
- }
-diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/pci.rti
---- a/rathaxes/samples/lkm/pci.rti	Sat Jan 07 22:45:07 2012 +0100
-+++ b/rathaxes/samples/lkm/pci.rti	Sat Jan 07 23:09:24 2012 +0100
-@@ -7,13 +7,20 @@
- 
-     provided sequence   PCI::register()
-     {
-+        // it is impossible to provide a "dummy" sequence
-+        // which just hook itself. The PCI:register juste
-+        // inject its code in the module_init function
-+        // in order to load the pci driver.
-+        // Everything is done with the configuration.
-         provided chunk  ::CALL;
-         provided chunk  LKM::data;
-+        provided chunk  LKM::init_bus_hook;
-     }
- 
-     provided sequence   PCI::unregister()
-     {
-         provided chunk  ::CALL;
-+        provided chunk  LKM::deinit_bus_hook;
-     }
- 
-     required sequence   PCI::probe(PCI::Device)
--- a/rathaxes_add_a_linux_lkm.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-# HG changeset patch
-# Parent 9006ed3c5074b918e2f824b0053b494e2a82dbb8
-rathaxes: add a kernel module sample (for now Linux only)
-
-diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt
---- a/rathaxes/samples/CMakeLists.txt
-+++ b/rathaxes/samples/CMakeLists.txt
-@@ -1,2 +1,3 @@
- ADD_SUBDIRECTORY(helloworld)
-+ADD_SUBDIRECTORY(lkm)
- ADD_SUBDIRECTORY(syntax)
-diff --git a/rathaxes/samples/lkm/CMakeLists.txt b/rathaxes/samples/lkm/CMakeLists.txt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/CMakeLists.txt
-@@ -0,0 +1,3 @@
-+ADD_RATHAXES_SOURCES(lkm lkm.rtx
-+                     RTI log.rti lkm.rti
-+                     BLT log.blt lkm.blt)
-diff --git a/rathaxes/samples/lkm/lkm.blt b/rathaxes/samples/lkm/lkm.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/lkm.blt
-@@ -0,0 +1,47 @@
-+with LKM
-+{
-+    ${pointcut LKM::includes};
-+    ${pointcut LKM::init};
-+    ${pointcut LKM::exit};
-+
-+    template sequence   LKM::init()
-+    {
-+        chunk   LKM::includes()
-+        {
-+            #include <linux/module.h>
-+            #include <linux/kernel.h>
-+            typedef int  lkm_headers_include_stamp;
-+
-+            MODULE_DESCRIPTION(${config.description});
-+            MODULE_AUTHOR(${config.author});
-+            MODULE_LICENSE(${config.license});
-+        }
-+
-+        chunk   LKM::init()
-+        {
-+            /*
-+             * Rathaxes doesn't yet support arbitrary "decorators" like __init
-+             * or __exit.
-+             */
-+            static int __attribute__((__section__(.init.text)))  rtx_module_init(void)
-+            {
-+                ${pointcut ::IMPLEMENTATION};
-+            }
-+
-+            module_init(rtx_module_init);
-+        }
-+    }
-+
-+    template sequence   LKM::exit()
-+    {
-+        chunk   LKM::exit
-+        {
-+            static void __attribute((__section__(.exit.text)))   rtx_module_exit(void)
-+            {
-+                ${pointcut ::IMPLEMENTATION};
-+            }
-+
-+            module_exit(rtx_module_init);
-+        }
-+    }
-+}
-diff --git a/rathaxes/samples/lkm/lkm.rti b/rathaxes/samples/lkm/lkm.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/lkm.rti
-@@ -0,0 +1,21 @@
-+interface LKM
-+{
-+    provided pointcut   LKM::includes;
-+    provided pointcut   LKM::init;
-+    provided pointcut   LKM::exit;
-+
-+    required variable ::string  LKM::author;
-+    required variable ::string  LKM::description;
-+    required variable ::string  LKM::license;
-+
-+    required sequence   LKM::init()
-+    {
-+        provided chunk  LKM::includes;
-+        provided chunk  LKM::init;
-+    }
-+
-+    required sequence   LKM::exit()
-+    {
-+        provided chunk  LKM::exit;
-+    }
-+}
-diff --git a/rathaxes/samples/lkm/lkm.rtx b/rathaxes/samples/lkm/lkm.rtx
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/lkm.rtx
-@@ -0,0 +1,19 @@
-+device LKM use LKM, Log
-+{
-+    LKM::init()
-+    {
-+        Log::info("Hello this is LKM");
-+    }
-+
-+    LKM::exit()
-+    {
-+        Log::info("Good bye this was LKM");
-+    }
-+}
-+
-+configuration
-+{
-+    LKM::author = "Rathaxes";
-+    LKM::description = "Hello World Loadable Kernel Module (LKM)";
-+    LKM::license = "BSD";
-+}
-diff --git a/rathaxes/samples/lkm/log.blt b/rathaxes/samples/lkm/log.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/log.blt
-@@ -0,0 +1,10 @@
-+with Log
-+{
-+    template sequence   Log::info(::string msg)
-+    {
-+        chunk   ::CALL
-+        {
-+            pr_info("%s\n", ${msg});
-+        }
-+    }
-+}
-diff --git a/rathaxes/samples/lkm/log.rti b/rathaxes/samples/lkm/log.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/log.rti
-@@ -0,0 +1,7 @@
-+interface Log
-+{
-+    provided sequence   Log::info(::string)
-+    {
-+        provided chunk  ::CALL;
-+    }
-+}
--- a/rathaxes_add_lkm_ethernet_sample.patch	Sun Jan 08 01:45:20 2012 +0100
+++ b/rathaxes_add_lkm_ethernet_sample.patch	Sun Jan 08 01:51:34 2012 +0100
@@ -1,40 +1,120 @@
 # HG changeset patch
-# Parent a109185dcd773ae92b98a8195b7cc91f1c1cee47
+# Parent b995d8934956b83383c144303178f3eb383d0acf
 rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver
 
+diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt
+--- a/rathaxes/samples/CMakeLists.txt
++++ b/rathaxes/samples/CMakeLists.txt
+@@ -1,2 +1,3 @@
+ ADD_SUBDIRECTORY(helloworld)
++ADD_SUBDIRECTORY(lkm)
+ ADD_SUBDIRECTORY(syntax)
+diff --git a/rathaxes/samples/lkm/CMakeLists.txt b/rathaxes/samples/lkm/CMakeLists.txt
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/lkm/CMakeLists.txt
+@@ -0,0 +1,7 @@
++ADD_RATHAXES_SOURCES(lkm lkm.rtx
++                     RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti
++                     BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt)
++
++# We can't name lkm since it's already used as the target name to generate the
++# source (with ADD_RATHAXES_SOURCES).
++ADD_RATHAXES_LKM(lkm_hello lkm)
 diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt
---- a/rathaxes/samples/lkm/e1000.blt
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/e1000.blt
-@@ -5,7 +5,7 @@
-         chunk   LKM::includes()
-         {
-             /*
--             * Force the generation of the structure in the "headers part, we
+@@ -0,0 +1,80 @@
++with e1000, Ethernet, Socket, PCI, LKM, Log
++{
++    template type   e1000::Context()
++    {
++        chunk   LKM::includes()
++        {
++            /*
 +             * Force the generation of the structure in the "headers" part, we
-              * have to do this since we do not use the structure in this blt
-              * (we hacked a bit and used it in ethernet.blt directly).
-              */
-@@ -64,8 +64,10 @@
-     {
-         chunk   Ethernet::destroy_device
-         {
--            // XXX: add a check in order to avoid freeing none allocated
--            // resources.
++             * have to do this since we do not use the structure in this blt
++             * (we hacked a bit and used it in ethernet.blt directly).
++             */
++            typedef int ${e1000::Context}; /* CNorm __std__ workaround */
++            ${e1000::Context} force_declaration_in_includes;
++        }
++
++        chunk   ::decl()
++        {
++            struct rtx_e1000_ctx
++            {
++                int                             bars;
++                unsigned char /* __iomem */     *ioaddr;
++            };
++        }
++
++        map
++        {
++        }
++    }
++
++    template sequence   e1000::create_device()
++    {
++        chunk Ethernet::create_device()
++        {
++            rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM);
++            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")};
++            }
++        }
++
++        chunk ::CALL
++        {
++        }
++    }
++
++    template sequence   e1000::destroy_device()
++    {
++        chunk   Ethernet::destroy_device
++        {
 +            /*
 +             * Here, we should have some checks to avoid to free resources that
 +             * haven't been allocated. (e.g: in case of previous errors).
 +             */
-             struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev);
-             iounmap(rtx_ether_ctx->hw_ctx.ioaddr);
-             pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars);
++            struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev);
++            iounmap(rtx_ether_ctx->hw_ctx.ioaddr);
++            pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars);
++        }
++
++        chunk   ::CALL
++        {
++        }
++    }
++}
 diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti
---- a/rathaxes/samples/lkm/e1000.rti
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/e1000.rti
-@@ -2,7 +2,14 @@
- {
-     provided type   e1000::Context;
- 
--    /* Not sure if we need the argument */
+@@ -0,0 +1,24 @@
++interface e1000 : Socket, Ethernet, PCI, LKM
++{
++    provided type   e1000::Context;
++
 +    /*
 +     * This sequence should receive an argument like Ethernet::Device, but it is
 +     * unclear about how this argument should be bound to a variable/argument in
@@ -43,138 +123,561 @@
 +     * Here again, we rely on the fact that *we* wrote the parent context and
 +     * named the C variables we need/use with the same name everywhere.
 +     */
-     provided sequence   e1000::create_device()
-     {
-         provided chunk  Ethernet::create_device;
++    provided sequence   e1000::create_device()
++    {
++        provided chunk  Ethernet::create_device;
++        provided chunk  ::CALL;
++    }
++
++    provided sequence   e1000::destroy_device()
++    {
++        provided chunk  Ethernet::destroy_device;
++        provided chunk  ::CALL;
++    }
++}
 diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt
---- a/rathaxes/samples/lkm/ethernet.blt
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/ethernet.blt
-@@ -6,8 +6,6 @@
-         {
-             #include <linux/netdevice.h>
-             #include <linux/etherdevice.h>
--
--            typedef int include_linux_net_system_stamp;
-         }
- 
-         chunk ::decl()
-@@ -93,10 +91,9 @@
-     template sequence   Ethernet::interrupt_handler(Ethernet::Device dev)
-     {
-         /*
--         * Why we can't use irqreturn_t here? (we are forced to use enum
--         * irqreturn, which is the real type).
+@@ -0,0 +1,207 @@
++with Ethernet, PCI, LKM, Log
++{
++    template type   Ethernet::Device()
++    {
++        chunk LKM::includes()
++        {
++            #include <linux/netdevice.h>
++            #include <linux/etherdevice.h>
++        }
++
++        chunk ::decl()
++        {
++            struct rtx_ethernet_dev
++            {
++                /*
++                 * I think it's useless to use the ${PCI::Device} "abstraction"
++                 * here, since we are already in a Linux specific context here.
++                 */
++                struct pci_dev          *pci_dev;
++                struct net_device       *net_dev;
++
++                /* while waiting on issue #8 */
++                struct rtx_e1000_ctx    hw_ctx;
++            };
++        }
++
++        chunk ::init(net_dev)
++        {
++            ${self} = ${net_dev};
++        }
++
++        map
++        {
++        }
++    }
++
++    template sequence   Ethernet::open(Ethernet::Device dev)
++    {
++        chunk LKM::prototypes()
++        {
++            static int  rtx_ethernet_open(struct net_device *);
++        }
++
++        chunk LKM::code()
++        {
++            static int  rtx_ethernet_open(struct net_device *dev)
++            {
++                ${pointcut ::IMPLEMENTATION};
++
++                return 0;
++            }
++        }
++    }
++
++    template sequence   Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
++    {
++        chunk LKM::prototypes()
++        {
++            static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev);
++        }
++
++        chunk LKM::code()
++        {
++            static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev)
++            {
++                ${pointcut ::IMPLEMENTATION};
++
++                return 0;
++            }
++        }
++    }
++
++    template sequence   Ethernet::close(Ethernet::Device dev)
++    {
++        chunk LKM::prototypes()
++        {
++            static int  rtx_ethernet_close(struct net_device *);
++        }
++
++        chunk LKM::code()
++        {
++            static int  rtx_ethernet_close(struct net_device *dev)
++            {
++                ${pointcut ::IMPLEMENTATION};
++
++                return 0;
++            }
++        }
++    }
++
++    template sequence   Ethernet::interrupt_handler(Ethernet::Device dev)
++    {
++        /*
 +         * We can't use the irqreturn_t type here because CNornm doesn't know
 +         * it.
-          */
--
-         chunk LKM::prototypes()
-         {
-             static enum irqreturn   rtx_ethernet_interrupt_handler(int, void *);
-@@ -141,7 +138,12 @@
-             if (net_dev == 0)
-             {
-                 ${Log::info("Cannot allocate memory")};
--                // is it the thing to do?
++         */
++        chunk LKM::prototypes()
++        {
++            static enum irqreturn   rtx_ethernet_interrupt_handler(int, void *);
++        }
++
++        chunk LKM::code()
++        {
++            static enum irqreturn   rtx_ethernet_interrupt_handler(int irq, void *dev_id)
++            {
++                ${pointcut ::IMPLEMENTATION};
++
++                return IRQ_NONE;
++            }
++        }
++    }
++
++    template sequence   Ethernet::init(PCI::Device pdev)
++    {
++        chunk LKM::data()
++        {
++            static const struct net_device_ops  rtx_ether_ops =
++            {
++                .ndo_open = rtx_ethernet_open,
++                .ndo_stop = rtx_ethernet_close,
++                .ndo_start_xmit = rtx_ethernet_xmit,
++            };
++        }
++
++        chunk PCI::pci_probe_hook()
++        {
++            /*
++             * This typedef is needed to workaround a bug in CNorm __std__
++             * dialect.
++             */
++            typedef int ${Ethernet::Device};
++            ${Ethernet::Device} *rtx_ether_ctx;
++            struct net_device   *net_dev;
++            int error;
++
++            error = 0;
++            net_dev = alloc_etherdev(sizeof(*rtx_ether_ctx));
++            if (net_dev == 0)
++            {
++                ${Log::info("Cannot allocate memory")};
 +                /*
 +                 * Again, the error should be "raised" in the parent context.
 +                 *
 +                 * Here we know that we should return ENOMEM because *we* wrote
 +                 * the parent context.
 +                 */
-                 return -ENOMEM;
-             }
-             strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name));
-@@ -166,13 +168,13 @@
-             if ((error = register_netdev(net_dev)))
-             {
-                 ${Log::info("Cannot register the driver")};
--                // is it the thing to do?
-                 return error;
-             }
- 
-             /* same problem as above with ${pdev} */
-             //pci_set_drvdata(${pdev}, net_dev);
-             pci_set_drvdata(pdev, net_dev);
++                return -ENOMEM;
++            }
++            strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name));
++            net_dev->irq = pdev->irq;
++            // Maybe we should try ${rtx_ether_ctx.init()} here:
++            rtx_ether_ctx = netdev_priv(net_dev);
++            //rtx_ether_ctx->pci_dev = ${pdev};
++            rtx_ether_ctx->pci_dev = pdev; // In the meantime do it directly
++            rtx_ether_ctx->net_dev = net_dev;
++
++            /*
++             * The substitution of ${pdev} fails here. I also tried to add a
++             * "substitute method" to the PCI::Device that was just doing
++             * "${self}" but it didn't work either (it was subsituted by a
++             * placeholder, e.g: _1).
++             *
++             * That's why we cheated a bit and named all the arguments pdev.
++             */
++            //SET_NETDEV_DEV(net_dev, &${pdev}->dev);
++            SET_NETDEV_DEV(net_dev, &pdev->dev);
++            net_dev->netdev_ops = &rtx_ether_ops;
++            if ((error = register_netdev(net_dev)))
++            {
++                ${Log::info("Cannot register the driver")};
++                return error;
++            }
++
++            /* same problem as above with ${pdev} */
++            //pci_set_drvdata(${pdev}, net_dev);
++            pci_set_drvdata(pdev, net_dev);
 +
-             ${pointcut Ethernet::create_device};
-         }
- 
++            ${pointcut Ethernet::create_device};
++        }
++
++        chunk   ::CALL
++        {
++        }
++    }
++
++    template sequence   Ethernet::exit(PCI::Device pdev)
++    {
++        chunk   PCI::pci_remove_hook()
++        {
++            struct net_device *net_dev = pci_get_drvdata(pdev);
++
++            ${pointcut Ethernet::destroy_device};
++
++            unregister_netdev(net_dev);
++            /*
++             * If we had some cleanup todo with struct rtx_ether_ctx we would
++             * do a netdev_priv(net_dev) here and do it.
++             */
++            free_netdev(net_dev);
++        }
++
++        chunk ::CALL
++        {
++        }
++    }
++}
++
 diff --git a/rathaxes/samples/lkm/ethernet.rti b/rathaxes/samples/lkm/ethernet.rti
---- a/rathaxes/samples/lkm/ethernet.rti
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/ethernet.rti
-@@ -37,7 +37,6 @@
-         provided pointcut   Ethernet::create_device;
-     }
- 
--    /* Likely extends PCI::remove */
-     provided sequence   Ethernet::exit(PCI::Device)
-     {
-         provided chunk  ::CALL;
+@@ -0,0 +1,47 @@
++interface Ethernet : Socket, PCI, LKM
++{
++    provided type       Ethernet::Device;
++
++    required variable ::string  Ethernet::ifname;
++
++    required sequence   Ethernet::open(Ethernet::Device)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++    }
++
++    required sequence   Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++    }
++
++    required sequence   Ethernet::close(Ethernet::Device)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++    }
++
++    required sequence   Ethernet::interrupt_handler(Ethernet::Device)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++    }
++
++    provided sequence   Ethernet::init(PCI::Device)
++    {
++        provided chunk  LKM::data;
++        provided chunk  PCI::pci_probe_hook;
++        provided chunk  ::CALL;
++
++        provided pointcut   Ethernet::create_device;
++    }
++
++    provided sequence   Ethernet::exit(PCI::Device)
++    {
++        provided chunk  ::CALL;
++        provided chunk  PCI::pci_remove_hook;
++
++        provided pointcut   Ethernet::destroy_device;
++    }
++}
 diff --git a/rathaxes/samples/lkm/lkm.blt b/rathaxes/samples/lkm/lkm.blt
---- a/rathaxes/samples/lkm/lkm.blt
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/lkm.blt
-@@ -12,9 +12,6 @@
-         {
-             #include <linux/module.h>
-             #include <linux/kernel.h>
--
--            typedef int  include_linux_module_stamp;
--            typedef int  include_linux_kernel_stamp;
-         }
- 
-         chunk   LKM::data()
+@@ -0,0 +1,55 @@
++with LKM
++{
++    /* Skel of the generated C file: */
++    ${pointcut LKM::includes};
++    ${pointcut LKM::prototypes};
++    ${pointcut LKM::data};
++    ${pointcut LKM::code};
++
++    template sequence   LKM::init()
++    {
++        chunk   LKM::includes()
++        {
++            #include <linux/module.h>
++            #include <linux/kernel.h>
++        }
++
++        chunk   LKM::data()
++        {
++            MODULE_DESCRIPTION(${config.description});
++            MODULE_AUTHOR(${config.author});
++            MODULE_LICENSE(${config.license});
++        }
++
++        chunk   LKM::code()
++        {
++            /*
++             * Rathaxes doesn't yet support arbitrary "decorators" like __init
++             * or __exit.
++             */
++            static int __attribute__((__section__(".init.text")))  rtx_module_init(void)
++            {
++                ${pointcut ::IMPLEMENTATION};
++                ${pointcut LKM::init_bus_hook};
++
++                return 0;
++            }
++
++            module_init(rtx_module_init);
++        }
++    }
++
++    template sequence   LKM::exit()
++    {
++        chunk   LKM::code()
++        {
++            static void __attribute__((__section__(".exit.text")))   rtx_module_exit(void)
++            {
++                ${pointcut ::IMPLEMENTATION};
++                ${pointcut LKM::deinit_bus_hook};
++            }
++
++            module_exit(rtx_module_exit);
++        }
++    }
++}
+diff --git a/rathaxes/samples/lkm/lkm.rti b/rathaxes/samples/lkm/lkm.rti
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/lkm/lkm.rti
+@@ -0,0 +1,25 @@
++interface LKM
++{
++    provided pointcut   LKM::includes;
++    /* maybe it should be possible to use chunk ::decl in sequence templates? */
++    provided pointcut   LKM::prototypes;
++    provided pointcut   LKM::data;
++    provided pointcut   LKM::code;
++
++    required variable ::string  LKM::author;
++    required variable ::string  LKM::description;
++    required variable ::string  LKM::license;
++
++    required sequence   LKM::init()
++    {
++        provided chunk      LKM::includes;
++        provided chunk      LKM::code;
++        provided pointcut   LKM::init_bus_hook;
++    }
++
++    required sequence   LKM::exit()
++    {
++        provided chunk      LKM::code;
++        provided pointcut   LKM::deinit_bus_hook;
++    }
++}
 diff --git a/rathaxes/samples/lkm/lkm.rtx b/rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/lkm.rtx
-@@ -1,4 +1,4 @@
--device LKM use LKM, PCI, Log
+@@ -0,0 +1,46 @@
 +device LKM use LKM, PCI, Ethernet, Log
- {
-     Ethernet::open(Ethernet::Device dev)
-     {
++{
++    Ethernet::open(Ethernet::Device dev)
++    {
++        Log::info("Open the device");
++    }
++
++    Ethernet::close(Ethernet::Device dev)
++    {
++        Log::info("Close the device");
++    }
++
++    Ethernet::interrupt_handler(Ethernet::Device dev)
++    {
++        Log::info("Got an interruption");
++    }
++
++    Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
++    {
++        Log::info("We have one packet to transmit!");
++    }
++
++    LKM::init()
++    {
++        Log::info("Hello this is LKM");
++    }
++
++    LKM::exit()
++    {
++        Log::info("Good bye this was LKM");
++    }
++}
++
++configuration
++{
++    LKM::name = "hello";
++    LKM::author = "Rathaxes";
++    LKM::description = "Hello World Loadable Kernel Module (LKM)";
++    LKM::license = "GPL";
++
++    PCI::vendor_id = 0x8086;
++    PCI::product_id = 0x100f;
++    PCI::set_master = true;
++
++    Ethernet::ifname = "rtx%d";
++}
+diff --git a/rathaxes/samples/lkm/log.blt b/rathaxes/samples/lkm/log.blt
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/lkm/log.blt
+@@ -0,0 +1,10 @@
++with Log
++{
++    template sequence   Log::info(::string msg)
++    {
++        chunk   ::CALL
++        {
++            pr_info("%s\n", ${msg});
++        }
++    }
++}
+diff --git a/rathaxes/samples/lkm/log.rti b/rathaxes/samples/lkm/log.rti
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/lkm/log.rti
+@@ -0,0 +1,7 @@
++interface Log
++{
++    provided sequence   Log::info(::string)
++    {
++        provided chunk  ::CALL;
++    }
++}
 diff --git a/rathaxes/samples/lkm/pci.blt b/rathaxes/samples/lkm/pci.blt
---- a/rathaxes/samples/lkm/pci.blt
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/pci.blt
-@@ -5,8 +5,6 @@
-         chunk   LKM::includes()
-         {
-             #include <linux/pci.h>
--
--            typedef int include_linux_pci_stamp;
-         }
- 
-         chunk   ::decl()
-@@ -24,16 +22,6 @@
-         }
-     }
- 
--    /*
--     * The PCI::probe sequence is a "required" sequence which means that its
--     * implementation will be done in the .rtx. Here we just define the context
--     * were this implementation will be inserted. The implementation should be
--     * able to access to the struct pci_dev (here marked as the "argument"
--     * PCI::Device). How do we bind this PCI::Device argument with the pdev
--     * struct pci_dev pointer defined in the LKM::code chunk?
--     *
--     * The only thing I can imagine is: ${pointcut ::IMPLEMENTATION(pdev)};
--     */
-     template sequence   PCI::probe(PCI::Device pdev)
-     {
-         chunk LKM::prototypes()
-@@ -112,22 +100,32 @@
- 
-         chunk LKM::init_bus_hook()
-         {
--            /*
--             * So how do we use the return value in the parent context?
--             */
-             int error;
-             if ((error = pci_register_driver(&rtx_pci_driver)))
-             {
-                  ${Log::info("Cannot register pci driver")};
--                 // should we return here.
--                 // error managmement procedure has to be determined ASAP.
+@@ -0,0 +1,143 @@
++with PCI, LKM, Log
++{
++    template type   PCI::Device()
++    {
++        chunk   LKM::includes()
++        {
++            #include <linux/pci.h>
++        }
++
++        chunk   ::decl()
++        {
++            struct pci_dev;
++        }
++
++        chunk   ::init(pci_dev)
++        {
++            ${self} = ${pci_dev};
++        }
++
++        map
++        {
++        }
++    }
++
++    template sequence   PCI::probe(PCI::Device pdev)
++    {
++        chunk LKM::prototypes()
++        {
++            static int /* __devinit */  rtx_pci_probe(struct pci_dev *,
++                                                      const struct pci_device_id *);
++        }
++
++        chunk LKM::code()
++        {
++            static int /* __devinit */  rtx_pci_probe(struct pci_dev *pdev,
++                                                      const struct pci_device_id *pdev_id)
++            {
++                int             err;
++
++                err = pci_enable_device(pdev);
++                if (err < 0)
++                    goto fail;
++
++                ${pointcut PCI::pci_probe_hook};
++
++                return 0;
++
++                fail:
++                    return err;
++            }
++        }
++
++        chunk   ::CALL
++        {
++        }
++    }
++
++    template sequence   PCI::remove(PCI::Device pdev)
++    {
++        chunk LKM::prototypes()
++        {
++            static void rtx_pci_remove(struct pci_dev *);
++        }
++
++        chunk LKM::code()
++        {
++            static void rtx_pci_remove(struct pci_dev *pdev)
++            {
++                ${pointcut PCI::pci_remove_hook};
++
++                pci_disable_device(pdev);
++            }
++        }
++
++        chunk   ::CALL()
++        {
++        }
++    }
++
++    template sequence   PCI::register()
++    {
++        chunk LKM::data()
++        {
++            /*
++             * CNorm doesn't seem to like "dynamic" arrays (i.e: you always
++             * have to specify the exact size).
++             */
++            static struct pci_device_id rtx_pci_device_table[2] = {
++                { ${config.vendor_id}, ${config.product_id}, PCI_ANY_ID, PCI_ANY_ID },
++                { 0, }
++            };
++
++            static struct pci_driver rtx_pci_driver = {
++                .name = ${config.name},
++                .id_table = rtx_pci_device_table,
++                .probe = rtx_pci_probe,
++                .remove = rtx_pci_remove
++            };
++        }
++
++        chunk LKM::init_bus_hook()
++        {
++            int error;
++            if ((error = pci_register_driver(&rtx_pci_driver)))
++            {
++                 ${Log::info("Cannot register pci driver")};
 +                 /*
 +                  * So we catched the error but how do we return it to the
 +                  * parent context?
@@ -183,13 +686,12 @@
 +                  * a coincidence (and, in this case, *we* wrote the parent
 +                  * context).
 +                  */
-                  return error;
-             }
-         }
- 
-         chunk ::CALL()
-         {
--            // no implementation, we just need to instrument the lkm::bus_hook
++                 return error;
++            }
++        }
++
++        chunk ::CALL()
++        {
 +            /*
 +             * The implementation of ::CALL is empty. This template sequence is
 +             * actually not provided nor required.
@@ -198,21 +700,100 @@
 +             * itself in the hook LKM::init_bus_hook for which this sequence
 +             * has a chunk (see above chunk).
 +             */
-         }
-     }
- 
++        }
++    }
++
++    template sequence   PCI::unregister()
++    {
++        chunk   LKM::deinit_bus_hook()
++        {
++            pci_unregister_driver(&rtx_pci_driver);
++        }
++
++        chunk ::CALL
++        {
++        }
++    }
++}
 diff --git a/rathaxes/samples/lkm/pci.rti b/rathaxes/samples/lkm/pci.rti
---- a/rathaxes/samples/lkm/pci.rti
+new file mode 100644
+--- /dev/null
 +++ b/rathaxes/samples/lkm/pci.rti
-@@ -7,11 +7,6 @@
- 
-     provided sequence   PCI::register()
-     {
--        // it is impossible to provide a "dummy" sequence
--        // which just hook itself. The PCI:register juste
--        // inject its code in the module_init function
--        // in order to load the pci driver.
--        // Everything is done with the configuration.
-         provided chunk  ::CALL;
-         provided chunk  LKM::data;
-         provided chunk  LKM::init_bus_hook;
+@@ -0,0 +1,36 @@
++interface PCI : LKM
++{
++    provided type       PCI::Device;
++
++    required variable ::number  PCI::vendor_id;
++    required variable ::number  PCI::product_id;
++
++    provided sequence   PCI::register()
++    {
++        provided chunk  ::CALL;
++        provided chunk  LKM::data;
++        provided chunk  LKM::init_bus_hook;
++    }
++
++    provided sequence   PCI::unregister()
++    {
++        provided chunk  ::CALL;
++        provided chunk  LKM::deinit_bus_hook;
++    }
++
++    provided sequence   PCI::probe(PCI::Device)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++
++        provided pointcut   PCI::pci_probe_hook;
++    }
++
++    provided sequence   PCI::remove(PCI::Device)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++
++        provided pointcut   PCI::pci_remove_hook;
++    }
++}
+diff --git a/rathaxes/samples/lkm/socket.blt b/rathaxes/samples/lkm/socket.blt
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/lkm/socket.blt
+@@ -0,0 +1,27 @@
++with Socket, LKM
++{
++    template type Socket::SKBuff()
++    {
++        chunk LKM::includes()
++        {
++            #include <linux/skbuff.h>
++        }
++
++        chunk ::decl()
++        {
++            struct sk_buff;
++        }
++
++        chunk ::init()
++        {
++        }
++
++        map
++        {
++            // some work may have to be done here in order
++            // to access to some field of the sk_buff.
++            // We should determine if all the sk_buff managment
++            // can be abstracted from the user.
++        }
++    }
++}
+diff --git a/rathaxes/samples/lkm/socket.rti b/rathaxes/samples/lkm/socket.rti
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/lkm/socket.rti
+@@ -0,0 +1,4 @@
++interface Socket : LKM
++{
++    provided type Socket::SKBuff;
++}
--- a/rathaxes_start_to_implement_pci_stuff_in_the_lkm.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,319 +0,0 @@
-# HG changeset patch
-# Parent 6e00628ccba9fd82577a8a30fe4e730bc982e987
-rathaxes: start to implement the PCI registration part in the LKM sample
-
-diff -r 6e00628ccba9 rathaxes/samples/lkm/CMakeLists.txt
---- a/rathaxes/samples/lkm/CMakeLists.txt	Sat Jan 07 19:07:39 2012 +0100
-+++ b/rathaxes/samples/lkm/CMakeLists.txt	Sat Jan 07 19:10:21 2012 +0100
-@@ -1,3 +1,7 @@
- ADD_RATHAXES_SOURCES(lkm lkm.rtx
--                     RTI log.rti lkm.rti
--                     BLT log.blt lkm.blt)
-+                     RTI log.rti lkm.rti pci.rti
-+                     BLT log.blt lkm.blt pci.blt)
-+
-+# We can't name lkm since it's already used as the target name to generate the
-+# source (with ADD_RATHAXES_SOURCES).
-+ADD_RATHAXES_LKM(lkm_hello lkm)
-diff -r 6e00628ccba9 rathaxes/samples/lkm/lkm.blt
---- a/rathaxes/samples/lkm/lkm.blt	Sat Jan 07 19:07:39 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.blt	Sat Jan 07 19:10:21 2012 +0100
-@@ -1,8 +1,10 @@
- with LKM
- {
-+    /* Skel of the generated C file: */
-     ${pointcut LKM::includes};
--    ${pointcut LKM::init};
--    ${pointcut LKM::exit};
-+    ${pointcut LKM::prototypes};
-+    ${pointcut LKM::data};
-+    ${pointcut LKM::code};
- 
-     template sequence   LKM::init()
-     {
-@@ -10,22 +12,29 @@
-         {
-             #include <linux/module.h>
-             #include <linux/kernel.h>
--            typedef int  lkm_headers_include_stamp;
- 
-+            typedef int  include_linux_module_stamp;
-+            typedef int  include_linux_kernel_stamp;
-+        }
-+
-+        chunk   LKM::data()
-+        {
-             MODULE_DESCRIPTION(${config.description});
-             MODULE_AUTHOR(${config.author});
-             MODULE_LICENSE(${config.license});
-         }
- 
--        chunk   LKM::init()
-+        chunk   LKM::code()
-         {
-             /*
-              * Rathaxes doesn't yet support arbitrary "decorators" like __init
-              * or __exit.
-              */
--            static int __attribute__((__section__(.init.text)))  rtx_module_init(void)
-+            static int __attribute__((__section__(".init.text")))  rtx_module_init(void)
-             {
-                 ${pointcut ::IMPLEMENTATION};
-+
-+                return 0;
-             }
- 
-             module_init(rtx_module_init);
-@@ -34,14 +43,14 @@
- 
-     template sequence   LKM::exit()
-     {
--        chunk   LKM::exit
-+        chunk   LKM::code()
-         {
--            static void __attribute((__section__(.exit.text)))   rtx_module_exit(void)
-+            static void __attribute__((__section__(".exit.text")))   rtx_module_exit(void)
-             {
-                 ${pointcut ::IMPLEMENTATION};
-             }
- 
--            module_exit(rtx_module_init);
-+            module_exit(rtx_module_exit);
-         }
-     }
- }
-diff -r 6e00628ccba9 rathaxes/samples/lkm/lkm.rti
---- a/rathaxes/samples/lkm/lkm.rti	Sat Jan 07 19:07:39 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rti	Sat Jan 07 19:10:21 2012 +0100
-@@ -1,8 +1,10 @@
- interface LKM
- {
-     provided pointcut   LKM::includes;
--    provided pointcut   LKM::init;
--    provided pointcut   LKM::exit;
-+    /* maybe it should be possible to use chunk ::decl in sequence templates? */
-+    provided pointcut   LKM::prototypes;
-+    provided pointcut   LKM::data;
-+    provided pointcut   LKM::code;
- 
-     required variable ::string  LKM::author;
-     required variable ::string  LKM::description;
-@@ -11,11 +13,11 @@
-     required sequence   LKM::init()
-     {
-         provided chunk  LKM::includes;
--        provided chunk  LKM::init;
-+        provided chunk  LKM::code;
-     }
- 
-     required sequence   LKM::exit()
-     {
--        provided chunk  LKM::exit;
-+        provided chunk  LKM::code;
-     }
- }
-diff -r 6e00628ccba9 rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 19:07:39 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 19:10:21 2012 +0100
-@@ -1,19 +1,35 @@
--device LKM use LKM, Log
-+device LKM use LKM, PCI, Log
- {
-+    PCI::probe(PCI::Device dev)
-+    {
-+
-+    }
-+
-+    PCI::remove(PCI::Device dev)
-+    {
-+
-+    }
-+
-     LKM::init()
-     {
-         Log::info("Hello this is LKM");
-+        PCI::register();
-     }
- 
-     LKM::exit()
-     {
-         Log::info("Good bye this was LKM");
-+        PCI::unregister();
-     }
- }
- 
- configuration
- {
-+    LKM::name = "hello";
-     LKM::author = "Rathaxes";
-     LKM::description = "Hello World Loadable Kernel Module (LKM)";
-     LKM::license = "BSD";
-+
-+    PCI::vendor_id = 0x8086;
-+    PCI::product_id = 0x100f;
- }
-diff -r 6e00628ccba9 rathaxes/samples/lkm/pci.blt
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/pci.blt	Sat Jan 07 19:10:21 2012 +0100
-@@ -0,0 +1,127 @@
-+with PCI, LKM, Log
-+{
-+    template type   PCI::Device()
-+    {
-+        chunk   LKM::includes()
-+        {
-+            #include <linux/pci.h>
-+
-+            typedef int include_linux_pci_stamp;
-+        }
-+
-+        chunk   ::decl()
-+        {
-+            struct  rtx_pci_device
-+            {
-+                struct pci_dev  *pci_dev;
-+            };
-+        }
-+
-+        chunk   ::init(pci_dev)
-+        {
-+            ${self}.pci_dev = pci_dev;
-+        }
-+
-+        map
-+        {
-+        }
-+    }
-+
-+    template sequence   PCI::probe(PCI::Device dev)
-+    {
-+        chunk LKM::prototypes()
-+        {
-+            static int /* __devinit */  rtx_pci_probe(struct pci_dev *,
-+                                                      const struct pci_device_id *);
-+        }
-+
-+        chunk LKM::code()
-+        {
-+            static int /* __devinit */  rtx_pci_probe(struct pci_dev *pdev,
-+                                                      const struct pci_device_id *pdev_id)
-+            {
-+                /* workaround for CNorm __std__ dialect, shouldn't be here */
-+                typedef int ${PCI::Device};
-+
-+                int             err;
-+                ${PCI::Device}  *dev = NULL;
-+
-+                err = pci_enable_device(pdev);
-+                if (err < 0)
-+                    goto fail;
-+
-+                ${pointcut ::IMPLEMENTATION};
-+
-+                pci_set_drvdata(pdev, dev);
-+
-+                return 0;
-+
-+                fail:
-+                    return err;
-+            }
-+        }
-+    }
-+
-+    template sequence   PCI::remove(PCI::Device dev)
-+    {
-+        chunk LKM::prototypes()
-+        {
-+            static void rtx_pci_remove(struct pci_dev *);
-+        }
-+
-+        chunk LKM::code()
-+        {
-+            static void rtx_pci_remove(struct pci_dev *pdev)
-+            {
-+                pci_disable_device(pdev);
-+
-+                ${pointcut ::IMPLEMENTATION};
-+            }
-+        }
-+    }
-+
-+    template sequence   PCI::register()
-+    {
-+        chunk LKM::data()
-+        {
-+            /*
-+             * CNorm doesn't seem to like "dynamic" arrays (i.e: you always
-+             * have to specify the exact size).
-+             */
-+            static struct pci_device_id rtx_pci_device_table[2] = {
-+                { ${config.vendor_id}, ${config.product_id}, 0, PCI_ANY_ID, PCI_ANY_ID },
-+                { 0, }
-+            };
-+
-+            static struct pci_driver rtx_pci_driver = {
-+                .name = ${config.name},
-+                .id_table = rtx_pci_device_table,
-+                .probe = rtx_pci_probe,
-+                .remove = rtx_pci_remove
-+            };
-+        }
-+
-+        chunk ::CALL
-+        {
-+            /*
-+             * So how do we use the return value in the parent context?
-+             */
-+            int error;
-+            if ((error = pci_register_driver(&rtx_pci_driver)))
-+            {
-+                 ${Log::info("Cannot register pci driver")};
-+                 // should we return here.
-+                 // error managmement procedure has to be determined ASAP.
-+                 return error;
-+            }
-+        }
-+    }
-+
-+    template sequence   PCI::unregister()
-+    {
-+        chunk ::CALL
-+        {
-+            pci_unregister_driver(&rtx_pci_driver);
-+        }
-+    }
-+}
-diff -r 6e00628ccba9 rathaxes/samples/lkm/pci.rti
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/pci.rti	Sat Jan 07 19:10:21 2012 +0100
-@@ -0,0 +1,30 @@
-+interface PCI : LKM
-+{
-+    provided type       PCI::Device;
-+
-+    required variable ::number  PCI::vendor_id;
-+    required variable ::number  PCI::product_id;
-+
-+    provided sequence   PCI::register()
-+    {
-+        provided chunk  ::CALL;
-+        provided chunk  LKM::data;
-+    }
-+
-+    provided sequence   PCI::unregister()
-+    {
-+        provided chunk  ::CALL;
-+    }
-+
-+    required sequence   PCI::probe(PCI::Device)
-+    {
-+        provided chunk  LKM::prototypes;
-+        provided chunk  LKM::code;
-+    }
-+
-+    required sequence   PCI::remove(PCI::Device)
-+    {
-+        provided chunk  LKM::prototypes;
-+        provided chunk  LKM::code;
-+    }
-+}
--- a/rathaxes_start_to_implement_sk_buff_in_the_lkm.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-# HG changeset patch
-# Parent 86594bdb2ed616f9cbbafe8d78bccc676f832f49
-rathaxes: add sk_buff abstraction and add the implementation of the xmit function for the ethernet system. We have a fully (empty) functionnal ethernet driver
-
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/CMakeLists.txt
---- a/rathaxes/samples/lkm/CMakeLists.txt	Sat Jan 07 20:51:10 2012 +0100
-+++ b/rathaxes/samples/lkm/CMakeLists.txt	Sat Jan 07 20:51:27 2012 +0100
-@@ -1,6 +1,6 @@
- ADD_RATHAXES_SOURCES(lkm lkm.rtx
--                     RTI log.rti lkm.rti pci.rti ethernet.rti
--                     BLT log.blt lkm.blt pci.blt ethernet.blt)
-+                     RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti
-+                     BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt)
- 
- # We can't name lkm since it's already used as the target name to generate the
- # source (with ADD_RATHAXES_SOURCES).
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/e1000.blt
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/e1000.blt	Sat Jan 07 20:51:27 2012 +0100
-@@ -0,0 +1,72 @@
-+with e1000, Ethernet, Socket, PCI, LKM, Log
-+{
-+    template type   e1000::Context()
-+    {
-+        chunk   LKM::includes()
-+        {
-+            /*
-+             * Force the generation of the structure in the "headers part, we
-+             * have to do this since we do not use the structure in this blt
-+             * (we hacked a bit and used it in ethernet.blt directly).
-+             */
-+            typedef int ${e1000::Context}; /* CNorm __std__ workaround */
-+            ${e1000::Context} force_declaration_in_includes;
-+        }
-+
-+        chunk   ::decl()
-+        {
-+            struct rtx_e1000_ctx
-+            {
-+                int                             bars;
-+                unsigned char /* __iomem */     *ioaddr;
-+            };
-+        }
-+
-+        map
-+        {
-+        }
-+    }
-+
-+    template sequence   e1000::create()
-+    {
-+        chunk ::CALL
-+        {
-+            rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM);
-+            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")};
-+            }
-+        }
-+    }
-+
-+    template sequence   e1000::destroy()
-+    {
-+        chunk ::CALL
-+        {
-+            // XXX: add a check in order to avoid freeing none allocated
-+            // resources.
-+            struct net_device *net_dev = pci_get_drvdata(pdev);
-+            struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev);
-+            iounmap(rtx_ether_ctx->hw_ctx.ioaddr);
-+            pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars);
-+            pci_release_region(pdev, 0);
-+        }
-+    }
-+}
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/e1000.rti
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/e1000.rti	Sat Jan 07 20:51:27 2012 +0100
-@@ -0,0 +1,15 @@
-+interface e1000 : Socket, Ethernet, PCI, LKM
-+{
-+    provided type   e1000::Context;
-+
-+    /* Not sure if we need the argument */
-+    provided sequence   e1000::create()
-+    {
-+        provided chunk  ::CALL;
-+    }
-+
-+    provided sequence   e1000::destroy()
-+    {
-+        provided chunk  ::CALL;
-+    }
-+}
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/ethernet.blt
---- a/rathaxes/samples/lkm/ethernet.blt	Sat Jan 07 20:51:10 2012 +0100
-+++ b/rathaxes/samples/lkm/ethernet.blt	Sat Jan 07 20:51:27 2012 +0100
-@@ -18,8 +18,11 @@
-                  * I think it's useless to use the ${PCI::Device} "abstraction"
-                  * here, since we are already in a Linux specific context here.
-                  */
--                struct pci_dev      *pci_dev;
--                struct net_device   *net_dev;
-+                struct pci_dev          *pci_dev;
-+                struct net_device       *net_dev;
-+
-+                /* while waiting on issue #8 */
-+                struct rtx_e1000_ctx    hw_ctx;
-             };
-         }
- 
-@@ -51,6 +54,24 @@
-         }
-     }
- 
-+    template sequence   Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
-+    {
-+        chunk LKM::prototypes()
-+        {
-+            static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev);
-+        }
-+
-+        chunk LKM::code()
-+        {
-+            static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev)
-+            {
-+                ${pointcut ::IMPLEMENTATION};
-+
-+                return 0;
-+            }
-+        }
-+    }
-+
-     template sequence   Ethernet::close(Ethernet::Device dev)
-     {
-         chunk LKM::prototypes()
-@@ -100,7 +121,7 @@
-             {
-                 .ndo_open = rtx_ethernet_open,
-                 .ndo_stop = rtx_ethernet_close,
--                .ndo_start_xmit = NULL,
-+                .ndo_start_xmit = rtx_ethernet_xmit,
-             };
-         }
- 
-@@ -159,9 +180,6 @@
-     {
-         chunk ::CALL
-         {
--            struct net_device   *net_dev;
--
--            net_dev = pci_get_drvdata(pdev); // should be ${pdev}, see above
-             unregister_netdev(net_dev);
-             /*
-              * If we had some cleanup todo with struct rtx_ether_ctx we would
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/ethernet.rti
---- a/rathaxes/samples/lkm/ethernet.rti	Sat Jan 07 20:51:10 2012 +0100
-+++ b/rathaxes/samples/lkm/ethernet.rti	Sat Jan 07 20:51:27 2012 +0100
-@@ -1,4 +1,4 @@
--interface Ethernet : PCI, LKM
-+interface Ethernet : Socket, PCI, LKM
- {
-     provided type       Ethernet::Device;
- 
-@@ -10,6 +10,12 @@
-         provided chunk  LKM::code;
-     }
- 
-+    required sequence   Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
-+    {
-+        provided chunk  LKM::prototypes;
-+        provided chunk  LKM::code;
-+    }
-+
-     required sequence   Ethernet::close(Ethernet::Device)
-     {
-         provided chunk  LKM::prototypes;
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 20:51:10 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 20:51:27 2012 +0100
-@@ -15,15 +15,22 @@
-         Log::info("Got an interruption");
-     }
- 
-+    Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
-+    {
-+        Log::info("We have one packet to transmit!");
-+    }
-+
-     PCI::probe(PCI::Device dev)
-     {
-         Log::info("Probe the device");
-         Ethernet::init(dev);
-+        e1000::create();
-     }
- 
-     PCI::remove(PCI::Device dev)
-     {
-         Log::info("Remove the pci device");
-+        e1000::destroy();
-         Ethernet::exit(dev);
-     }
- 
-@@ -45,10 +52,11 @@
-     LKM::name = "hello";
-     LKM::author = "Rathaxes";
-     LKM::description = "Hello World Loadable Kernel Module (LKM)";
--    LKM::license = "BSD";
-+    LKM::license = "GPL";
- 
-     PCI::vendor_id = 0x8086;
-     PCI::product_id = 0x100f;
-+    PCI::set_master = true;
- 
-     Ethernet::ifname = "rtx%d";
- }
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/socket.blt
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/socket.blt	Sat Jan 07 20:51:27 2012 +0100
-@@ -0,0 +1,27 @@
-+with Socket, LKM
-+{
-+    template type Socket::SKBuff()
-+    {
-+        chunk LKM::includes()
-+        {
-+            #include <linux/skbuff.h>
-+        }
-+
-+        chunk ::decl()
-+        {
-+            struct sk_buff;
-+        }
-+
-+        chunk ::init()
-+        {
-+        }
-+
-+        map
-+        {
-+            // some work may have to be done here in order
-+            // to access to some field of the sk_buff.
-+            // We should determine if all the sk_buff managment
-+            // can be abstracted from the user.
-+        }
-+    }
-+}
-diff -r 86594bdb2ed6 rathaxes/samples/lkm/socket.rti
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/socket.rti	Sat Jan 07 20:51:27 2012 +0100
-@@ -0,0 +1,4 @@
-+interface Socket : LKM
-+{
-+    provided type Socket::SKBuff;
-+}
--- a/rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch	Sun Jan 08 01:45:20 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,368 +0,0 @@
-# HG changeset patch
-# Parent 53c073d05449cc4cd6130bd79eb02c07239dd8d8
-rathaxes: start to implement the Ethernet subsystem in linux LKM sample
-
-diff -r 53c073d05449 rathaxes/samples/lkm/CMakeLists.txt
---- a/rathaxes/samples/lkm/CMakeLists.txt	Sat Jan 07 19:10:21 2012 +0100
-+++ b/rathaxes/samples/lkm/CMakeLists.txt	Sat Jan 07 19:18:24 2012 +0100
-@@ -1,6 +1,6 @@
- ADD_RATHAXES_SOURCES(lkm lkm.rtx
--                     RTI log.rti lkm.rti pci.rti
--                     BLT log.blt lkm.blt pci.blt)
-+                     RTI log.rti lkm.rti pci.rti ethernet.rti
-+                     BLT log.blt lkm.blt pci.blt ethernet.blt)
- 
- # We can't name lkm since it's already used as the target name to generate the
- # source (with ADD_RATHAXES_SOURCES).
-diff -r 53c073d05449 rathaxes/samples/lkm/ethernet.blt
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/ethernet.blt	Sat Jan 07 19:18:24 2012 +0100
-@@ -0,0 +1,173 @@
-+with Ethernet, PCI, LKM, Log
-+{
-+    template type   Ethernet::Device()
-+    {
-+        chunk LKM::includes()
-+        {
-+            #include <linux/netdevice.h>
-+            #include <linux/etherdevice.h>
-+
-+            typedef int include_linux_net_system_stamp;
-+        }
-+
-+        chunk ::decl()
-+        {
-+            struct rtx_ethernet_dev
-+            {
-+                /*
-+                 * I think it's useless to use the ${PCI::Device} "abstraction"
-+                 * here, since we are already in a Linux specific context here.
-+                 */
-+                struct pci_dev      *pci_dev;
-+                struct net_device   *net_dev;
-+            };
-+        }
-+
-+        chunk ::init(net_dev)
-+        {
-+            ${self} = ${net_dev};
-+        }
-+
-+        map
-+        {
-+        }
-+    }
-+
-+    template sequence   Ethernet::open(Ethernet::Device dev)
-+    {
-+        chunk LKM::prototypes()
-+        {
-+            static int  rtx_ethernet_open(struct net_device *);
-+        }
-+
-+        chunk LKM::code()
-+        {
-+            static int  rtx_ethernet_open(struct net_device *dev)
-+            {
-+                ${pointcut ::IMPLEMENTATION};
-+
-+                return 0;
-+            }
-+        }
-+    }
-+
-+    template sequence   Ethernet::close(Ethernet::Device dev)
-+    {
-+        chunk LKM::prototypes()
-+        {
-+            static int  rtx_ethernet_close(struct net_device *);
-+        }
-+
-+        chunk LKM::code()
-+        {
-+            static int  rtx_ethernet_close(struct net_device *dev)
-+            {
-+                ${pointcut ::IMPLEMENTATION};
-+
-+                return 0;
-+            }
-+        }
-+    }
-+
-+    template sequence   Ethernet::interrupt_handler(Ethernet::Device dev)
-+    {
-+        /*
-+         * Why we can't use irqreturn_t here? (we are forced to use enum
-+         * irqreturn, which is the real type).
-+         */
-+
-+        chunk LKM::prototypes()
-+        {
-+            static enum irqreturn   rtx_ethernet_interrupt_handler(int, void *);
-+        }
-+
-+        chunk LKM::code()
-+        {
-+            static enum irqreturn   rtx_ethernet_interrupt_handler(int irq, void *dev_id)
-+            {
-+                ${pointcut ::IMPLEMENTATION};
-+
-+                return IRQ_NONE;
-+            }
-+        }
-+    }
-+
-+    template sequence   Ethernet::init(PCI::Device pdev)
-+    {
-+        chunk LKM::data()
-+        {
-+            static const struct net_device_ops  rtx_ether_ops =
-+            {
-+                .ndo_open = rtx_ethernet_open,
-+                .ndo_stop = rtx_ethernet_close,
-+                .ndo_start_xmit = NULL,
-+            };
-+        }
-+
-+        chunk ::CALL
-+        {
-+            /*
-+             * This typedef is needed to workaround a bug in CNorm __std__
-+             * dialect.
-+             */
-+            typedef int ${Ethernet::Device};
-+            ${Ethernet::Device} *rtx_ether_ctx;
-+            struct net_device   *net_dev;
-+            int error;
-+
-+            error = 0;
-+            net_dev = alloc_etherdev(sizeof(*rtx_ether_ctx));
-+            if (net_dev == 0)
-+            {
-+                ${Log::info("Cannot allocate memory")};
-+                // is it the thing to do?
-+                return -ENOMEM;
-+            }
-+            strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name));
-+            net_dev->irq = pdev->irq;
-+            // Maybe we should try ${rtx_ether_ctx.init()} here:
-+            rtx_ether_ctx = netdev_priv(net_dev);
-+            //rtx_ether_ctx->pci_dev = ${pdev};
-+            rtx_ether_ctx->pci_dev = pdev; // In the meantime do it directly
-+            rtx_ether_ctx->net_dev = net_dev;
-+
-+            /*
-+             * The substitution of ${pdev} fails here. I also tried to add a
-+             * "substitute method" to the PCI::Device that was just doing
-+             * "${self}" but it didn't work either (it was subsituted by a
-+             * placeholder, e.g: _1).
-+             *
-+             * That's why we cheated a bit and named all the arguments pdev.
-+             */
-+            //SET_NETDEV_DEV(net_dev, &${pdev}->dev);
-+            SET_NETDEV_DEV(net_dev, &pdev->dev);
-+            net_dev->netdev_ops = &rtx_ether_ops;
-+            if ((error = register_netdev(net_dev)))
-+            {
-+                ${Log::info("Cannot register the driver")};
-+                // is it the thing to do?
-+                return error;
-+            }
-+
-+            /* same problem as above with ${pdev} */
-+            //pci_set_drvdata(${pdev}, net_dev);
-+            pci_set_drvdata(pdev, net_dev);
-+        }
-+    }
-+
-+    template sequence   Ethernet::exit(PCI::Device pdev)
-+    {
-+        chunk ::CALL
-+        {
-+            struct net_device   *net_dev;
-+
-+            net_dev = pci_get_drvdata(pdev); // should be ${pdev}, see above
-+            unregister_netdev(net_dev);
-+            /*
-+             * If we had some cleanup todo with struct rtx_ether_ctx we would
-+             * do a netdev_priv(net_dev) here and do it.
-+             */
-+            free_netdev(net_dev);
-+        }
-+    }
-+}
-diff -r 53c073d05449 rathaxes/samples/lkm/ethernet.rti
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/rathaxes/samples/lkm/ethernet.rti	Sat Jan 07 19:18:24 2012 +0100
-@@ -0,0 +1,37 @@
-+interface Ethernet : PCI, LKM
-+{
-+    provided type       Ethernet::Device;
-+
-+    required variable ::string  Ethernet::ifname;
-+
-+    required sequence   Ethernet::open(Ethernet::Device)
-+    {
-+        provided chunk  LKM::prototypes;
-+        provided chunk  LKM::code;
-+    }
-+
-+    required sequence   Ethernet::close(Ethernet::Device)
-+    {
-+        provided chunk  LKM::prototypes;
-+        provided chunk  LKM::code;
-+    }
-+
-+    required sequence   Ethernet::interrupt_handler(Ethernet::Device)
-+    {
-+        provided chunk  LKM::prototypes;
-+        provided chunk  LKM::code;
-+    }
-+
-+    /* Kinda extends PCI::probe */
-+    provided sequence   Ethernet::init(PCI::Device)
-+    {
-+        provided chunk  LKM::data;
-+        provided chunk  ::CALL;
-+    }
-+
-+    /* Likely extends PCI::remove */
-+    provided sequence   Ethernet::exit(PCI::Device)
-+    {
-+        provided chunk  ::CALL;
-+    }
-+}
-diff -r 53c073d05449 rathaxes/samples/lkm/lkm.rtx
---- a/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 19:10:21 2012 +0100
-+++ b/rathaxes/samples/lkm/lkm.rtx	Sat Jan 07 19:18:24 2012 +0100
-@@ -1,13 +1,30 @@
- device LKM use LKM, PCI, Log
- {
-+    Ethernet::open(Ethernet::Device dev)
-+    {
-+        Log::info("Open the device");
-+    }
-+
-+    Ethernet::close(Ethernet::Device dev)
-+    {
-+        Log::info("Close the device");
-+    }
-+
-+    Ethernet::interrupt_handler(Ethernet::Device dev)
-+    {
-+        Log::info("Got an interruption");
-+    }
-+
-     PCI::probe(PCI::Device dev)
-     {
--
-+        Log::info("Probe the device");
-+        Ethernet::init(dev);
-     }
- 
-     PCI::remove(PCI::Device dev)
-     {
--
-+        Log::info("Remove the pci device");
-+        Ethernet::exit(dev);
-     }
- 
-     LKM::init()
-@@ -32,4 +49,6 @@
- 
-     PCI::vendor_id = 0x8086;
-     PCI::product_id = 0x100f;
-+
-+    Ethernet::ifname = "rtx%d";
- }
-diff -r 53c073d05449 rathaxes/samples/lkm/pci.blt
---- a/rathaxes/samples/lkm/pci.blt	Sat Jan 07 19:10:21 2012 +0100
-+++ b/rathaxes/samples/lkm/pci.blt	Sat Jan 07 19:18:24 2012 +0100
-@@ -11,15 +11,12 @@
- 
-         chunk   ::decl()
-         {
--            struct  rtx_pci_device
--            {
--                struct pci_dev  *pci_dev;
--            };
-+            struct pci_dev;
-         }
- 
-         chunk   ::init(pci_dev)
-         {
--            ${self}.pci_dev = pci_dev;
-+            ${self} = ${pci_dev};
-         }
- 
-         map
-@@ -27,7 +24,17 @@
-         }
-     }
- 
--    template sequence   PCI::probe(PCI::Device dev)
-+    /*
-+     * The PCI::probe sequence is a "required" sequence which means that its
-+     * implementation will be done in the .rtx. Here we just define the context
-+     * were this implementation will be inserted. The implementation should be
-+     * able to access to the struct pci_dev (here marked as the "argument"
-+     * PCI::Device). How do we bind this PCI::Device argument with the pdev
-+     * struct pci_dev pointer defined in the LKM::code chunk?
-+     *
-+     * The only thing I can imagine is: ${pointcut ::IMPLEMENTATION(pdev)};
-+     */
-+    template sequence   PCI::probe(PCI::Device pdev)
-     {
-         chunk LKM::prototypes()
-         {
-@@ -40,11 +47,7 @@
-             static int /* __devinit */  rtx_pci_probe(struct pci_dev *pdev,
-                                                       const struct pci_device_id *pdev_id)
-             {
--                /* workaround for CNorm __std__ dialect, shouldn't be here */
--                typedef int ${PCI::Device};
--
-                 int             err;
--                ${PCI::Device}  *dev = NULL;
- 
-                 err = pci_enable_device(pdev);
-                 if (err < 0)
-@@ -52,8 +55,6 @@
- 
-                 ${pointcut ::IMPLEMENTATION};
- 
--                pci_set_drvdata(pdev, dev);
--
-                 return 0;
- 
-                 fail:
-@@ -62,7 +63,7 @@
-         }
-     }
- 
--    template sequence   PCI::remove(PCI::Device dev)
-+    template sequence   PCI::remove(PCI::Device pdev)
-     {
-         chunk LKM::prototypes()
-         {
-@@ -73,9 +74,9 @@
-         {
-             static void rtx_pci_remove(struct pci_dev *pdev)
-             {
-+                ${pointcut ::IMPLEMENTATION};
-+
-                 pci_disable_device(pdev);
--
--                ${pointcut ::IMPLEMENTATION};
-             }
-         }
-     }
-@@ -89,7 +90,7 @@
-              * have to specify the exact size).
-              */
-             static struct pci_device_id rtx_pci_device_table[2] = {
--                { ${config.vendor_id}, ${config.product_id}, 0, PCI_ANY_ID, PCI_ANY_ID },
-+                { ${config.vendor_id}, ${config.product_id}, PCI_ANY_ID, PCI_ANY_ID },
-                 { 0, }
-             };
- 
--- a/series	Sun Jan 08 01:45:20 2012 +0100
+++ b/series	Sun Jan 08 01:51:34 2012 +0100
@@ -1,10 +1,3 @@
 doc_improve_first_steps.patch
 provided_pointcut_in_required_sequences_fail.patch
-rathaxes_add_a_linux_lkm.patch
-rathaxes_start_to_implement_pci_stuff_in_the_lkm.patch
-rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch
-rathaxes_start_to_implement_sk_buff_in_the_lkm.patch
-pci_rework_without_explicit_call.patch
-ethernet_rework_without_explicit_call.patch
-e1000_rework_without_explicit_call.patch
 rathaxes_add_lkm_ethernet_sample.patch