changeset 87:e9736ab70995

Add a couple of patches to the build system and WIP on the e1000 code architecture to implement the tranmission
author Louis Opter <louis@lse.epitech.net>
date Mon, 24 Sep 2012 09:13:15 +0200
parents c99e69966dd3
children 8ffcdd6aa410
files e1000_implement_the_frame_transmission_chunk.patch maintainers_build_lkm_in_gnu99.patch maintainers_remove_tarte_workaround.patch series
diffstat 4 files changed, 527 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- a/e1000_implement_the_frame_transmission_chunk.patch	Tue Sep 18 08:57:14 2012 +0200
+++ b/e1000_implement_the_frame_transmission_chunk.patch	Mon Sep 24 09:13:15 2012 +0200
@@ -1,22 +1,166 @@
 # HG changeset patch
-# Parent 42d6e2a573d077772c1a9c697cc066337569b129
+# Parent 87ba2a19a59fb7be346ad40a57439b6b752b152e
 rathaxes: start to queue up packets in the TX ring on the e1000 sample
 
-diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in
---- a/maintainers/CMakeScripts/Templates/MakefileLKM.in
-+++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in
-@@ -1,6 +1,6 @@
- # Disable this "coding-style" warning (seriously, you have to compile with
- # -pedantic to get it...)
--EXTRA_CFLAGS	= -Wno-declaration-after-statement
-+EXTRA_CFLAGS	= -Wno-declaration-after-statement -std=gnu99
+diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt
+--- a/rathaxes/samples/e1000/CMakeLists.txt
++++ b/rathaxes/samples/e1000/CMakeLists.txt
+@@ -1,6 +1,22 @@
+-ADD_RATHAXES_SOURCES(e1000_src lkm.rtx
+-                     RTI builtin.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)
++ADD_RATHAXES_SOURCES(e1000_src
++                     lkm.rtx
++                     RTI
++                     builtin.rti
++                     log.rti
++                     lkm.rti
++                     device.rti
++                     pci.rti
++                     socket.rti
++                     ethernet.rti
++                     e1000.rti
++                     BLT
++                     log.blt
++                     lkm.blt
++                     pci.blt
++                     device.blt
++                     socket.blt
++                     ethernet.blt
++                     e1000.blt)
  
- KDIR		= /lib/modules/$(shell uname -r)/build
- obj-m		:= @LKM_OBJECTS@
+ IF (LINUX_KBUILD_DIR)
+     ADD_RATHAXES_LKM(e1000 e1000_src)
+diff --git a/rathaxes/samples/e1000/device.blt b/rathaxes/samples/e1000/device.blt
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/e1000/device.blt
+@@ -0,0 +1,25 @@
++with Device, LKM
++{
++    template type   Device::Device()
++    {
++        chunk   LKM::includes()
++        {
++            #include <linux/device.h>
++
++            static const ${Device::Device}  force_rtx_device_decl;
++        }
++
++        chunk   decl()
++        {
++            typedef struct device   *rtx_device_p;
++        }
++
++        chunk   init()
++        {
++        }
++
++        map
++        {
++        }
++    }
++}
+diff --git a/rathaxes/samples/e1000/device.rti b/rathaxes/samples/e1000/device.rti
+new file mode 100644
+--- /dev/null
++++ b/rathaxes/samples/e1000/device.rti
+@@ -0,0 +1,9 @@
++interface Device : LKM
++{
++    provided type   Device
++    {
++        chunk       LKM::includes();
++        method      decl();
++        method      init();
++    }
++}
 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
-@@ -332,6 +332,30 @@
+@@ -110,9 +110,9 @@
+             {
+                 unsigned int                    size;
+                 struct rtx_e1000_rx_descriptor  *base;
+-                void*   /* dma_addr_t */        dma_base;
++                dma_addr_t                      dma_base;
+                 struct sk_buff                  *skbuffs[256 /* ${config.rx_ring_size} */];
+-                void*   /* dma_addr_t */        dma_skbuffs[256 /* ${config.rx_ring_size} */];
++                dma_addr_t                      dma_skbuffs[256 /* ${config.rx_ring_size} */];
+             };
+         }
+ 
+@@ -148,11 +148,59 @@
+             struct rtx_e1000_tx_ring
+             {
+                 unsigned int                    size;
++                /* We should probably use ${e1000::TxDescriptor} here: */
+                 struct rtx_e1000_tx_descriptor  *base;
+-                void*   /* dma_addr_t */        dma_base;
++                dma_addr_t                      dma_base;
++                /* indexes on base */
++                unsigned int                    head;
++                unsigned int                    tail;
+             };
+         }
+ 
++        chunk   LKM::prototypes()
++        {
++            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *);
++            static int          rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *);
++            static int          rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *);
++        }
++
++        chunk   LKM::code()
++        {
++            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *self)
++            {
++                if (self->tail == self->head) /* ring is empty */
++                    return 256; /* XXX: ${config.tx_ring_size}; */
++                if (self->tail > self->head)
++                    /* XXX: ${config.tx_ring_size} */
++                    return 256 - (self->tail - self->head);
++                return self->head - self->tail;
++            }
++
++            static int          rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *self, struct rtx_socket_skbuff *skb)
++            {
++                return skb_is_gso(skb->skbuff) || skb->skbuff->ip_summed == CHECKSUM_PARTIAL;
++            }
++
++            static int          rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *self, struct rtx_socket_skbuff *skb)
++            {
++                return NETDEV_TX_OK;
++            }
++        }
++
++        chunk   descriptors_remaining()
++        {
++            rtx_e1000_tx_ring_descriptors_remaining(${self});
++        }
++
++        chunk   tso_cksum_offload(Socket::SKBuff skb)
++        {
++        }
++
++        chunk   put(Socket::SKBuff skb)
++        {
++            rtx_e1000_tx_ring_put(${self}, &${skb});
++        }
++
+         chunk   ::init()
+         {
+         }
+@@ -183,7 +231,7 @@
+             struct rtx_e1000_ctx
+             {
+                 int                         bars;
+-                unsigned char /* __iomem */ *ioaddr;
++                unsigned char __iomem       *ioaddr;
+                 int                         irq;
+ 
+                 /* we can't use the Rathaxes type here (#8) */
+@@ -334,6 +382,30 @@
          }
      }
  
@@ -47,7 +191,63 @@
      template sequence   e1000::create_device()
      {
          chunk Ethernet::create_device(PCI::Device pdev, Ethernet::Device rtx_ether_ctx)
-@@ -964,4 +988,86 @@
+@@ -358,8 +430,8 @@
+                 ${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});
++// XXX      if (${config.set_master})
++// XXX          pci_set_master(${pdev});
+ 
+             /* 0 here is for BAR_0: */
+             ${rtx_ether_ctx}->hw_ctx.ioaddr = pci_ioremap_bar(${pdev}, 0);
+@@ -630,8 +702,6 @@
+     {
+         chunk  ::CALL()
+         {
+-            typedef unsigned long int   dma_addr_t;
+-
+             /*
+              * This part is documented in the Intel Gigabit Ethernet Controller
+              * Software Developper manual. (You can find it in the doc/hardware
+@@ -733,7 +803,7 @@
+             hw_ctx->rx_ring.base = dma_alloc_coherent(
+                     &${ctx}->pci_dev->dev,
+                     hw_ctx->rx_ring.size,
+-                    (dma_addr_t *)&hw_ctx->rx_ring.dma_base,
++                    &hw_ctx->rx_ring.dma_base,
+                     GFP_KERNEL);
+             if (!hw_ctx->rx_ring.base)
+             {
+@@ -758,7 +828,7 @@
+                     ${Log::info("cannot allocate a skbuff for the rx ring")};
+                     goto err_skbuffs_alloc;
+                 }
+-                hw_ctx->rx_ring.dma_skbuffs[i] = (void *)dma_map_single(
++                hw_ctx->rx_ring.dma_skbuffs[i] = dma_map_single(
+                         &${ctx}->pci_dev->dev,
+                         hw_ctx->rx_ring.skbuffs[i]->data,
+                         ${config.rx_buffer_len},
+@@ -820,7 +890,7 @@
+             hw_ctx->tx_ring.base = dma_alloc_coherent(
+                     &${ctx}->pci_dev->dev,
+                     hw_ctx->tx_ring.size,
+-                    (dma_addr_t *)&hw_ctx->tx_ring.dma_base,
++                    &hw_ctx->tx_ring.dma_base,
+                     GFP_KERNEL);
+             if (!hw_ctx->rx_ring.base)
+             {
+@@ -838,6 +908,8 @@
+             /* 3. Setup TDH/TDT to zero: the queue is empty */
+             rtx_e1000_register_write32(hw_ctx, E1000_TDH, 0);
+             rtx_e1000_register_write32(hw_ctx, E1000_TDT, 0);
++            hw_ctx->tx_ring.head = 0;
++            hw_ctx->tx_ring.tail = 0;
+ 
+             /* 4. Set TCTL.PSP and enable the transmitter */
+             rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_PSP);
+@@ -930,4 +1002,81 @@
              }
          }
      }
@@ -56,53 +256,43 @@
 +    {
 +        chunk   ::CALL()
 +        {
-+            if (skb_is_gso(${skb}) || ${skb}->ip_summed == CHECKSUM_PARTIAL)
-+            {
-+                ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")};
-+                return NETDEV_TX_OK;
-+            }
 +        }
 +    }
 +
-+    template sequence   e1000::_xmit_map_skbuff(Ethernet::Device ctx, Socket::SKBuff skb)
++    template sequence   e1000::xmit(Ethernet::Device ctx, Socket::KernelSKBuff kernel_skb)
 +    {
 +        chunk   ::CALL()
 +        {
-+            dma_addr_t buff_addr = dma_map_single(
-+                    &${ctx}->pci_dev->dev,
-+                    ${skb}->data,
-+                    skb_headlen(${skb}),
-+                    DMA_TO_DEVICE);
-+            if (dma_mapping_error(&${ctx}->pci_dev->dev, buff_addr))
-+            {
-+                ${Log::info("xmit: can't DMA map a SKBuff")};
-+                goto err_dma_map;
-+            }
-+        }
-+    }
-+
-+    template sequence   e1000::_xmit_update_tx_ring(Ethernet::Device, Socket::SKBuff skb)
-+    {
-+        chunk   ::CALL()
-+        {
-+        }
-+    }
-+
-+    template sequence   e1000::xmit(Ethernet::Device ctx, Socket::SKBuff skb)
-+    {
-+        chunk   ::CALL()
-+        {
-+            typedef unsigned long int   dma_addr_t;
-+
-+            (void)1; // Issue 10
 +            /*
 +             * Put packets on the TX ring, must return NETDEV_TX_OK or
 +             * NETDEV_TX_BUSY.
 +             */
-+            {
-+                ${Log::info("xmit: skbuff details:")};
-+                ${skb.dump_infos()};
-+            }
++
++            /*
++             * XXX: This leaves a placeholder if I cast local.tx_ring as
++             * e1000::TxRing below.
++             */
++            ${Socket::SKBuff} skb;
++            ${local.skb.init(kernel_skb)};
++
++            /*
++             * XXX: can't write ${e1000::TxRing} * (the placeholder isn't
++             * resolved).
++             */
++            struct rtx_e1000_tx_ring *tx_ring = &${ctx}->hw_ctx.tx_ring;
++            //${cast local.tx_ring as e1000::TxRing};
++
++            ${Log::info("xmit: skbuff details:")};
++            /*
++             * skb is not expand on the bound C variable (should be rtx_skbuff),
++             * which is funny because it works for the sequence template call
++             * right after.
++             */
++            /*
++             * XXX: doesn't work (I tried to pass self explicitely too):
++             * ${local.skb.dump_infos()};
++             */
++            rtx_socket_skbuff_dump_infos(&skb);
 +
 +            /*
 +             * The transmission is going to be several steps:
@@ -114,22 +304,27 @@
 +             * 3. Signal the hardware that data is available via a tx desc.
 +             */
 +
++            /* XXX: same thing wanted to use: ${local.tx_ring.descriptors_remaining()} */
++            if (!rtx_e1000_tx_ring_descriptors_remaining(tx_ring))
++                return NETDEV_TX_BUSY;
++
 +            /* 1. Offloading */
-+            { // workaround #10 (and it's useful to workaround #47 too)
-+                ${e1000::_xmit_tso_cksum_offload(ctx, skb)};
++            /* XXX: ${local.tx_ring.tso_cksum_offload(skb)}; */
++            if (rtx_e1000_tx_ring_tso_cksum_offload(tx_ring, &skb))
++            {
++                ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")};
++                return NETDEV_TX_OK;
 +            }
 +
 +            /* 2. Map the data */
-+            {
-+                ${e1000::_xmit_map_skbuff(ctx, skb)};
-+            }
++            ${Device::Device} dev = &${ctx}->pci_dev->dev;
++            /* XXX: ${local.skb.dma_map(local.dev)}; */
++            rtx_socket_dma_map(&skb, dev);
 +
 +            /* 3. Update the TX Ring */
-+            {
-+                ${e1000::_xmit_update_tx_ring(ctx, skb)};
-+            }
++            /* XXX: ${local.tx_ring.put(skb)}; */
++            rtx_e1000_tx_ring_put(tx_ring, &skb);
 +
-+        err_dma_map:
 +            return NETDEV_TX_OK;
 +        }
 +    }
@@ -137,7 +332,22 @@
 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
-@@ -51,6 +51,12 @@
+@@ -31,8 +31,14 @@
+     provided type   TxRing
+     {
+         chunk       LKM::includes();
++        chunk       LKM::prototypes();
++        chunk       LKM::code();
+         method      decl();
+         method      init();
++
++        method      descriptors_remaining();
++        method      tso_cksum_offload(Socket::SKBuff);
++        method      put(Socket::SKBuff);
+     }
+ 
+     /*
+@@ -51,6 +57,12 @@
          method      decl();
      }
  
@@ -150,7 +360,7 @@
      provided sequence   create_device()
      {
          provided chunk  Ethernet::create_device(PCI::Device, Ethernet::Device);
-@@ -109,6 +115,26 @@
+@@ -109,6 +121,16 @@
          provided chunk  ::CALL();
      }
  
@@ -159,17 +369,7 @@
 +        provided chunk  ::CALL();
 +    }
 +
-+    provided sequence   _xmit_map_skbuff(Ethernet::Device, Socket::SKBuff)
-+    {
-+        provided chunk  ::CALL();
-+    }
-+
-+    provided sequence   _xmit_update_tx_ring(Ethernet::Device, Socket::SKBuff)
-+    {
-+        provided chunk  ::CALL();
-+    }
-+
-+    provided sequence   xmit(Ethernet::Device, Socket::SKBuff)
++    provided sequence   xmit(Ethernet::Device, Socket::KernelSKBuff)
 +    {
 +        provided chunk  ::CALL();
 +    }
@@ -180,7 +380,7 @@
 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
-@@ -1,6 +1,51 @@
+@@ -1,6 +1,56 @@
  with Ethernet, PCI, LKM, Log
  {
 -    template type Ethernet::Net()
@@ -219,6 +419,11 @@
 +            }
 +        }
 +
++        chunk decl()
++        {
++            typedef unsigned short  rtx_ether_protocol_id;
++        }
++
 +        chunk to_str()
 +        {
 +            rtx_ethernet_protocol_id_to_str(${self});
@@ -233,7 +438,7 @@
      {
          chunk LKM::includes()
          {
-@@ -17,11 +62,6 @@
+@@ -17,11 +67,6 @@
          }
      }
  
@@ -245,7 +450,19 @@
      template type   Ethernet::Device()
      {
          chunk LKM::includes()
-@@ -52,7 +92,7 @@
+@@ -47,15 +92,15 @@
+                 struct pci_dev          *pci_dev;
+                 struct net_device       *net_dev;
+ 
+-                /* while waiting on issue #8 */
+-                //${e1000::Context}       hw_ctx;
+-                // In the long-term, this may disappear for a new concept allowing
+-                // to embbed a descriptor defined and manipulated by the front-end
++                /*
++                 * In the long-term, this may disappear for a new concept allowing
++                 * to embbed a descriptor defined and manipulated by the front-end
++                 */
+                 ${pointcut Ethernet::SubContext()};
              } *rtx_ethernet_dev_p;
          }
  
@@ -254,45 +471,89 @@
          {
              ${self} = netdev_priv(${net_dev});
              /*
-@@ -100,11 +140,11 @@
+@@ -82,9 +127,8 @@
          {
-             static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev)
+             static int  rtx_ethernet_open(struct net_device *dev)
+             {
+-                struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev);
++                ${Ethernet::Device} rtx_ether_dev = netdev_priv(dev);
+ 
+-                ${cast local.rtx_ether_dev as Ethernet::Device};
+                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)};
+ 
+                 return 0;
+@@ -92,7 +136,7 @@
+         }
+     }
+ 
+-    template sequence   Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
++    template sequence   Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb)
+     {
+         chunk LKM::prototypes()
+         {
+@@ -101,13 +145,11 @@
+ 
+         chunk LKM::code()
+         {
+-            static int  rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev)
++            static int  rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev)
              {
 -                ${cast local.dev as Ethernet::Device};
-+                struct rtx_ethernet_dev* rtx_ethernet_dev = netdev_priv(dev);
-+
-+                ${cast local.rtx_ethernet_dev as Ethernet::Device};
-                 ${cast local.skb as Socket::SKBuff};
+-                ${cast local.skb as Socket::SKBuff};
 -                ${pointcut ::IMPLEMENTATION(local.dev, local.skb)};
 -
 -                return 0;
-+                ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.skb)};
++                ${Ethernet::Device} rtx_ethernet_dev = netdev_priv(net_dev);
++                ${cast local.kernel_skb as Socket::KernelSKBuff};
++                ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.kernel_skb)};
              }
          }
      }
+@@ -123,9 +165,8 @@
+         {
+             static int  rtx_ethernet_close(struct net_device *dev)
+             {
+-                struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev);
++                ${Ethernet::Device} rtx_ether_dev = netdev_priv(dev);
+ 
+-                ${cast local.rtx_ether_dev as Ethernet::Device};
+                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)};
+ 
+                 return 0;
+@@ -148,11 +189,8 @@
+         {
+             static enum irqreturn   rtx_ethernet_interrupt_handler(int irq, void *dev_id)
+             {
+-                struct rtx_ethernet_dev* rtx_ether_dev;
+-                struct rtx_e1000_ctx* ctx;
++                ${Ethernet::Device} rtx_ether_dev = dev_id;
+ 
+-                rtx_ether_dev = dev_id;
+-                ${cast local.rtx_ether_dev as Ethernet::Device};
+                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)};
+ 
+                 return IRQ_NONE;
 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,16 +1,33 @@
+@@ -1,16 +1,30 @@
  interface Ethernet : Socket, PCI, LKM
  {
 -    provided type   Net
-+    provided type   ProtocolId
-+    {
-+        chunk       LKM::prototypes();
-+        chunk       LKM::data();
-+        chunk       LKM::code();
-+        method      ::to_str();
-+    }
++     provided type   ProtocolId
++     {
++         chunk       LKM::prototypes();
++         chunk       LKM::data();
++         chunk       LKM::code();
++         method      decl();
++         method      to_str();
++     }
 +
-+    /*
-+     * This is the abstract type used by the Kernel to represent an ethernet
-+     * device.
-+     */
 +    provided type   AbstractDevice
      {
          chunk       LKM::includes();
-         method       decl();
+-        method       decl();
++        method      decl();
      }
  
 +    /*
@@ -306,14 +567,33 @@
          method      decl();
 -        method      init(Ethernet::Net, PCI::Device);
 +        method      init(Ethernet::AbstractDevice, PCI::Device);
+         pointcut    Ethernet::SubContext();
      }
  
-     required variable ::string  ifname;
+@@ -22,7 +36,7 @@
+         provided chunk  LKM::code();
+     }
+ 
+-    required sequence   send(Ethernet::Device dev, Socket::SKBuff skb)
++    required sequence   send(Ethernet::Device, Socket::KernelSKBuff)
+     {
+         provided chunk  LKM::prototypes();
+         provided chunk  LKM::code();
 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx
 --- a/rathaxes/samples/e1000/lkm.rtx
 +++ b/rathaxes/samples/e1000/lkm.rtx
-@@ -46,6 +46,7 @@
-     Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
+@@ -1,4 +1,4 @@
+-device LKM use LKM, PCI, Ethernet, Log
++device LKM use LKM, PCI, Ethernet, Log, Socket
+ {
+     Ethernet::open(Ethernet::Device dev)
+     {
+@@ -43,9 +43,10 @@
+         e1000::handle_interrupt(dev);
+     }
+ 
+-    Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
++    Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb)
      {
          Log::info("we have one packet to transmit!");
 +        e1000::xmit(dev, skb);
@@ -334,69 +614,141 @@
 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
 --- a/rathaxes/samples/e1000/socket.blt
 +++ b/rathaxes/samples/e1000/socket.blt
-@@ -1,4 +1,4 @@
+@@ -1,20 +1,104 @@
 -with Socket, LKM
-+with Socket, LKM, Ethernet
++with Socket, LKM, Device, Ethernet
  {
++    template type Socket::KernelSKBuff()
++    {
++        chunk LKM::includes()
++        {
++            #include <linux/skbuff.h>
++
++            static const ${Socket::KernelSKBuff} force_rtx_socket_kernel_skbuff_decl;
++        }
++
++        chunk ::decl()
++        {
++            typedef struct sk_buff  *rtx_socket_kernel_skbuff_p;
++        }
++
++        map
++        {
++        }
++    }
++
      template type Socket::SKBuff()
      {
-@@ -10,13 +10,41 @@
+         chunk LKM::includes()
+         {
+-            #include <linux/skbuff.h>
+-            static const ${Socket::SKBuff} force_rtx_lnux_skbuf_decl;
++            static const ${Socket::SKBuff} force_rtx_socket_skbuff_decl;
+         }
  
          chunk ::decl()
          {
 -            struct sk_buff;
-+            typedef struct sk_buff  *rtx_socket_skbuff_p;
-         }
- 
-         chunk ::init()
-         {
++            struct  rtx_socket_skbuff
++            {
++                struct sk_buff  *skbuff;
++                dma_addr_t      dma_handle;
++            };
          }
  
-+        chunk ::dump_infos()
-+        {
-+            /*
-+             * We should use a Rathaxes log abstraction instead of pr_info here,
-+             * but Rathaxes doesn't support functions with a variable number of
-+             * arguments yet.
-+             */
-+            unsigned short ethernet_proto = be16_to_cpu(${self}->protocol);
-+            ${cast local.ethernet_proto as Ethernet::ProtocolId};
-+
-+            static const char * const ip_summed_values[] = {
-+                "none", "unnecessary", "complete", "partial"
-+            };
-+
-+            pr_info(
-+                    "\t protocol = %#-5x (%s)\n"
-+                    "\t      len = %-5u data_len = %-5u head_len = %-5u\n"
-+                    "\t nr_frags = %u\n"
-+                    "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n"
-+                    "\tip_summed = %d (%s)",
-+                    ethernet_proto, "", // XXX: ${local.ethernet_proto.to_str()},
-+                    ${self}->len, ${self}->data_len, skb_headlen(${self}),
-+                    skb_shinfo(${self})->nr_frags,
-+                    skb_shinfo(${self})->gso_size, skb_shinfo(${self})->gso_segs, skb_shinfo(${self})->gso_type,
-+                    ${self}->ip_summed, ip_summed_values[${self}->ip_summed]
-+            );
+-        chunk ::init()
++        chunk   LKM::prototypes()
+         {
++            static void rtx_socket_skbuff_dump_infos(struct rtx_socket_skbuff *);
++            static int  rtx_socket_dma_map(struct rtx_socket_skbuff *, struct device *);
 +        }
 +
++        chunk   LKM::code()
++        {
++            static void rtx_socket_skbuff_dump_infos(struct rtx_socket_skbuff *self)
++            {
++                /*
++                 * We should use a Rathaxes log abstraction instead of pr_info here,
++                 * but Rathaxes doesn't support functions with a variable number of
++                 * arguments yet.
++                 */
++                ${Ethernet::ProtocolId} ethernet_proto = be16_to_cpu(self->skbuff->protocol);
++                static const char * const ip_summed_values[] = {
++                    "none", "unnecessary", "complete", "partial"
++                };
++                struct skb_shared_info *shinfo = skb_shinfo(self->skbuff);
++
++                pr_info(
++                        "\t protocol = %#-5x (%s)\n"
++                        "\t      len = %-5u data_len = %-5u head_len = %-5u\n"
++                        "\t nr_frags = %u\n"
++                        "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n"
++                        "\tip_summed = %d (%s)",
++                        ethernet_proto, rtx_ethernet_protocol_id_to_str(ethernet_proto) /* XXX: ${local.ethernet_proto.to_str()} */,
++                        self->skbuff->len, self->skbuff->data_len, skb_headlen(self->skbuff),
++                        shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type,
++                        self->skbuff->ip_summed, ip_summed_values[self->skbuff->ip_summed]
++                );
++            }
++
++            static int rtx_socket_dma_map(struct rtx_socket_skbuff *self, struct device *dev)
++            {
++                self->dma_handle = dma_map_single(
++                        dev,
++                        self->skbuff->data,
++                        skb_headlen(self->skbuff),
++                        DMA_TO_DEVICE);
++                return dma_mapping_error(dev, self->dma_handle);
++            }
++        }
++
++        /*
++         * XXX: the rathaxes argument kernel_skb is not actually bound to the
++         * correct C variable from Ethernet::send() (so I named it as the C
++         * variable I needed)
++         */
++        chunk ::init(Socket::KernelSKBuff kernel_skb)
++        {
++            ${self}.skbuff = kernel_skb;
++            ${self}.dma_handle = 0;
++        }
++
++        chunk dump_infos()
++        {
++            rtx_socket_skbuff_dump_infos(${self});
++        }
++
++        chunk   dma_map(Device::Device dev)
++        {
++            rtx_socket_dma_map(${self}, ${dev});
+         }
+ 
          map
-         {
-             // some work may have to be done here in order
 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti
 --- a/rathaxes/samples/e1000/socket.rti
 +++ b/rathaxes/samples/e1000/socket.rti
-@@ -1,8 +1,10 @@
- interface Socket : LKM
+@@ -1,8 +1,19 @@
+-interface Socket : LKM
++interface Socket : LKM, Device
  {
 -    provided type Socket::SKBuff {
-+    provided type Socket::SKBuff
-+    {
-         chunk   LKM::includes();
+-        chunk   LKM::includes();
 -        method  decl();
 -        method  init();
-+        chunk   ::decl();
-+        method  ::init();
-+        method  ::dump_infos();
++    provided type   KernelSKBuff
++    {
++        chunk       LKM::includes();
++        method      decl();
++    }
++
++    provided type   SKBuff
++    {
++        chunk       LKM::includes();
++        chunk       LKM::prototypes();
++        chunk       LKM::code();
++        method      decl();
++        method      init(Socket::KernelSKBuff);
++        method      dump_infos();
++        method      dma_map(Device::Device);
      }
  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/maintainers_build_lkm_in_gnu99.patch	Mon Sep 24 09:13:15 2012 +0200
@@ -0,0 +1,15 @@
+# HG changeset patch
+# Parent c53df313fbe2c5f971327b697cfcf506941b9b80
+maintainers: use the gnu99 "standard" to build Linux kernel modules
+
+diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in
+--- a/maintainers/CMakeScripts/Templates/MakefileLKM.in
++++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in
+@@ -1,6 +1,6 @@
+ # Disable this "coding-style" warning (seriously, you have to compile with
+ # -pedantic to get it...)
+-EXTRA_CFLAGS	= -Wno-declaration-after-statement
++EXTRA_CFLAGS	= -Wno-declaration-after-statement -std=gnu99
+ 
+ KDIR		= /lib/modules/$(shell uname -r)/build
+ obj-m		:= @LKM_OBJECTS@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/maintainers_remove_tarte_workaround.patch	Mon Sep 24 09:13:15 2012 +0200
@@ -0,0 +1,16 @@
+# HG changeset patch
+# Parent 05a7e20d2dc9dbce3f3877da1db7c743448c000e
+maintainers: remove the workaround used to generate source without CNorm unstrict
+
+diff --git a/maintainers/CMakeScripts/UseRathaxes.cmake b/maintainers/CMakeScripts/UseRathaxes.cmake
+--- a/maintainers/CMakeScripts/UseRathaxes.cmake
++++ b/maintainers/CMakeScripts/UseRathaxes.cmake
+@@ -185,8 +185,6 @@
+ 
+         SET(KERNEL_OBJECT_NAME "${RATHAXES_SOURCE}_${SYSTEM}.ko")
+         ADD_CUSTOM_COMMAND(OUTPUT "${KERNEL_OBJECT_NAME}"
+-                           # …
+-                           COMMAND "sed" "-i" "/TARTE/ d" "${RATHAXES_SOURCE}_${SYSTEM}.c"
+                            # The linux Makefile to build kernel module is quite
+                            # picky about file location and its own name. Let's
+                            # copy our source side by side with the Makefile:
--- a/series	Tue Sep 18 08:57:14 2012 +0200
+++ b/series	Mon Sep 24 09:13:15 2012 +0200
@@ -1,1 +1,3 @@
+maintainers_build_lkm_in_gnu99.patch
+maintainers_remove_tarte_workaround.patch
 e1000_implement_the_frame_transmission_chunk.patch