Mercurial > archived > louis > epitech > mq > rathaxes
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch Thu Feb 28 23:30:59 2013 -0800 @@ -0,0 +1,759 @@ +# 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