changeset 106:976a4b87803f

Fix the resolution and the e1000 sample with the new scalar ref feature
author David Pineau <dav.pineau@gmail.com>
date Mon, 25 Mar 2013 01:17:56 +0100
parents fb20f01ea997
children f42751b8ca99
files E1000_UpdateToScalarRef FixRecursiveTypeFieldResolution FixScalarRefCasts FixScalarRefPlaceholders FixScalarRefUnstrictBug rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch series
diffstat 8 files changed, 976 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/E1000_UpdateToScalarRef	Mon Mar 25 01:17:56 2013 +0100
@@ -0,0 +1,600 @@
+# 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});
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FixRecursiveTypeFieldResolution	Mon Mar 25 01:17:56 2013 +0100
@@ -0,0 +1,128 @@
+# HG changeset patch
+# Parent f625aa6908ee7a45ab3f97d7137f45003ef02975
+Fix the recursive field resolution within types.
+
+diff --git a/rathaxes/compiler/passes/common/rtxResolve.inc.cws b/rathaxes/compiler/passes/common/rtxResolve.inc.cws
+--- a/rathaxes/compiler/passes/common/rtxResolve.inc.cws
++++ b/rathaxes/compiler/passes/common/rtxResolve.inc.cws
+@@ -739,9 +739,13 @@
+                 local source_type;
+ 
+                 // First retrieve the type of the value we just resolved.
+-                if (getArraySize(subidentifiers) != 0)
++                if (getArraySize(subidentifiers) == 1)
+                 {
+-                    ref source_type = theChunk.type_map[varName];
++                    // If there's a resval argument for it, then take the source type from there
++                    // Otherwise, use the chunk's type_map.
++                    if (rtxNodeArg_getRType(self, source_type) == false)
++                    { ref source_type = theChunk.type_map[varName]; }
++                    rtxNodeArg_getRType(self, source_type);
+                 }
+                 else
+                 {
+@@ -1100,6 +1104,7 @@
+                 return false;
+             }
+ 
++
+             if (instanceChunk<c_tree.instanceKey>(resVals, c_tree.body, source_tree) != false)
+             {
+                 rtxResolve_InsertCode(theBlock, startIdx, phName, phIdx, c_tree.body);
+@@ -1115,6 +1120,7 @@
+         if (errcount != 0)
+             return false;
+     }
++
+     return true;
+ }
+ 
+@@ -1309,39 +1315,69 @@
+                      placeHolder : node, out_node : node, source_tree : reference)
+ {
+     traceLine("rtxResolve:<LOG> type_map<"+T+"> for variable '"+mappedIds#[0]+"' ("+toString(mappedIds)+")");
+-    local   theTemplate;
+     local   identifiers;
+-
+-    if (rtxLink_FindUniqueTemplate(theRtype, source_tree.config, theTemplate) == false)
+-        return false;
++    local   actual_resVals;
++    local   actual_rtype;
++    setall actual_rtype = theRtype;
++    setall actual_resVals = resolverValues;
+ 
+     setall identifiers = mappedIds;
+     removeFirstElement(identifiers);
+     if (getArraySize(identifiers) > 0)
+     {
+-        // Now that we have selected an unique template, load the tree+script
+-        local   subtree;
+-        rtxLink_LoadItem(theTemplate, subtree);
+-        localref theMapping = subtree.mapping.body.block[identifiers#front];
+-
+-        // Call the right mapping function (based on hash + identifier mapped).
+-        traceLine("type_map<"+T+">:<LOG> type_map<" + T + ">: Calling mapping key : "
+-                  + theMapping.instanceKey);
+-
+-        if (instanceMapping<theMapping.instanceKey>(resolverValues, subtree, source_tree) == false)
++        local self_arg;
++        local prev_expr;
++        if (rtxNodeArgs_GetArgByName(resolverValues, "self", self_arg) == false)
+         {
+-            traceLine(RED + "[Error] type_map<"+T+">: instanceMapping<\""+theMapping.instanceKey+"\"> failed");
+-            traceLine(RED + "        for mapping at " + placeHolder#parent.location + "." + DEFAULT_COLOR);
++            traceLine(RED + "[Error] type_map<"+T+">: Could not retrieve self." + DEFAULT_COLOR);
+             return false;
+         }
++        rtxNodeArg_getValue(self_arg, prev_expr);
+ 
+-        setall out_node = theMapping.body.expr;
++        while (getArraySize(identifiers) > 0)
++        {
++            local   theTemplate;
++            local   subtree;
++            if (rtxLink_FindUniqueTemplate(actual_rtype, source_tree.config, theTemplate) == false)
++                return false;
++            rtxLink_LoadItem(theTemplate, subtree);
++            localref theMapping = subtree.mapping.body.block[identifiers#front];
++
++            // Call the right mapping function (based on hash + identifier mapped).
++            traceLine("type_map<"+T+">:<LOG> type_map<" + T + ">: Calling mapping key : "
++                      + theMapping.instanceKey);
++
++            if (instanceMapping<theMapping.instanceKey>(actual_resVals, subtree, source_tree) == false)
++            {
++                traceLine(RED + "[Error] type_map<"+T+">: instanceMapping<\""+theMapping.instanceKey+"\"> failed");
++                traceLine(RED + "        for mapping at " + placeHolder#parent.location + "." + DEFAULT_COLOR);
++                return false;
++            }
++
++            // Update actual rtype.
++            local rtypeName = rtxRTypeName<actual_rtype.type>(actual_rtype);
++            local field_rtype;
++            if (rtxTypingLookup_TypeField<rtypeName>(actual_rtype, identifiers#front, placeHolder#root, source_tree, field_rtype) == false)
++            {
++                traceLine(RED + "[Error] Could not resolve type field '"
++                          + identifiers#front + "' for type " + rtypeName + DEFAULT_COLOR);
++                return false;
++            }
++
++            setall prev_expr = theMapping.body.expr;
++            setall actual_rtype = field_rtype;
++            clearVariable(actual_resVals);
++            rtxNodeArgs(actual_resVals);
++            rtxNodeArgs_AppendArg(actual_resVals, "self", actual_rtype, prev_expr);
++            removeFirstElement(identifiers);
++        }
+     }
+-    else
++
++    // Now, resolve as a "self"
+     {
+         local self;
+         local val;
+-        if (rtxNodeArgs_GetArgByName(resolverValues, "self", self) == false)
++        if (rtxNodeArgs_GetArgByName(actual_resVals, "self", self) == false)
+         {
+             error(RED + "Could not get value..." + DEFAULT_COLOR);
+         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FixScalarRefCasts	Mon Mar 25 01:17:56 2013 +0100
@@ -0,0 +1,60 @@
+# HG changeset patch
+# Parent 9fcbcd542e91d0b05c087f4c44cb26c6f4df9ddc
+Add .ref and .scalar to rathaxes types
+
+diff --git a/rathaxes/compiler/node/rtxNodeBack.inc.cws b/rathaxes/compiler/node/rtxNodeBack.inc.cws
+--- a/rathaxes/compiler/node/rtxNodeBack.inc.cws
++++ b/rathaxes/compiler/node/rtxNodeBack.inc.cws
+@@ -19,7 +19,7 @@
+ declare function rtxNodePlaceHolder(local_node : node);
+ declare function rtxNodeCall(local_node : node, theVars : node, theChunk : node, out_ref_params : reference);
+ declare function rtxNodeSequenceCall(local_node : node, name : node, args : node);
+-declare function rtxNodeCast(local_node : node, varName : value, typeId : node);
++declare function rtxNodeCast(local_node : node, varName : value, typeId : node, sQualifier : value);
+ // Tool functions for the resolution/generation
+ declare function rtxNodeResVal_GetField(resolver_values : node, idList : node, out_ref : reference);
+ declare function rtxNodeResVal(local_node : node);
+@@ -233,7 +233,7 @@
+         return true;
+ }
+ 
+-function rtxNodeCast(local_node : node, varName : value, typeId : node)
++function rtxNodeCast(local_node : node, varName : value, typeId : node, sQualifier : value)
+ {
+     rtxNode(local_node);
+     local_node.type = "__rtx_tpl_cast__";
+@@ -244,6 +244,8 @@
+     local dummy;
+     if (rtxNodeRType(local_node.rtype, typeId, dummy) == false)
+         return false;
++    if (rtxNodeRType_SetQualifier(local_node.rtype, sQualifier) == false)
++        return false;
+ 
+     return true;
+ }
+diff --git a/rathaxes/compiler/passes/back/rtxMeta.inc.cws b/rathaxes/compiler/passes/back/rtxMeta.inc.cws
+--- a/rathaxes/compiler/passes/back/rtxMeta.inc.cws
++++ b/rathaxes/compiler/passes/back/rtxMeta.inc.cws
+@@ -292,15 +292,20 @@
+ 
+                 // Here, we allow casting a local C variable into a rathaxes type. This casts lasts for the current chunk's scope.
+                 tpl_cast(theCast : node) ::=
++/**/                    => local sQualifier = "scalar";
+                         "cast"
++                        #continue(sError, "A cast can only be applied to a local variable (\"local.\" is expected).")
+                         => local typeId;
+-                        #continue(sError, "A cast can only be applied to a local variable (\"local.\" is expected).")
+                         "local" '.' rootidentifier:varName
+                         #continue(sError, "Expected 'as' token for a rathaxes cast.")
+                         "as"
+                         #continue(sError, "Expected Type name for casting type.")
+                         rtx_scoped_identifier(typeId, false)
+-                        #check(rtxNodeCast(theCast, varName, typeId))
++                        [
++                            "."
++                            tpl_type_qualifier:sQualifier
++                        ]?
++                        #check(rtxNodeCast(theCast, varName, typeId, sQualifier))
+                 ;
+ 
+                 tpl_type_qualifier ::=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FixScalarRefPlaceholders	Mon Mar 25 01:17:56 2013 +0100
@@ -0,0 +1,81 @@
+# HG changeset patch
+# Parent ff998c040d556c284f488a9565ddd38bb21a5737
+Fix Scalar/Ref placeholders annotations by adding a 'copy' that does not alter the current state
+
+diff --git a/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws b/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws
+--- a/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws
++++ b/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws
+@@ -194,12 +194,13 @@
+                 // in unstrict mode
+                 if (existVariable(ctype_ref.unknown) && $getArraySize(ctype_ref.unknown) > 0$)
+                 {       
+-                        ctype_ref.identifier = ctype_ref.unknown#back;
+-                        removeVariable(ctype_ref.unknown);
++                    ctype_ref.identifier = ctype_ref.unknown#back;
++                    removeVariable(ctype_ref.unknown);
+                 }
+                 // name of a type
+                 if (existVariable(ctype_ref.identifier) && rtxPH_havePlaceHolder(ctype_ref.identifier))
+                 { rtxPH_mapPlaceHolder(ctype_ref.identifier, compile, node_idx, "target_decl"); }
++
+                 // composed
+                 if (existVariable(ctype_ref.list))
+                 {
+@@ -266,7 +267,7 @@
+ // So do not bother with subtypes and check them all and then recurse.
+ function        rtxPH_compile<"__expr__">(local_node : node, compile : node, node_idx : value)
+ {
+-        if (!existVariable(this.phtype)) insert this.phtype = "scalar";/////
++        if (!existVariable(this.phtype)) insert this.phtype = "copy";//// set to default
+         // left for bin operator
+         if (existVariable(local_node.left))
+         { 
+@@ -275,7 +276,7 @@
+                 // all post expr case [] or (), are pointer
+                 if (local_node.expr_type == "__postexpr__") { insert this.phtype = "pointer";}////
+                 rtxPH_compile<local_node.left.type>(local_node.left, compile, node_idx); 
+-                insert this.phtype = "scalar";////
++                insert this.phtype = "copy";//// set to default
+         }
+         // right for bin operator
+         if (existVariable(local_node.right))
+@@ -283,7 +284,7 @@
+                 // the unary *
+                 if (local_node.operator == "*" && local_node.expr_type == "__unary__") {insert this.phtype = "pointer";}////
+                 rtxPH_compile<local_node.right.type>(local_node.right, compile, node_idx); 
+-                insert this.phtype = "scalar";////
++                insert this.phtype = "copy";//// set to default
+         }
+         // if,while
+         if (existVariable(local_node.condition))
+diff --git a/rathaxes/compiler/passes/common/rtxResolve.inc.cws b/rathaxes/compiler/passes/common/rtxResolve.inc.cws
+--- a/rathaxes/compiler/passes/common/rtxResolve.inc.cws
++++ b/rathaxes/compiler/passes/common/rtxResolve.inc.cws
+@@ -177,6 +177,10 @@
+     if (out_type == "ref")
+         out_type = "pointer";
+ 
++    // Then, check if we need any changes or not for the out_type
++    if (out_type == "copy") // Copy means that we keep the current state, whether pointer or scalar.
++        return true;
++
+     // make sure in and out types are either scalar or ref
+     if ((in_type != "scalar" && in_type != "pointer")
+         || (out_type != "scalar" && out_type != "pointer"))
+@@ -593,7 +597,7 @@
+     // We want to set the mangled typedef name into the ctype's identifier:
+     // (equivalent of: theDecl.ctype.identifier = COMPUTED_NAME;)
+     local_node#parent.ref_placeholder.identifier = rtxResolve_MangleTypeName(theRtype, theRtype.qualifier != "scalar");
+-    
++
+     return true;
+ }
+ 
+@@ -756,7 +760,6 @@
+                 { error(RED + "[Error] Cannot transcribe an expression from " + in_type + " to " + out_type + DEFAULT_COLOR); }
+                 setall local_node#parent.ref_placeholder = mapping;
+             }
+-
+         }
+         else if (isBuiltinVariable(varName)) // Mapping for a  builtin type
+         {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FixScalarRefUnstrictBug	Mon Mar 25 01:17:56 2013 +0100
@@ -0,0 +1,75 @@
+# HG changeset patch
+# Parent 3f3babe6040fc925e39353a4b36270ae100f7f6b
+Work around an unstrict cnorm bug issue concerning the function declarations.
+
+diff --git a/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws b/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws
+--- a/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws
++++ b/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws
+@@ -213,9 +213,65 @@
+                             { rtxPH_compile<item.type>(item, compile, node_idx); }
+                         }
+                 }
+-                // recurse param list
++                // recurse param list + Resolve unknown before going down.
+                 if (existVariable(ctype_ref.param))
+-                { rtxPH_compile<ctype_ref.param.type>(ctype_ref.param, compile, node_idx);}
++                {
++                    // XXX FIXME
++                    // This is a workaround for a bug involving the unstrict cnorm.
++                    // We patch-up the function's arg's types and names before checking further.
++                    local argnames;
++                    foreach param in ctype_ref.param.block
++                    {
++                        localref theType = param;
++                        localref param_ctype = theType.ctype;
++
++                        //First setup the iterator over the right param to retrieve name.
++                        local name_it;
++                        local it_idx = 0;
++                        createIterator(name_it, ctype_ref.param.map);
++                        while (it_idx != index(param))
++                        {
++                            next(name_it);
++                            increment(it_idx);
++                        }
++                        local theName = key(name_it);
++
++                        if (existVariable(param_ctype.unknown))
++                        {
++                            local placeholder_key = false;
++                            foreach token in param_ctype.unknown
++                            {
++                                local theKey = key(token);
++                                if (rtxPH_havePlaceHolder(theKey))
++                                {
++                                    placeholder_key = theKey;
++                                    break ;
++                                }
++                            }
++                            if (placeholder_key == false) // no token found
++                            {
++                                param_ctype.identifier = param_ctype.unknown#back;
++                                removeVariable(param_ctype.unknown);
++                            }
++                            else // placeholder found -> Set as type, use other var as name.
++                            {
++                                param_ctype.identifier = placeholder_key;
++                                removeVariable(param_ctype.unknown[placeholder_key]);
++                                local last_it;
++                                createReverseIterator(last_it, param_ctype.unknown);
++                                theName = key(last_it);
++                                removeVariable(param_ctype.unknown);
++                                insert param.name = theName;
++                            }
++                        }
++                        insert argnames[theName] = index(param);
++                    }
++                    setall ctype_ref.param.map = argnames;
++
++                    rtxPH_compile<ctype_ref.param.type>(ctype_ref.param, compile, node_idx);
++                }
++
++
+                 // if type is enum
+                 if (existVariable(ctype_ref.enum))
+                 {
--- a/rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch	Fri Mar 22 00:25:52 2013 -0700
+++ b/rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch	Mon Mar 25 01:17:56 2013 +0100
@@ -1,5 +1,5 @@
 # HG changeset patch
-# Parent 1fa9b24e6012b2d53f1a84d4606cf3b6b9685fef
+# Parent f046837f963dcba715cebe8b6dc40e7bbe2ce598
 rathaxes: change the abstract type notation in the e1000 sample
 
 Starting with ra24db32bf134 Rathaxes types are generated differently: you
@@ -56,8 +56,8 @@
          decl        data_types();
          chunk       LKM::includes();
          method      init();
--        attribute   Builtin::symbol data;
-+        attribute   Builtin::symbol k_device;
+-        attribute   Builtin::symbol.scalar data;
++        attribute   Builtin::symbol.scalar k_device;
      }
  }
 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
@@ -472,30 +472,17 @@
          chunk       LKM::includes();
 +        method      init(Builtin::symbol);
          decl        data_types();
--        attribute   Builtin::symbol netdev;
+-        attribute   Builtin::symbol.scalar netdev;
 +
-+        attribute   Builtin::symbol k_net_dev;
++        attribute   Builtin::symbol.scalar k_net_dev;
 +        /*
 +         * XXX: should be a Ethernet::Device, but that causes a circular
 +         * dependency.
 +         */
-+        attribute   Builtin::symbol rtx_ether_ctx;
++        attribute   Builtin::symbol.scalar rtx_ether_ctx;
      }
  
      provided type   Device
-@@ -34,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             perm_addr;
--        attribute   Builtin::symbol             dev_addr;
--        attribute   Builtin::symbol             irq;
-+        attribute   Builtin::symbol perm_addr;
-+        attribute   Builtin::symbol dev_addr;
-+        attribute   Builtin::symbol 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
@@ -617,32 +604,34 @@
          chunk       LKM::includes();
          method      init(PCI::AbstractDevice);
 -        method      set_context(Builtin::symbol);
+-
+-        attribute   Builtin::symbol.scalar data;
+-        attribute   Builtin::symbol.scalar drv_data;
 +        /*
 +         * 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;
++ 
++        attribute   Builtin::symbol.scalar k_pci_dev;
 +        /* XXX: should be PCI::Device (see above point) */
-+        attribute   Builtin::symbol rtx_pci_ctx;
++        attribute   Builtin::symbol.scalar rtx_pci_ctx;
      }
  
      provided type   PCI::Device
-@@ -27,9 +32,9 @@
+@@ -27,9 +32,10 @@
          method      enable();
          method      disable();
          method      select_ioaddr(Builtin::number);
 -        method      set_context(Builtin::symbol);
+ 
+-        attribute   Builtin::symbol.scalar      context;
 +        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;
++ 
++        attribute   Builtin::symbol.scalar      rtx_drv_context;
+         attribute   Device::AbstractDevice.ref  device;
+         attribute   PCI::AbstractDevice.ref     pci_device;
+         attribute   Builtin::symbol.ref         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
@@ -751,13 +740,12 @@
 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,8 @@
+@@ -5,7 +5,7 @@
      {
          chunk       LKM::includes();
          decl        data_types();
--        attribute   Builtin::symbol data;
-+
-+        attribute   Builtin::symbol k_sk_buff;
+-        attribute   Builtin::symbol.scalar data;
++        attribute   Builtin::symbol.scalar k_sk_buff;
      }
  
      provided type   SKBuff
--- a/rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch	Fri Mar 22 00:25:52 2013 -0700
+++ b/rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch	Mon Mar 25 01:17:56 2013 +0100
@@ -1,5 +1,5 @@
 # HG changeset patch
-# Parent 1e9f01563db8cac05d81f26c5e100d9629b67f1e
+# Parent db54879402d420664f53e83cb7f55204571a9a8e
 Move the interrupt handler init/cleanup out of e1000.blt
 
 This is not device dependant and can be done from the Ethernet subsystem
@@ -232,9 +232,9 @@
 +++ b/rathaxes/samples/e1000/ethernet.rti
 @@ -36,10 +36,12 @@
           */
-         attribute   Builtin::symbol             perm_addr;
-         attribute   Builtin::symbol             dev_addr;
-+        attribute   Builtin::symbol             irq;
+         attribute   Builtin::symbol.scalar      perm_addr;
+         attribute   Builtin::symbol.scalar      dev_addr;
++        attribute   Builtin::symbol.scalar      irq;
      }
  
      required sequence   open(Ethernet::Device)
--- a/series	Fri Mar 22 00:25:52 2013 -0700
+++ b/series	Mon Mar 25 01:17:56 2013 +0100
@@ -1,3 +1,8 @@
 maintainers_fix_indentation_in_use_rathaxes.patch
 rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch
 rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch
+FixScalarRefCasts
+FixScalarRefPlaceholders
+FixScalarRefUnstrictBug
+FixRecursiveTypeFieldResolution
+E1000_UpdateToScalarRef