view rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch @ 102:8e8aa342078b

Close the series on the slides and backup some wip on the abstract type nightmare in e1000
author Louis Opter <louis@lse.epita.fr>
date Thu, 28 Feb 2013 23:30:59 -0800
parents
children d9af98faac8a
line wrap: on
line source

# HG changeset patch
# Parent 21cb4b0b59ebfc3350ded6f9cea2b44203437ab2
diff --git a/rathaxes/samples/e1000/device.blt b/rathaxes/samples/e1000/device.blt
--- a/rathaxes/samples/e1000/device.blt
+++ b/rathaxes/samples/e1000/device.blt
@@ -18,7 +18,7 @@
 
         map
         {
-            data:   ${self}->data;
+            k_device: ((struct device *)${self});
         }
     }
 }
diff --git a/rathaxes/samples/e1000/device.rti b/rathaxes/samples/e1000/device.rti
--- a/rathaxes/samples/e1000/device.rti
+++ b/rathaxes/samples/e1000/device.rti
@@ -5,6 +5,6 @@
         decl        data_types();
         chunk       LKM::includes();
         method      init();
-        attribute   Builtin::symbol data;
+        attribute   Builtin::symbol k_device;
     }
 }
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
@@ -249,7 +249,6 @@
         {
             int                         bars;
             unsigned char /* __iomem */ *ioaddr;
-            int                         irq;
 
             ${e1000::RxRing}    rx_ring;
             ${e1000::TxRing}    tx_ring;
@@ -267,14 +266,12 @@
 
         chunk   Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx,
                                                Builtin::number bars,
-                                               Builtin::symbol ioaddr,
-                                               Builtin::number irq)
+                                               Builtin::symbol ioaddr)
         {
             {
                 ${e1000::Context} *hw_ctx = &${rtx_ether_ctx}->hw_ctx;
                 hw_ctx->bars = ${bars};
                 hw_ctx->ioaddr = ${ioaddr};
-                hw_ctx->irq = ${irq};
             }
         }
 
@@ -606,68 +603,6 @@
         }
     }
 
-    template sequence   e1000::setup_interrupt_handler(Ethernet::Device rtx_ether_ctx)
-    {
-        chunk   LKM::includes()
-        {
-            #include <linux/interrupt.h>
-        }
-
-        chunk   LKM::prototypes()
-        {
-            static int e1000_setup_interrupt_handler(${Ethernet::Device} *);
-        }
-
-        chunk   LKM::code()
-        {
-            static int e1000_setup_interrupt_handler(${Ethernet::Device} *rtx_ether_ctx)
-            {
-                int error;
-
-                error = request_irq(rtx_ether_ctx->hw_ctx.irq,
-                        rtx_ethernet_interrupt_handler,
-                        IRQF_SHARED,
-                        ${config.name},
-                        rtx_ether_ctx);
-
-                if (error)
-                    ${Log::info("cannot register the interrupt handler")};
-
-                return error;
-            }
-        }
-
-        chunk   ::CALL()
-        {
-                int error = e1000_setup_interrupt_handler(${rtx_ether_ctx});
-                if (error)
-                {
-                        return error;
-                }
-        }
-    }
-
-    template sequence   free_interrupt_handler(Ethernet::Device rtx_ether_ctx)
-    {
-        chunk   prototypes()
-        {
-            static void e1000_free_interrupt_handler(${Ethernet::Device} *rtx_ether_ctx);
-        }
-
-        chunk code()
-        {
-            static void e1000_free_interrupt_handler(${Ethernet::Device} *rtx_ether_ctx)
-            {
-                free_irq(rtx_ether_ctx->hw_ctx.irq, rtx_ether_ctx);
-            }
-        }
-
-        chunk ::CALL()
-        {
-            e1000_free_interrupt_handler(${rtx_ether_ctx});
-        }
-    }
-
     template sequence   activate_device_interruption(Ethernet::Device rtx_ether_ctx)
     {
         chunk  ::CALL()
@@ -816,12 +751,10 @@
              * Allocate the skbuffs, map them for DMA, and write their address
              * in the corresponding descriptor.
              */
-            ${Ethernet::AbstractDevice} *rtx_ether_dev = ${rtx_ether_ctx.net_device};
-            ${cast local.rtx_ether_dev as Ethernet::AbstractDevice};
             for (i = 0; i != ${config.rx_ring_size}; ++i)
             {
-                hw_ctx->rx_ring.skbuffs[i].skbuff = (${Socket::AbstractSKBuff}*)  netdev_alloc_skb(
-                        &${rtx_ether_dev.netdev},
+                hw_ctx->rx_ring.skbuffs[i].skbuff = (${Socket::AbstractSKBuff}*)netdev_alloc_skb(
+                        ${rtx_ether_ctx.net_device},
                         ${config.rx_buffer_len});
                 if (!hw_ctx->rx_ring.skbuffs[i].skbuff)
                 {
@@ -830,7 +763,7 @@
                 }
                 hw_ctx->rx_ring.skbuffs[i].dma_handle = dma_map_single(
                         &${rtx_ether_ctx.device},
-                        &hw_ctx->rx_ring.skbuffs[i].skbuff->data,
+                        (struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff, /* XXX leaking cast */
                         ${config.rx_buffer_len},
                         DMA_FROM_DEVICE);
                 int dma_error = dma_mapping_error(&${rtx_ether_ctx.device},
@@ -933,7 +866,8 @@
                         ${config.rx_buffer_len},
                         DMA_FROM_DEVICE);
         err_skbuffs_map:
-                dev_kfree_skb(&hw_ctx->rx_ring.skbuffs[i].skbuff->data);
+                /* XXX leaking cast: */
+                dev_kfree_skb((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff);
             }
 
             dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->rx_ring.size,
@@ -1042,9 +976,9 @@
 
             ${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.
+             * skb does 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):
@@ -1077,8 +1011,8 @@
 
             /* 2. Map the data */
 
-            /* XXX: ${local.skb.map_to(local.devp)}; */
-            if (rtx_socket_skbuff_map(&skb, &${devp.data}, DMA_TO_DEVICE))
+            /* XXX: ${local.skb.map_to(devp.k_device)}; */
+            if (rtx_socket_skbuff_map(&skb, ${devp.k_device}, DMA_TO_DEVICE))
             {
                 ${Log::info("xmit: can't DMA map a SKbuff")};
                 goto err_skb_map_to;
@@ -1097,7 +1031,7 @@
         err_offload:
         err_skb_map_to:
             /* XXX: ${local.skb.unmap_to_and_free(local.dev)}; */
-            rtx_socket_skbuff_unmap_and_free(&skb, &${devp.data}, DMA_TO_DEVICE);
+            rtx_socket_skbuff_unmap_and_free(&skb, &${devp.k_device}, DMA_TO_DEVICE);
             return NETDEV_TX_OK;
         }
     }
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
@@ -13,8 +13,7 @@
         /* Callbacks/Hooks which should probably be in the front-end: */
         chunk       Ethernet::adapter_init_context(Ethernet::Device,
                                                    Builtin::number,
-                                                   Builtin::symbol,
-                                                   Builtin::number);
+                                                   Builtin::symbol);
         chunk       Ethernet::adapter_reset(Ethernet::Device);
         chunk       Ethernet::adapter_load_mac_address(Ethernet::Device);
     }
@@ -85,21 +84,6 @@
         provided chunk  ::CALL();
     }
 
-    provided sequence   setup_interrupt_handler(Ethernet::Device)
-    {
-        provided chunk  LKM::includes(); // works without this one
-        provided chunk  LKM::prototypes();
-        provided chunk  LKM::code();
-        provided chunk  ::CALL();
-    }
-
-    provided sequence   free_interrupt_handler(Ethernet::Device)
-    {
-        provided chunk  LKM::prototypes();
-        provided chunk  LKM::code();
-        provided chunk  ::CALL();
-    }
-
     provided sequence   activate_device_interruption(Ethernet::Device)
     {
         provided chunk  ::CALL();
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,4 +1,4 @@
-with Ethernet, PCI, LKM, Log
+with Ethernet, PCI, LKM, Log, Builtin
 {
     template type   Ethernet::ProtocolId()
     {
@@ -51,7 +51,7 @@
     {
         decl  data_types()
         {
-            struct net_device ndev;
+            struct net_device   data;
         }
 
         chunk LKM::includes()
@@ -59,9 +59,15 @@
             #include <linux/netdevice.h>
         }
 
+        method  init(Builtin::symbol dev)
+        {
+            ${self} = (${Ethernet::AbstractDevice} *)${dev};
+        }
+
         map
         {
-            netdev:   ${self}->ndev;
+            k_net_dev: ((struct net_device *)${self});
+            rtx_ether_ctx: netdev_priv((struct net_device *)${self});
         }
     }
 
@@ -88,29 +94,43 @@
             #include <linux/etherdevice.h>
         }
 
-        method init(Ethernet::AbstractDevice net_dev, PCI::AbstractDevice pci_dev)
+        /* XXX: if the first arg is not called rtx_net_dev, it breaks. */
+        method init(Ethernet::AbstractDevice rtx_net_dev, PCI::AbstractDevice pci_dev)
         {
-            ${self} = netdev_priv(&${net_dev.netdev});
+            ${self} = ${rtx_net_dev.rtx_ether_ctx}; 
             /*
              * We can use -> because we know that ${self} will be always a
              * pointer, but the ambiguity sucks.
              */
             ${self}->pci_dev = ${pci_dev};
-            ${self}->net_dev = ${net_dev};
+            ${self}->net_dev = ${rtx_net_dev};
         }
 
         map
         {
-            device: ${self}->pci_dev->data.dev;
+            /*
+             * XXX: I'd like to be able to do things like:
+             * device: ${self.pci_dev.k_pci_dev}->dev;
+             *
+             * Btw, should this be ${PCI::AbstractDevice} instead of directly
+             * struct pci_dev?
+             */
+            device: ((struct pci_dev *)(${self})->pci_dev)->dev;
             pci_device: ${self}->pci_dev;
             net_device: ${self}->net_dev;
-            perm_addr: ${self}->net_dev->ndev.perm_addr;
-            dev_addr: ${self}->net_dev->ndev.dev_addr;
+            perm_addr: ((struct net_device *)(${self})->net_dev)->perm_addr;
+            dev_addr: ((struct net_device *)(${self})->net_dev)->dev_addr;
+            irq: ((struct pci_dev *)(${self})->pci_dev)->irq;
         }
     }
 
     template sequence   Ethernet::open(Ethernet::Device dev)
     {
+        chunk   LKM::includes()
+        {
+            #include <linux/interrupt.h>
+        }
+
         chunk LKM::prototypes()
         {
             static int  rtx_ethernet_open(struct net_device *);
@@ -120,12 +140,40 @@
         {
             static int  rtx_ethernet_open(struct net_device *dev)
             {
-                ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(dev);
+                /*
+                 * XXX The casts are here because the compiler doesn't resolve
+                 * "enclosed" type (e.g: local.var.enclosed) correctly.
+                 */
+                ${Ethernet::AbstractDevice} *rtx_net_dev;
+                ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
+                { /* XXX: I end up with a placeholder if I don't open a scope */
+                    ${local.rtx_net_dev.init(local.dev)};
+                }
 
+                ${Ethernet::Device} *rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
                 ${cast local.rtx_ether_ctx as Ethernet::Device};
+
+                int error;
+                {
+                    ${Log::info("installing the interrupt handler")};
+                }
+                error = request_irq(${local.rtx_ether_ctx.irq},
+                                    rtx_ethernet_interrupt_handler,
+                                    IRQF_SHARED,
+                                    ${config.name},
+                                    ${local.rtx_net_dev.k_net_dev});
+                if (error)
+                {
+                    ${Log::info("Cannot register the interrupt handler")};
+                    goto error;
+                }
+
                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
 
                 return 0;
+
+            error:
+                return error;
             }
         }
     }
@@ -162,11 +210,23 @@
         {
             static int  rtx_ethernet_close(struct net_device *dev)
             {
-                ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(dev);
+                ${Ethernet::AbstractDevice} *rtx_net_dev;
+                ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
+                { /* XXX: I end up with a placeholder if I don't open a scope */
+                    ${local.rtx_net_dev.init(local.dev)};
+                }
 
+                ${Ethernet::Device} *rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
                 ${cast local.rtx_ether_ctx as Ethernet::Device};
+
+                /* TODO: change this pointcut into a pointcut/adapter/callback: */
                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
 
+                free_irq(${local.rtx_ether_ctx.irq}, ${local.rtx_net_dev.k_net_dev});
+                {
+                    ${Log::info("interrupt handler free'ed")};
+                }
+
                 return 0;
             }
         }
@@ -187,9 +247,13 @@
         {
             static enum irqreturn   rtx_ethernet_interrupt_handler(int irq, void *dev_id)
             {
-                ${Ethernet::Device} *rtx_ether_ctx = dev_id;
+                ${Ethernet::AbstractDevice} *rtx_net_dev = dev_id;
+                ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
 
+                ${Ethernet::Device} *rtx_ether_ctx;
                 ${cast local.rtx_ether_ctx as Ethernet::Device};
+                rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
+
                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
 
                 return IRQ_NONE;
@@ -219,23 +283,26 @@
          */
         chunk PCI::pci_probe_hook(PCI::Device rtx_pci_dev)
         {
+            ${Ethernet::AbstractDevice} *rtx_net_dev;
             ${Ethernet::Device} *rtx_ether_ctx;
-            ${Ethernet::AbstractDevice} *net_dev;
-            ${cast local.net_dev as Ethernet::AbstractDevice};
+            ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
 
-            net_dev = (${Ethernet::AbstractDevice}*) alloc_etherdev(sizeof(*rtx_ether_ctx));
-            if (!net_dev)
+            /* Cast the result back into our "transparent wrapper" type */
+            rtx_net_dev = (${Ethernet::AbstractDevice}*)alloc_etherdev(sizeof(*rtx_ether_ctx));
+            if (!rtx_net_dev)
             {
                 ${Log::info("cannot allocate the ethernet device context")};
                 error = -ENOMEM;
                 goto fail;
             }
-            SET_NETDEV_DEV(&${local.net_dev.netdev}, ${rtx_pci_dev.device});
-            strlcpy(${local.net_dev.netdev}.name, ${config.ifname}, sizeof(${local.net_dev.netdev}.name));
-            ${local.net_dev.netdev}.irq = ${rtx_pci_dev.irq};
-            ${local.net_dev.netdev}.netdev_ops = &rtx_ether_ops;
+            SET_NETDEV_DEV(${local.rtx_net_dev.k_net_dev}, ${rtx_pci_dev.device});
+            strlcpy(${local.rtx_net_dev.k_net_dev}->name,
+                    ${config.ifname},
+                    sizeof(${local.rtx_net_dev.k_net_dev}->name));
+            ${local.rtx_net_dev.k_net_dev}->irq = ${rtx_pci_dev.irq};
+            ${local.rtx_net_dev.k_net_dev}->netdev_ops = &rtx_ether_ops;
 
-            error = register_netdev(&${local.net_dev.netdev});
+            error = register_netdev(${local.rtx_net_dev.k_net_dev});
             if (error)
             {
                 ${Log::info("cannot register the driver in the net subsystem")};
@@ -247,14 +314,11 @@
              * XXX: the cast is here because the compiler resolve the
              * type of rtx_pci_dev.pci_device to the type of
              * rtx_pci_dev instead of the type of rtx_pci_dev.pci_device.
-             *
-             * Also, I'm getting placeholder in the generated code if
-             * I don't open a scope here.
              */
-            {
-                ${PCI::AbstractDevice} *rtx_pdev = ${rtx_pci_dev.pci_device};
-                ${cast local.rtx_pdev as PCI::AbstractDevice};
-                ${local.rtx_ether_ctx.init(local.net_dev, local.rtx_pdev)};
+            ${PCI::AbstractDevice} *workaround = ${rtx_pci_dev.pci_device};
+            ${cast local.workaround as PCI::AbstractDevice};
+            { /* XXX: I end up with a placeholder if I don't open a scope */
+                ${local.rtx_ether_ctx.init(local.rtx_net_dev, local.workaround)};
             }
 
             /* Register ourselves in the parent context: */
@@ -267,19 +331,16 @@
              */
             int bars = ${rtx_pci_dev.bars};
             unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr};
-            int irq = ${rtx_pci_dev.irq};
             ${cast local.bars as Builtin::number};
-            ${cast local.irq as Builtin::number};
             ${cast local.rtx_ether_ctx as Ethernet::Device};
             ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx,
                                                       local.bars,
-                                                      local.ioaddr,
-                                                      local.irq)};
+                                                      local.ioaddr)};
             ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)};
             ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)};
             memcpy(${local.rtx_ether_ctx.perm_addr},
                    ${local.rtx_ether_ctx.dev_addr},
-                   ${local.net_dev.netdev}.addr_len);
+                   ${local.rtx_net_dev.k_net_dev}->addr_len);
         }
 
         /* This chunk should be removed (see #26) */
@@ -296,15 +357,15 @@
          */
         chunk   PCI::pci_remove_hook(PCI::Device rtx_pci_dev)
         {
-            ${Ethernet::Device} *rtx_ether_ctx = ${rtx_pci_dev.context};
-            ${Ethernet::AbstractDevice} *rtx_ether_dev = (${Ethernet::AbstractDevice}*) ${local.rtx_ether_ctx.net_device};
-
+            ${Ethernet::Device} *rtx_ether_ctx = ${rtx_pci_dev.rtx_drv_context};
+            ${cast local.rtx_ether_ctx as Ethernet::Device}; /* XXX */
             BUG_ON(!rtx_ether_ctx);
 
-            ${cast local.rtx_ether_ctx as Ethernet::Device};
-            ${cast local.rtx_ether_dev as Ethernet::AbstractDevice};
-            unregister_netdev(&${local.rtx_ether_dev.netdev});
-            free_netdev(&${local.rtx_ether_dev.netdev});
+            ${Ethernet::AbstractDevice} *rtx_net_dev = ${local.rtx_ether_ctx.net_device};
+            ${cast local.rtx_net_dev as Ethernet::AbstractDevice}; /* XXX */
+
+            unregister_netdev(${local.rtx_net_dev.k_net_dev});
+            free_netdev(${local.rtx_net_dev.k_net_dev});
         }
 
         /* This chunk should be removed (see #26) */
diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti
--- a/rathaxes/samples/e1000/ethernet.rti
+++ b/rathaxes/samples/e1000/ethernet.rti
@@ -16,8 +16,15 @@
     provided type   AbstractDevice
     {
         chunk       LKM::includes();
+        method      init(Builtin::symbol);
         decl        data_types();
-        attribute   Builtin::symbol netdev;
+
+        attribute   Builtin::symbol k_net_dev;
+        /*
+         * XXX: should be a Ethernet::Device, but that causes a circular
+         * dependency.
+         */
+        attribute   Builtin::symbol rtx_ether_ctx;
     }
 
     provided type   Device
@@ -34,12 +41,14 @@
          * I'd like to use better names here, but I'd like to understand the
          * difference between the two first:
          */
-        attribute   Builtin::symbol             perm_addr;
-        attribute   Builtin::symbol             dev_addr;
+        attribute   Builtin::symbol perm_addr;
+        attribute   Builtin::symbol dev_addr;
+        attribute   Builtin::symbol irq;
     }
 
     required sequence   open(Ethernet::Device)
     {
+        provided chunk  LKM::includes();
         provided chunk  LKM::prototypes();
         provided chunk  LKM::code();
     }
@@ -69,8 +78,7 @@
 
         provided pointcut   Ethernet::adapter_init_context(Ethernet::Device,
                                                            Builtin::number,
-                                                           Builtin::symbol,
-                                                           Builtin::number);
+                                                           Builtin::symbol);
         provided pointcut   Ethernet::adapter_reset(Ethernet::Device);
         provided pointcut   Ethernet::adapter_load_mac_address(Ethernet::Device);
     }
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
@@ -4,13 +4,6 @@
     {
         Log::info("opening the device");
 
-        /*
-         * Maybe e1000::create_device should be called from here, to be
-         * more coherent.
-         */
-
-        e1000::setup_interrupt_handler(dev);
-        Log::info("interrupt handler installed");
 
         e1000::set_up_device(dev);
         Log::info("device activated");
@@ -32,9 +25,6 @@
          */
         e1000::free_rx_tx(dev);
         Log::info("free'ed up rx/tx resources");
-
-        e1000::free_interrupt_handler(dev);
-        Log::info("interrupt handler free'ed");
     }
 
     Ethernet::interrupt_handler(Ethernet::Device dev)
diff --git a/rathaxes/samples/e1000/pci.blt b/rathaxes/samples/e1000/pci.blt
--- a/rathaxes/samples/e1000/pci.blt
+++ b/rathaxes/samples/e1000/pci.blt
@@ -16,15 +16,15 @@
         {
         }
 
-        method  set_context(Builtin::symbol ctx)
+        method  set_rtx_context(Builtin::symbol ctx)
         {
-            pci_set_drvdata(&${self}->data, ${ctx});
+            pci_set_drvdata(${self.k_pci_dev}, ${ctx});
         }
 
         map
         {
-            data: ${self}->data;
-            drv_data: pci_get_drvdata(&${self}->data);
+            k_pci_dev: ((struct pci_dev *)${self});
+            rtx_pci_ctx: pci_get_drvdata((struct pci_dev *)${self});
         }
     }
 
@@ -52,13 +52,13 @@
                 int error;
                 ${PCI::AbstractDevice}  *enable_pdev = self->pdev;
                 ${cast local.enable_pdev as PCI::AbstractDevice};
-                error = pci_enable_device(&${local.enable_pdev.data});
+                error = pci_enable_device(${local.enable_pdev.k_pci_dev});
                 if (error)
                     return error;
-                error = pci_request_selected_regions(&${local.enable_pdev.data}, self->bars, ${config.name});
+                error = pci_request_selected_regions(${local.enable_pdev.k_pci_dev}, self->bars, ${config.name});
                 if (error)
                     return error;
-                pci_set_master(&${local.enable_pdev.data});
+                pci_set_master(${local.enable_pdev.k_pci_dev});
                 return 0;
             }
 
@@ -68,8 +68,8 @@
                 ${cast local.disable_pdev as PCI::AbstractDevice};
                 if (self->ioaddr)
                     iounmap(self->ioaddr);
-                pci_release_selected_regions(&${local.disable_pdev.data}, self->bars);
-                pci_disable_device(&${local.disable_pdev.data});
+                pci_release_selected_regions(${local.disable_pdev.k_pci_dev}, self->bars);
+                pci_disable_device(${local.disable_pdev.k_pci_dev});
             }
         }
 
@@ -78,7 +78,7 @@
             ${PCI::AbstractDevice} * workaround = (${PCI::AbstractDevice}*)pdev;
             ${cast local.workaround as PCI::AbstractDevice};
             ${self}->pdev = ${pdev};
-            ${self}->bars = pci_select_bars(&${local.workaround.data}, IORESOURCE_MEM);
+            ${self}->bars = pci_select_bars(${local.workaround.k_pci_dev}, IORESOURCE_MEM);
             ${self}->ioaddr = NULL;
             ${self}->context = NULL;
         }
@@ -97,18 +97,18 @@
         {
             ${PCI::AbstractDevice} *select_ioaddr_pdev = ${self}->pdev;
             ${cast local.select_ioaddr_pdev as PCI::AbstractDevice};
-            ${self}->ioaddr = pci_ioremap_bar(&${local.select_ioaddr_pdev.data}, ${bar});
+            ${self}->ioaddr = pci_ioremap_bar(${local.select_ioaddr_pdev.k_pci_dev}, ${bar});
         }
 
-        method  set_context(Builtin::symbol ctx)
+        method  set_rtx_drv_context(Builtin::symbol ctx)
         {
             ${self}->context = ctx;
         }
 
         map
         {
-            context: ${self}->context;
-            device: &${self}->pdev->data.dev;
+            rtx_drv_context: ${self}->context;
+            device: &((struct pci_dev *)(${self})->pdev->dev);
             pci_device: ${self}->pdev;
             irq: ${self}->pdev->data.irq;
             bars: ${self}->bars;
@@ -151,7 +151,7 @@
                     ${local.rtx_pci_dev.init(local.rtx_pdev)};
                 }
 
-                /* ${local.pdev.set_context(local.rtx_pci_dev)}; */
+                /* ${local.pdev.set_rtx_context(local.rtx_pci_dev)}; */
                 pci_set_drvdata(pdev, rtx_pci_dev);
 
                 /* ${local.rtx_pci_dev.enable()}; */
@@ -184,7 +184,7 @@
                 return 0;
 
             fail:
-                /* ${local.pdev.set_context(NULL)}; */
+                /* ${local.pdev.set_rtx_drv_context(NULL)}; */
                 pci_set_drvdata(pdev, NULL);
                 kfree(rtx_pci_dev);
                 return error;
@@ -210,7 +210,7 @@
             {
                 ${PCI::AbstractDevice}  *rtx_pdev = (${PCI::AbstractDevice}*)pdev;
                 ${cast local.rtx_pdev as PCI::AbstractDevice};
-                ${PCI::Device} *rtx_pci_dev = ${rtx_pdev.drv_data};
+                ${PCI::Device} *rtx_pci_dev = ${rtx_pdev.rtx_pci_ctx};
 
                 BUG_ON(!rtx_pci_dev);
 
diff --git a/rathaxes/samples/e1000/pci.rti b/rathaxes/samples/e1000/pci.rti
--- a/rathaxes/samples/e1000/pci.rti
+++ b/rathaxes/samples/e1000/pci.rti
@@ -10,10 +10,15 @@
 
         chunk       LKM::includes();
         method      init(PCI::AbstractDevice);
-        method      set_context(Builtin::symbol);
+        /*
+         * XXX: the argument should be a PCI::Device but that causes a circular
+         * dependency:
+         */
+        method      set_rtx_context(Builtin::symbol);
 
-        attribute   Builtin::symbol data;
-        attribute   Builtin::symbol drv_data;
+        attribute   Builtin::symbol k_pci_dev;
+        /* XXX: should be PCI::Device (see above point) */
+        attribute   Builtin::symbol rtx_pci_ctx;
     }
 
     provided type   PCI::Device
@@ -27,9 +32,9 @@
         method      enable();
         method      disable();
         method      select_ioaddr(Builtin::number);
-        method      set_context(Builtin::symbol);
+        method      set_rtx_drv_context(Builtin::symbol);
 
-        attribute   Builtin::symbol         context;
+        attribute   Builtin::symbol         rtx_drv_context;
         attribute   Device::AbstractDevice  device;
         attribute   PCI::AbstractDevice     pci_device;
         attribute   Builtin::symbol         ioaddr;
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
@@ -14,7 +14,7 @@
 
         map
         {
-            data: ${self}->data;
+            k_sk_buff: ((struct sk_buff *)${self});
         }
     }
 
@@ -131,22 +131,22 @@
 
         method   map_to(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_map(${self}, &${dev.data}, DMA_TO_DEVICE);
+            rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_TO_DEVICE);
         }
 
         method   map_from(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_map(${self}, &${dev.data}, DMA_FROM_DEVICE);
+            rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
         }
 
         method   unmap_to_and_free(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_unmap_and_free(${self}, &${dev.data}, DMA_TO_DEVICE);
+            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_TO_DEVICE);
         }
 
         method   unmap_from_and_free(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_unmap_and_free(${self}, &${dev.data}, DMA_FROM_DEVICE);
+            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
         }
 
         map
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
@@ -5,7 +5,7 @@
     {
         chunk       LKM::includes();
         decl        data_types();
-        attribute   Builtin::symbol data;
+        attribute   Builtin::symbol k_sk_buff;
     }
 
     provided type   SKBuff