view E1000_UpdateToScalarRef @ 107:f42751b8ca99

Fix the interrupt handler refactoring patch and update the abstract type notation patch accordingly
author Louis Opter <louis@lse.epita.fr>
date Sun, 24 Mar 2013 21:47:39 -0700
parents 976a4b87803f
children 7efe3212db3a
line wrap: on
line source

# HG changeset patch
# Parent 9e6d855c6c477852924e13d354686f18d2036a0e
Update the e1000 sample with the new features

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
@@ -87,7 +87,7 @@
         decl    data_types()
         {
             unsigned int                    size;
-            ${e1000::RxDescriptor}          *base;
+            ${e1000::RxDescriptor.ref}      base;
             dma_addr_t                      dma_base;
             ${Socket::SKBuff}               skbuffs[${config.rx_ring_size}];
         }
@@ -124,7 +124,7 @@
         {
             unsigned int                    size;
             /* XXX: can't use ${e1000::TxDescriptor} here: */
-            ${e1000::TxDescriptor}          *base; /* rename to descs */
+            ${e1000::TxDescriptor.ref}      base; /* rename to descs */
             dma_addr_t                      dma_base;
             ${Socket::SKBuff}               skbuffs[${config.tx_ring_size}];
             unsigned short                  head;
@@ -133,20 +133,20 @@
 
         chunk   LKM::prototypes()
         {
-            static void         rtx_e1000_tx_ring_clean(${e1000::TxRing} *);
-            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing} *);
-            static int          rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing} *, ${Socket::SKBuff} *);
-            static void         rtx_e1000_tx_ring_put(${e1000::TxRing} *, ${Socket::SKBuff} *);
+            static void         rtx_e1000_tx_ring_clean(${e1000::TxRing.ref});
+            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing.ref});
+            static int          rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing.ref}, ${Socket::SKBuff.ref});
+            static void         rtx_e1000_tx_ring_put(${e1000::TxRing.ref}, ${Socket::SKBuff.ref});
             /* FIXME: See issue #54 */
-            static void         rtx_e1000_tx_ring_start_xmit(${e1000::TxRing} *, /*const*/ ${e1000::Context} *);
+            static void         rtx_e1000_tx_ring_start_xmit(${e1000::TxRing.ref}, /*const*/ ${e1000::Context.ref});
         }
 
         chunk   LKM::code()
         {
-            static void         rtx_e1000_tx_ring_clean(${e1000::TxRing} *self)
+            static void         rtx_e1000_tx_ring_clean(${e1000::TxRing.ref} self)
             {
-                ${e1000::TxDescriptor}  *tx_desc;
-                bool                    done;
+                ${e1000::TxDescriptor.ref}  tx_desc;
+                bool                        done;
 
                 for (; self->head != self->tail; self->head++)
                 {
@@ -159,7 +159,7 @@
                 pr_info("%s: tx_ring_clean: moving head to %d/%d", ${config.name}, self->head, ${config.tx_ring_size});
             }
 
-            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing} *self)
+            static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing.ref} self)
             {
                 if (self->tail == self->head) /* ring is empty */
                     return 256; /* XXX: ${config.tx_ring_size}; */
@@ -169,19 +169,17 @@
                 return self->head - self->tail;
             }
 
-            static int          rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing} *self, ${Socket::SKBuff} *skb)
+            static int          rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing.ref} self, ${Socket::SKBuff.ref} skb)
             {
                 /* XXX We can't use ${skb} here because it's a pointer */
-                ${Socket::AbstractSKBuff} *k_skb = skb->skbuff;
-                ${cast local.k_skb as Socket::AbstractSKBuff};
+                ${Socket::AbstractSKBuff.ref} k_skb = skb->skbuff;
                 return skb_is_gso(${local.k_skb.k_sk_buff}) || ${local.k_skb.k_sk_buff}->ip_summed == CHECKSUM_PARTIAL;
             }
 
-            static void         rtx_e1000_tx_ring_put(${e1000::TxRing} *self, ${Socket::SKBuff} *skb)
+            static void         rtx_e1000_tx_ring_put(${e1000::TxRing.ref} self, ${Socket::SKBuff.ref} skb)
             {
                 /* XXX We can't use ${skb} here because it's a pointer */
-                ${Socket::AbstractSKBuff} *k_skb = skb->skbuff;
-                ${cast local.k_skb as Socket::AbstractSKBuff};
+                ${Socket::AbstractSKBuff.ref} k_skb = skb->skbuff;
                 WARN_ON(!skb);
 
                 /*
@@ -192,7 +190,7 @@
                  * code shouldn't be aware of it and use something more
                  * abstract.
                  */
-                ${e1000::TxDescriptor} *tx_desc = &self->base[self->tail];
+                ${e1000::TxDescriptor.ref} tx_desc = &self->base[self->tail];
                 tx_desc->lower.data = cpu_to_le32(
                         E1000_TXD_CMD_EOP  |
                         E1000_TXD_CMD_IFCS |
@@ -205,7 +203,7 @@
             }
 
             /* FIXME: See issue #54 */
-            static void         rtx_e1000_tx_ring_start_xmit(${e1000::TxRing} *self, /*const*/ ${e1000::Context} *hw_ctx)
+            static void         rtx_e1000_tx_ring_start_xmit(${e1000::TxRing.ref} self, /*const*/ ${e1000::Context.ref} hw_ctx)
             {
                 pr_info("%s: start_xmit: moving tail to %d/%d", ${config.name}, self->tail, ${config.tx_ring_size});
                 rtx_e1000_register_write32(hw_ctx, E1000_TDT, self->tail);
@@ -271,7 +269,7 @@
                                                Builtin::symbol ioaddr)
         {
             {
-                ${e1000::Context} *hw_ctx = &${rtx_ether_ctx}->hw_ctx;
+                ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
                 hw_ctx->bars = ${bars};
                 hw_ctx->ioaddr = ${ioaddr};
             }
@@ -280,8 +278,9 @@
         chunk   Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx)
         {
             {
-                ${e1000::Context} *hw_ctx = &${rtx_ether_ctx}->hw_ctx;
-                rtx_e1000_register_write32(hw_ctx, E1000_CTRL, E1000_CMD_RST);
+                /* XXX Naming this variable 'hw_ctx' kicks the decl out of the generated code */
+                ${e1000::Context.ref} tmp_hw_ctx = &${rtx_ether_ctx}->hw_ctx;
+                rtx_e1000_register_write32(tmp_hw_ctx, E1000_CTRL, E1000_CMD_RST);
                 udelay(10);
             }
         }
@@ -289,7 +288,7 @@
         chunk   Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx)
         {
             {
-                ${e1000::Context} *hw_ctx = &${rtx_ether_ctx}->hw_ctx;
+                ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx;
                 /* Shamelessly borrowed from Minix */
                 for (int i = 0; i < 3; ++i)
                 {
@@ -468,12 +467,12 @@
     {
         chunk   LKM::prototypes()
         {
-            static void rtx_e1000_print_status(${e1000::Context} *);
+            static void rtx_e1000_print_status(${e1000::Context.ref});
         }
 
         chunk   LKM::code()
         {
-            static void rtx_e1000_print_status(${e1000::Context} *hw_ctx)
+            static void rtx_e1000_print_status(${e1000::Context.ref} hw_ctx)
             {
                 unsigned int status = rtx_e1000_register_read32(hw_ctx, E1000_STATUS);
                     ${Log::info("card status:")};
@@ -518,13 +517,13 @@
         chunk   LKM::prototypes()
         {
             /* FIXME: See issue #54 */
-            static unsigned int    rtx_e1000_register_read32(/*const*/ ${e1000::Context} *, unsigned int);
+            static unsigned int    rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref}, unsigned int);
         }
 
         chunk   LKM::code()
         {
             /* FIXME: See issue #54 */
-            static unsigned int    rtx_e1000_register_read32(/*const*/ ${e1000::Context} *ctx, unsigned int reg_offset)
+            static unsigned int    rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset)
             {
                 return ioread32(ctx->ioaddr + reg_offset);
             }
@@ -541,13 +540,13 @@
         chunk   LKM::prototypes()
         {
             /* FIXME: See issue #54 */
-            static void rtx_e1000_register_write32(/*const*/ ${e1000::Context} *, unsigned int, unsigned int);
+            static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int);
         }
 
         chunk   LKM::code()
         {
             /* FIXME: See issue #54 */
-            static void rtx_e1000_register_write32(/*const*/ ${e1000::Context} *ctx, unsigned int reg_offset, unsigned int value)
+            static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value)
             {
                 iowrite32(value, ctx->ioaddr + reg_offset);
             }
@@ -564,13 +563,13 @@
         chunk   LKM::prototypes()
         {
             /* FIXME: See issue #54 */
-            static void rtx_e1000_register_set32(/*const*/ ${e1000::Context} *, unsigned int, unsigned int);
+            static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int);
         }
 
         chunk   LKM::code()
         {
             /* FIXME: See issue #54 */
-            static void rtx_e1000_register_set32(/*const*/ ${e1000::Context} *ctx, unsigned int reg_offset, unsigned int value)
+            static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value)
             {
                 iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset);
             }
@@ -587,13 +586,13 @@
         chunk   LKM::prototypes()
         {
             /* FIXME: See issue #54 */
-            static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context} *, unsigned int, unsigned int);
+            static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int);
         }
 
         chunk   LKM::code()
         {
             /* FIXME: See issue #54 */
-            static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context} *ctx, unsigned int reg_offset, unsigned int value)
+            static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value)
             {
                 iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset);
             }
@@ -644,7 +643,7 @@
              * e1000::Context? (but we would need to make it point back to
              * the struct net_device)
              */
-            ${e1000::Context} *hw_ctx;
+            ${e1000::Context.ref} hw_ctx;
             hw_ctx = &${rtx_ether_ctx}->hw_ctx;
 
             /*
@@ -755,7 +754,7 @@
              */
             for (i = 0; i != ${config.rx_ring_size}; ++i)
             {
-                hw_ctx->rx_ring.skbuffs[i].skbuff = (${Socket::AbstractSKBuff}*)netdev_alloc_skb(
+                hw_ctx->rx_ring.skbuffs[i].skbuff = (${Socket::AbstractSKBuff.ref})netdev_alloc_skb(
                         ${rtx_ether_ctx.net_device.k_net_dev}, /* XXX: .k_net_dev isn't expanded here */
                         ${config.rx_buffer_len});
                 if (!hw_ctx->rx_ring.skbuffs[i].skbuff)
@@ -894,8 +893,7 @@
              * XXX: Not generated if named "hw_ctx" (which is funny because
              * it's used and works in the template right above this one):
              */
-            ${e1000::Context} *hw_ctx_;
-            ${cast local.hw_ctx_ as e1000::Context};
+            ${e1000::Context.ref} hw_ctx_;
             hw_ctx_ = &${rtx_ether_ctx}->hw_ctx;
 
             /*
@@ -911,7 +909,7 @@
                         ${config.rx_buffer_len},
                         DMA_FROM_DEVICE);
                 /* XXX Go through the rtx types (Socket::SKBuff, AbstractSKBuff) */
-                dev_kfree_skb(hw_ctx_->rx_ring.skbuffs[i].skbuff);
+                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,
                     hw_ctx_->rx_ring.base, hw_ctx_->rx_ring.dma_base);
@@ -973,14 +971,14 @@
              */
 
             ${Socket::SKBuff} skb;
-            ${e1000::Context} *hw_ctx;
-            ${e1000::TxRing} *tx_ring;
-            ${Device::AbstractDevice} *devp;
+            ${e1000::Context.ref} hw_ctx;
+            ${e1000::TxRing.ref} tx_ring;
+            ${Device::AbstractDevice.ref} devp;
 
             ${local.skb.init(kernel_skb)};
             hw_ctx = &${rtx_ether_ctx}->hw_ctx;
             tx_ring = &hw_ctx->tx_ring;
-            devp = (${Device::AbstractDevice}*)${rtx_ether_ctx.device};
+            devp = (${Device::AbstractDevice.ref})${rtx_ether_ctx.device};
 
             ${Log::info("xmit: skbuff details:")};
             /*
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
@@ -61,7 +61,7 @@
 
         method  init(Builtin::symbol dev)
         {
-            ${self} = (${Ethernet::AbstractDevice} *)${dev};
+            ${self} = (${Ethernet::AbstractDevice.ref})${dev};
         }
 
         map
@@ -79,8 +79,8 @@
              * I think it's useless to use the ${PCI::AbstractDevice} "abstraction"
              * here, since we already are in a Linux specific context.
              */
-            ${PCI::AbstractDevice}          *pci_dev;
-            ${Ethernet::AbstractDevice}     *net_dev;
+            ${PCI::AbstractDevice.ref}          pci_dev;
+            ${Ethernet::AbstractDevice.ref}     net_dev;
 
             /*
              * In the long-term, this may disappear for a new concept allowing
@@ -144,14 +144,12 @@
                  * 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};
+                ${Ethernet::AbstractDevice.ref} rtx_net_dev;
                 { /* 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};
+                ${Ethernet::Device.ref} rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
 
                 int error;
                 {
@@ -189,10 +187,8 @@
         {
             static int  rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev)
             {
-                ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(net_dev);
-                ${Socket::AbstractSKBuff} *rtx_skb = (${Socket::AbstractSKBuff}*) kernel_skb;
-                ${cast local.rtx_skb as Socket::AbstractSKBuff};
-                ${cast local.rtx_ether_ctx as Ethernet::Device};
+                ${Ethernet::Device.ref} rtx_ether_ctx = netdev_priv(net_dev);
+                ${Socket::AbstractSKBuff.ref} rtx_skb = (${Socket::AbstractSKBuff.ref}) kernel_skb;
 
                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx, local.rtx_skb)};
             }
@@ -210,14 +206,12 @@
         {
             static int  rtx_ethernet_close(struct net_device *dev)
             {
-                ${Ethernet::AbstractDevice} *rtx_net_dev;
-                ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
+                ${Ethernet::AbstractDevice.ref} rtx_net_dev;
                 { /* 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};
+                ${Ethernet::Device.ref} rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
 
                 /* TODO: change this pointcut into a pointcut/adapter/callback: */
                 {
@@ -249,11 +243,9 @@
         {
             static enum irqreturn   rtx_ethernet_interrupt_handler(int irq, void *dev_id)
             {
-                ${Ethernet::AbstractDevice} *rtx_net_dev = dev_id;
-                ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
+                ${Ethernet::AbstractDevice.ref} rtx_net_dev = dev_id;
 
-                ${Ethernet::Device} *rtx_ether_ctx;
-                ${cast local.rtx_ether_ctx as Ethernet::Device};
+                ${Ethernet::Device.ref} rtx_ether_ctx;
                 rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
 
                 ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
@@ -285,12 +277,11 @@
          */
         chunk PCI::pci_probe_hook(PCI::Device rtx_pci_dev)
         {
-            ${Ethernet::AbstractDevice} *rtx_net_dev;
-            ${Ethernet::Device} *rtx_ether_ctx;
-            ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
+            ${Ethernet::AbstractDevice.ref} rtx_net_dev;
+            ${Ethernet::Device.ref} rtx_ether_ctx;
 
             /* Cast the result back into our "transparent wrapper" type */
-            rtx_net_dev = (${Ethernet::AbstractDevice}*)alloc_etherdev(sizeof(*rtx_ether_ctx));
+            rtx_net_dev = (${Ethernet::AbstractDevice.ref})alloc_etherdev(sizeof(*rtx_ether_ctx));
             if (!rtx_net_dev)
             {
                 ${Log::info("cannot allocate the ethernet device context")};
@@ -317,8 +308,7 @@
              * type of rtx_pci_dev.pci_device to the type of
              * rtx_pci_dev instead of the type of rtx_pci_dev.pci_device.
              */
-            ${PCI::AbstractDevice} *workaround = ${rtx_pci_dev.pci_device};
-            ${cast local.workaround as PCI::AbstractDevice};
+            ${PCI::AbstractDevice.ref} workaround = ${rtx_pci_dev.pci_device};
             { /* 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)};
             }
@@ -333,8 +323,7 @@
              */
             int bars = ${rtx_pci_dev.bars};
             unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr};
-            ${cast local.bars as Builtin::number};
-            ${cast local.rtx_ether_ctx as Ethernet::Device};
+            ${cast local.bars as Builtin::number.scalar};
             ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx,
                                                       local.bars,
                                                       local.ioaddr)};
@@ -359,12 +348,10 @@
          */
         chunk   PCI::pci_remove_hook(PCI::Device rtx_pci_dev)
         {
-            ${Ethernet::Device} *rtx_ether_ctx = ${rtx_pci_dev.rtx_drv_context};
-            ${cast local.rtx_ether_ctx as Ethernet::Device}; /* XXX */
+            ${Ethernet::Device.ref} rtx_ether_ctx = ${rtx_pci_dev.rtx_drv_context};
             BUG_ON(!rtx_ether_ctx);
 
-            ${Ethernet::AbstractDevice} *rtx_net_dev = ${local.rtx_ether_ctx.net_device};
-            ${cast local.rtx_net_dev as Ethernet::AbstractDevice}; /* XXX */
+            ${Ethernet::AbstractDevice.ref} rtx_net_dev = ${local.rtx_ether_ctx.net_device};
 
             unregister_netdev(${local.rtx_net_dev.k_net_dev});
             free_netdev(${local.rtx_net_dev.k_net_dev});
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
@@ -41,9 +41,9 @@
          * I'd like to use better names here, but I'd like to understand the
          * difference between the two first:
          */
-        attribute   Builtin::symbol.scalar      perm_addr;
-        attribute   Builtin::symbol.scalar      dev_addr;
-        attribute   Builtin::symbol.scalar      irq;
+        attribute   Builtin::symbol.ref        perm_addr;
+        attribute   Builtin::symbol.ref        dev_addr;
+        attribute   Builtin::symbol.ref        irq;
     }
 
     required sequence   open(Ethernet::Device)
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
@@ -32,7 +32,7 @@
     {
         decl    data_types()
         {
-            ${PCI::AbstractDevice}      *pdev;
+            ${PCI::AbstractDevice.ref}  pdev;
             int                         bars;
             /* It could be an array at some point: */
             unsigned char /* __iomem */ *ioaddr;
@@ -41,17 +41,16 @@
 
         chunk   LKM::prototypes()
         {
-            static int  rtx_pci_device_enable(${PCI::Device} *);
-            static void rtx_pci_device_disable(${PCI::Device} *);
+            static int  rtx_pci_device_enable(${PCI::Device.ref});
+            static void rtx_pci_device_disable(${PCI::Device.ref});
         }
 
         chunk   LKM::code()
         {
-            static int rtx_pci_device_enable(${PCI::Device} *self)
+            static int rtx_pci_device_enable(${PCI::Device.ref} self)
             {
                 int error;
-                ${PCI::AbstractDevice}  *enable_pdev = self->pdev;
-                ${cast local.enable_pdev as PCI::AbstractDevice};
+                ${PCI::AbstractDevice.ref}  enable_pdev = self->pdev;
                 error = pci_enable_device(${local.enable_pdev.k_pci_dev});
                 if (error)
                     return error;
@@ -62,10 +61,9 @@
                 return 0;
             }
 
-            static void rtx_pci_device_disable(${PCI::Device} *self)
+            static void rtx_pci_device_disable(${PCI::Device.ref} self)
             {
-                ${PCI::AbstractDevice}  *disable_pdev = self->pdev;
-                ${cast local.disable_pdev as PCI::AbstractDevice};
+                ${PCI::AbstractDevice.ref}  disable_pdev = self->pdev;
                 if (self->ioaddr)
                     iounmap(self->ioaddr);
                 pci_release_selected_regions(${local.disable_pdev.k_pci_dev}, self->bars);
@@ -75,8 +73,7 @@
 
         method  init(PCI::AbstractDevice pdev)
         {
-            ${PCI::AbstractDevice} * workaround = (${PCI::AbstractDevice}*)pdev;
-            ${cast local.workaround as PCI::AbstractDevice};
+            ${PCI::AbstractDevice.ref} workaround = (${PCI::AbstractDevice.ref})pdev;
             ${self}->pdev = ${pdev};
             ${self}->bars = pci_select_bars(${local.workaround.k_pci_dev}, IORESOURCE_MEM);
             ${self}->ioaddr = NULL;
@@ -95,8 +92,7 @@
 
         method  select_ioaddr(Builtin::number bar)
         {
-            ${PCI::AbstractDevice} *select_ioaddr_pdev = ${self}->pdev;
-            ${cast local.select_ioaddr_pdev as PCI::AbstractDevice};
+            ${PCI::AbstractDevice.ref} select_ioaddr_pdev = ${self}->pdev;
             ${self}->ioaddr = pci_ioremap_bar(${local.select_ioaddr_pdev.k_pci_dev}, ${bar});
         }
 
@@ -131,9 +127,8 @@
                                                       const struct pci_device_id *pdev_id)
             {
                 int error;
-                ${PCI::Device} *rtx_pci_dev;
-                ${PCI::AbstractDevice}  *rtx_pdev = (${PCI::AbstractDevice}*)pdev;
-                ${cast local.rtx_pdev as PCI::AbstractDevice};
+                ${PCI::Device.ref} rtx_pci_dev;
+                ${PCI::AbstractDevice.ref} rtx_pdev = (${PCI::AbstractDevice.ref})pdev;
 
                 rtx_pci_dev = kmalloc(sizeof(*rtx_pci_dev), GFP_KERNEL);
                 if (!rtx_pci_dev)
@@ -173,12 +168,6 @@
                     goto fail;
                 }
 
-                /*
-                 * XXX: We have to cast here because the compiler is
-                 * confused by the fact that rtx_pci_dev is a
-                 * pointer.
-                 */
-                ${cast local.rtx_pci_dev as PCI::Device};
                 ${pointcut PCI::pci_probe_hook(local.rtx_pci_dev)};
 
                 return 0;
@@ -208,14 +197,11 @@
         {
             static void rtx_pci_remove(struct pci_dev *pdev)
             {
-                ${PCI::AbstractDevice}  *rtx_pdev = (${PCI::AbstractDevice}*)pdev;
-                ${cast local.rtx_pdev as PCI::AbstractDevice};
-                ${PCI::Device} *rtx_pci_dev = ${rtx_pdev.rtx_pci_ctx};
+                ${PCI::AbstractDevice.ref}  rtx_pdev = (${PCI::AbstractDevice.ref})pdev;
+                ${PCI::Device.ref} rtx_pci_dev = ${rtx_pdev.rtx_pci_ctx};
 
                 BUG_ON(!rtx_pci_dev);
 
-                /* XXX: compiler confused by the pointer type. */
-                ${cast local.rtx_pci_dev as PCI::Device};
                 ${pointcut PCI::pci_remove_hook(local.rtx_pci_dev)};
 
                 /* ${local.rtx_pci_dev.disable()}; */
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
@@ -22,20 +22,20 @@
     {
         decl  data_types()
         {
-            ${Socket::AbstractSKBuff}   *skbuff;
-            dma_addr_t                  dma_handle;
+            ${Socket::AbstractSKBuff.ref}   skbuff;
+            dma_addr_t                      dma_handle;
         }
 
         chunk   LKM::prototypes()
         {
-            static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff} *);
-            static int  rtx_socket_skbuff_map(${Socket::SKBuff} *, struct device *, enum dma_data_direction);
-            static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff} *, struct device *, enum dma_data_direction);
+            static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff.ref});
+            static int  rtx_socket_skbuff_map(${Socket::SKBuff.ref}, struct device *, enum dma_data_direction);
+            static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref}, struct device *, enum dma_data_direction);
         }
 
         chunk   LKM::code()
         {
-            static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff} *self)
+            static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff.ref} self)
             {
                 WARN_ON(!self->skbuff);
 
@@ -44,8 +44,7 @@
                  * but Rathaxes doesn't support functions with a variable number of
                  * arguments yet.
                  */
-                ${Socket::AbstractSKBuff}   *skb = self->skbuff;
-                ${cast local.skb as Socket::AbstractSKBuff};
+                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
                 ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.k_sk_buff}->protocol) };
 
                 static const char * const ip_summed_values[] = {
@@ -66,12 +65,11 @@
                 );
             }
 
-            static int rtx_socket_skbuff_map(${Socket::SKBuff} *self,
+            static int rtx_socket_skbuff_map(${Socket::SKBuff.ref} self,
                                              struct device *dev,
                                              enum dma_data_direction direction)
             {
-                ${Socket::AbstractSKBuff}   *skb = self->skbuff;
-                ${cast local.skb as Socket::AbstractSKBuff};
+                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
 
                 WARN_ON(!${local.skb.k_sk_buff});
                 WARN_ON(self->dma_handle);
@@ -90,12 +88,11 @@
                 return 0;
             }
 
-            static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff} *self,
+            static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref} self,
                                                          struct device *dev,
                                                          enum dma_data_direction direction)
             {
-                ${Socket::AbstractSKBuff}   *skb = self->skbuff;
-                ${cast local.skb as Socket::AbstractSKBuff};
+                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
 
                 WARN_ON(!${local.skb.k_sk_buff});