# HG changeset patch # User Louis Opter # Date 1363935960 25200 # Node ID c4c33ac02b9303b6b234a6cf4bdd887b9c260463 # Parent d9af98faac8a2e20e574d6f3a4d7dc4983f5d71e First try at splitting the type nightmare and the refactoring diff -r d9af98faac8a -r c4c33ac02b93 rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch Fri Mar 22 00:06:00 2013 -0700 @@ -0,0 +1,762 @@ +# HG changeset patch +# Parent 6603911e89e5f98231c90bccf4f4cb9d5534e000 +rathaxes: change the abstract type notation in the e1000 sample + +Starting with ra24db32bf134 Rathaxes types are generated differently: you +don't define entire structures anymore, but only the fields. And the +compiler generate a typedef'ed structure on top of it. + +This works fine, except for "abstract types" (the types defined by —and +used to interact with— the kernel). We need to define these types as +Rathaxes types to interact with them, in Rathaxes, but with +ra24db32bf134 it means that we loose (hide) the original type from the +kernel, making it very difficult to use "abstract types" with the +kernels APIs. + +For example, here the hypothetical generated struct for the abstract +type "struct net_device" from Linux would be: + +typedef struct { + struct net_device data; +} rtx_GeneratedType; + +And here is how we have to use it: + +rtx_GeneratedType *my_struct; +kernel_api_function(&my_struct->data); + +This &my_struct->data is actually always a nop, but it's confusing and +hard to understand. + +This changeset changes the notation to: + +rtx_GeneratedType *my_struct; +kernel_api_function((struct net_device *)my_struct); + +Which is, I believe, more intuitive and coherent with how you would +initialize the my_struct pointer here with a return value from the +kernel (i.e: with a cast into rtx_GeneratedType *). + + +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 +@@ -171,13 +171,17 @@ + + static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing} *self, ${Socket::SKBuff} *skb) + { +- ${Socket::AbstractSKBuff} *abs_skb = skb->skbuff; +- ${cast local.abs_skb as Socket::AbstractSKBuff}; +- return skb_is_gso(&${local.abs_skb.data}) || ${local.abs_skb.data}.ip_summed == CHECKSUM_PARTIAL; ++ /* 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}; ++ 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) + { ++ /* 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}; + WARN_ON(!skb); + + /* +@@ -188,17 +192,15 @@ + * code shouldn't be aware of it and use something more + * abstract. + */ +- ${Socket::AbstractSKBuff} *abs_skb = skb->skbuff; +- ${cast local.abs_skb as Socket::AbstractSKBuff}; + ${e1000::TxDescriptor} *tx_desc = &self->base[self->tail]; + tx_desc->lower.data = cpu_to_le32( + E1000_TXD_CMD_EOP | + E1000_TXD_CMD_IFCS | + E1000_TXD_CMD_RS | +- skb_headlen(&${local.abs_skb.data})); ++ skb_headlen(${local.k_skb.k_sk_buff})); + tx_desc->upper.data = 0; + tx_desc->buff_addr = cpu_to_le64(skb->dma_handle); +- memcpy(&self->skbuffs[self->tail], skb, sizeof(*skb)); ++ memcpy(&self->skbuffs[self->tail], ${local.k_skb.k_sk_buff}, sizeof(*${local.k_skb.k_sk_buff})); + self->tail = (self->tail + 1) % ${config.tx_ring_size}; + } + +@@ -733,7 +735,7 @@ + hw_ctx->rx_ring.size = ${config.rx_ring_size} * sizeof(*hw_ctx->rx_ring.base); + hw_ctx->rx_ring.size = ALIGN(hw_ctx->rx_ring.size, 4096); + hw_ctx->rx_ring.base = dma_alloc_coherent( +- &${rtx_ether_ctx.device}, ++ ${rtx_ether_ctx.device}, + hw_ctx->rx_ring.size, + &hw_ctx->rx_ring.dma_base, + GFP_KERNEL); +@@ -751,12 +753,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.k_net_dev}, /* XXX: .k_net_dev isn't expanded here */ + ${config.rx_buffer_len}); + if (!hw_ctx->rx_ring.skbuffs[i].skbuff) + { +@@ -764,11 +764,11 @@ + goto err_skbuffs_alloc; + } + hw_ctx->rx_ring.skbuffs[i].dma_handle = dma_map_single( +- &${rtx_ether_ctx.device}, +- &hw_ctx->rx_ring.skbuffs[i].skbuff->data, ++ ${rtx_ether_ctx.device}, ++ (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}, ++ int dma_error = dma_mapping_error(${rtx_ether_ctx.device}, + hw_ctx->rx_ring.skbuffs[i].dma_handle); + if (dma_error) + { +@@ -820,7 +820,7 @@ + hw_ctx->tx_ring.size = ${config.tx_ring_size} * sizeof(*hw_ctx->tx_ring.base); + hw_ctx->tx_ring.size = ALIGN(hw_ctx->tx_ring.size, 4096); + hw_ctx->tx_ring.base = dma_alloc_coherent( +- &${rtx_ether_ctx.device}, ++ ${rtx_ether_ctx.device}, + hw_ctx->tx_ring.size, + &hw_ctx->tx_ring.dma_base, + GFP_KERNEL); +@@ -863,15 +863,16 @@ + while (i--) + { + dma_unmap_single( +- &${rtx_ether_ctx.device}, ++ ${rtx_ether_ctx.device}, + hw_ctx->rx_ring.skbuffs[i].dma_handle, + ${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, ++ dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx->rx_ring.size, + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); + err_rx_ring_alloc: + return -ENOMEM; +@@ -889,8 +890,13 @@ + { + chunk ::CALL() + { +- ${e1000::Context} *hw_ctx; +- hw_ctx = &${rtx_ether_ctx}->hw_ctx; ++ /* ++ * 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}; ++ hw_ctx_ = &${rtx_ether_ctx}->hw_ctx; + + /* + * Free the rx ring: +@@ -900,22 +906,23 @@ + for (int i = 0; i != ${config.rx_ring_size}; ++i) + { + dma_unmap_single( +- &${rtx_ether_ctx.device}, +- (dma_addr_t)hw_ctx->rx_ring.skbuffs[i].dma_handle, ++ ${rtx_ether_ctx.device}, ++ (dma_addr_t)hw_ctx_->rx_ring.skbuffs[i].dma_handle, + ${config.rx_buffer_len}, + DMA_FROM_DEVICE); +- dev_kfree_skb(&hw_ctx->rx_ring.skbuffs[i].skbuff->data); ++ /* XXX Go through the rtx types (Socket::SKBuff, AbstractSKBuff) */ ++ dev_kfree_skb(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); ++ dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->rx_ring.size, ++ hw_ctx_->rx_ring.base, hw_ctx_->rx_ring.dma_base); + ${Log::info("free_rx_tx: rx ring free'ed")}; + + /* + * Free the tx ring: + * - Free the descriptors array. + */ +- dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->tx_ring.size, +- hw_ctx->tx_ring.base, hw_ctx->tx_ring.dma_base); ++ dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->tx_ring.size, ++ hw_ctx_->tx_ring.base, hw_ctx_->tx_ring.dma_base); + ${Log::info("free_rx_tx: tx ring free'ed")}; + } + } +@@ -973,13 +980,13 @@ + ${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}*)${rtx_ether_ctx.device}; + + ${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): +@@ -1012,8 +1019,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; +@@ -1032,7 +1039,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/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt +--- a/rathaxes/samples/e1000/ethernet.blt ++++ b/rathaxes/samples/e1000/ethernet.blt +@@ -51,7 +51,7 @@ + { + decl data_types() + { +- struct net_device ndev; ++ struct net_device data; + } + + chunk LKM::includes() +@@ -59,9 +59,15 @@ + #include + } + ++ 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,24 +94,33 @@ + #include + } + +- 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; ++ * ++ * Also, using ${PCI::AbstractDevice} instead of directly struct ++ * pci_dev doesn't work. ++ */ ++ 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; + } + } + +@@ -125,8 +140,17 @@ + { + 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; +@@ -186,8 +210,13 @@ + { + 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: */ +@@ -220,9 +249,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; +@@ -252,23 +285,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")}; +@@ -280,14 +316,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: */ +@@ -309,7 +342,7 @@ + ${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) */ +@@ -326,15 +359,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,8 +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 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 +@@ -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,20 +97,20 @@ + { + ${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; ++ irq: ((struct pci_dev *)(${self})->pdev)->irq; + bars: ${self}->bars; + ioaddr: ${self}->ioaddr; + BAR_0: 0; +@@ -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}); + } + } + +@@ -46,11 +46,12 @@ + */ + ${Socket::AbstractSKBuff} *skb = self->skbuff; + ${cast local.skb as Socket::AbstractSKBuff}; +- ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.data}.protocol) }; ++ ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.k_sk_buff}->protocol) }; ++ + static const char * const ip_summed_values[] = { + "none", "unnecessary", "complete", "partial" + }; +- struct skb_shared_info *shinfo = skb_shinfo(&${local.skb.data}); ++ struct skb_shared_info *shinfo = skb_shinfo(${local.skb.k_sk_buff}); + + pr_info( + "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n" +@@ -59,8 +60,8 @@ + "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u", + /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */ + ethernet_proto.id, ${local.ethernet_proto.str}, +- ${local.skb.data}.ip_summed, ip_summed_values[${local.skb.data}.ip_summed], +- ${local.skb.data}.len, ${local.skb.data}.data_len, skb_headlen(&${local.skb.data}), ++ ${local.skb.k_sk_buff}->ip_summed, ip_summed_values[${local.skb.k_sk_buff}->ip_summed], ++ ${local.skb.k_sk_buff}->len, ${local.skb.k_sk_buff}->data_len, skb_headlen(${local.skb.k_sk_buff}), + shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type + ); + } +@@ -72,14 +73,13 @@ + ${Socket::AbstractSKBuff} *skb = self->skbuff; + ${cast local.skb as Socket::AbstractSKBuff}; + +- WARN_ON(!skb); +- WARN_ON(!${local.skb.data}.data); ++ WARN_ON(!${local.skb.k_sk_buff}); + WARN_ON(self->dma_handle); + + self->dma_handle = dma_map_single( + dev, +- &${local.skb.data}.data, +- skb_headlen(&${local.skb.data}), ++ ${local.skb.k_sk_buff}, ++ skb_headlen(${local.skb.k_sk_buff}), + direction); + int err = dma_mapping_error(dev, self->dma_handle); + if (err) +@@ -97,18 +97,17 @@ + ${Socket::AbstractSKBuff} *skb = self->skbuff; + ${cast local.skb as Socket::AbstractSKBuff}; + +- WARN_ON(!${local.skb}); +- WARN_ON(!${local.skb.data}.data); ++ WARN_ON(!${local.skb.k_sk_buff}); + + if (self->dma_handle) + { + dma_unmap_single(dev, + self->dma_handle, +- skb_headlen(&${local.skb.data}), ++ skb_headlen(${local.skb.k_sk_buff}), + direction); + self->dma_handle = 0; + } +- dev_kfree_skb_any(&${local.skb.data}); ++ dev_kfree_skb_any(${local.skb.k_sk_buff}); + self->skbuff = 0; + } + } +@@ -131,22 +130,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,8 @@ + { + chunk LKM::includes(); + decl data_types(); +- attribute Builtin::symbol data; ++ ++ attribute Builtin::symbol k_sk_buff; + } + + provided type SKBuff diff -r d9af98faac8a -r c4c33ac02b93 rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch Fri Mar 22 00:06:00 2013 -0700 @@ -0,0 +1,266 @@ +# HG changeset patch +# Parent 68c4f142af579e558314cdeebd091fc5abd62014 + +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 +- } +- +- 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() +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() + { +@@ -111,6 +111,11 @@ + + template sequence Ethernet::open(Ethernet::Device dev) + { ++ chunk LKM::includes() ++ { ++ #include ++ } ++ + chunk LKM::prototypes() + { + static int rtx_ethernet_open(struct net_device *); +@@ -123,9 +128,28 @@ + ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(dev); + + ${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; + } + } + } +@@ -165,7 +189,16 @@ + ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(dev); + + ${cast local.rtx_ether_ctx as Ethernet::Device}; +- ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; ++ ++ /* 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; + } +@@ -267,14 +300,11 @@ + */ + 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}, +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 +@@ -40,6 +40,7 @@ + + required sequence open(Ethernet::Device) + { ++ provided chunk LKM::includes(); + provided chunk LKM::prototypes(); + provided chunk LKM::code(); + } +@@ -69,8 +70,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 -r d9af98faac8a -r c4c33ac02b93 rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch --- a/rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch Tue Mar 19 23:16:02 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,959 +0,0 @@ -# HG changeset patch -# Parent 7a2c9e5880145d2d42cd5bc01dbc2b6e96689934 - -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 -@@ -171,13 +171,17 @@ - - static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing} *self, ${Socket::SKBuff} *skb) - { -- ${Socket::AbstractSKBuff} *abs_skb = skb->skbuff; -- ${cast local.abs_skb as Socket::AbstractSKBuff}; -- return skb_is_gso(&${local.abs_skb.data}) || ${local.abs_skb.data}.ip_summed == CHECKSUM_PARTIAL; -+ /* 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}; -+ 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) - { -+ /* 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}; - WARN_ON(!skb); - - /* -@@ -188,17 +192,15 @@ - * code shouldn't be aware of it and use something more - * abstract. - */ -- ${Socket::AbstractSKBuff} *abs_skb = skb->skbuff; -- ${cast local.abs_skb as Socket::AbstractSKBuff}; - ${e1000::TxDescriptor} *tx_desc = &self->base[self->tail]; - tx_desc->lower.data = cpu_to_le32( - E1000_TXD_CMD_EOP | - E1000_TXD_CMD_IFCS | - E1000_TXD_CMD_RS | -- skb_headlen(&${local.abs_skb.data})); -+ skb_headlen(${local.k_skb.k_sk_buff})); - tx_desc->upper.data = 0; - tx_desc->buff_addr = cpu_to_le64(skb->dma_handle); -- memcpy(&self->skbuffs[self->tail], skb, sizeof(*skb)); -+ memcpy(&self->skbuffs[self->tail], ${local.k_skb.k_sk_buff}, sizeof(*${local.k_skb.k_sk_buff})); - self->tail = (self->tail + 1) % ${config.tx_ring_size}; - } - -@@ -249,7 +251,6 @@ - { - int bars; - unsigned char /* __iomem */ *ioaddr; -- int irq; - - ${e1000::RxRing} rx_ring; - ${e1000::TxRing} tx_ring; -@@ -267,14 +268,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 +605,6 @@ - } - } - -- template sequence e1000::setup_interrupt_handler(Ethernet::Device rtx_ether_ctx) -- { -- chunk LKM::includes() -- { -- #include -- } -- -- 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() -@@ -798,7 +735,7 @@ - hw_ctx->rx_ring.size = ${config.rx_ring_size} * sizeof(*hw_ctx->rx_ring.base); - hw_ctx->rx_ring.size = ALIGN(hw_ctx->rx_ring.size, 4096); - hw_ctx->rx_ring.base = dma_alloc_coherent( -- &${rtx_ether_ctx.device}, -+ ${rtx_ether_ctx.device}, - hw_ctx->rx_ring.size, - &hw_ctx->rx_ring.dma_base, - GFP_KERNEL); -@@ -816,12 +753,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.k_net_dev}, /* XXX: .k_net_dev isn't expanded here */ - ${config.rx_buffer_len}); - if (!hw_ctx->rx_ring.skbuffs[i].skbuff) - { -@@ -829,11 +764,11 @@ - goto err_skbuffs_alloc; - } - hw_ctx->rx_ring.skbuffs[i].dma_handle = dma_map_single( -- &${rtx_ether_ctx.device}, -- &hw_ctx->rx_ring.skbuffs[i].skbuff->data, -+ ${rtx_ether_ctx.device}, -+ (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}, -+ int dma_error = dma_mapping_error(${rtx_ether_ctx.device}, - hw_ctx->rx_ring.skbuffs[i].dma_handle); - if (dma_error) - { -@@ -885,7 +820,7 @@ - hw_ctx->tx_ring.size = ${config.tx_ring_size} * sizeof(*hw_ctx->tx_ring.base); - hw_ctx->tx_ring.size = ALIGN(hw_ctx->tx_ring.size, 4096); - hw_ctx->tx_ring.base = dma_alloc_coherent( -- &${rtx_ether_ctx.device}, -+ ${rtx_ether_ctx.device}, - hw_ctx->tx_ring.size, - &hw_ctx->tx_ring.dma_base, - GFP_KERNEL); -@@ -928,15 +863,16 @@ - while (i--) - { - dma_unmap_single( -- &${rtx_ether_ctx.device}, -+ ${rtx_ether_ctx.device}, - hw_ctx->rx_ring.skbuffs[i].dma_handle, - ${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, -+ dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx->rx_ring.size, - hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); - err_rx_ring_alloc: - return -ENOMEM; -@@ -954,8 +890,13 @@ - { - chunk ::CALL() - { -- ${e1000::Context} *hw_ctx; -- hw_ctx = &${rtx_ether_ctx}->hw_ctx; -+ /* -+ * 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}; -+ hw_ctx_ = &${rtx_ether_ctx}->hw_ctx; - - /* - * Free the rx ring: -@@ -965,22 +906,23 @@ - for (int i = 0; i != ${config.rx_ring_size}; ++i) - { - dma_unmap_single( -- &${rtx_ether_ctx.device}, -- (dma_addr_t)hw_ctx->rx_ring.skbuffs[i].dma_handle, -+ ${rtx_ether_ctx.device}, -+ (dma_addr_t)hw_ctx_->rx_ring.skbuffs[i].dma_handle, - ${config.rx_buffer_len}, - DMA_FROM_DEVICE); -- dev_kfree_skb(&hw_ctx->rx_ring.skbuffs[i].skbuff->data); -+ /* XXX Go through the rtx types (Socket::SKBuff, AbstractSKBuff) */ -+ dev_kfree_skb(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); -+ dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->rx_ring.size, -+ hw_ctx_->rx_ring.base, hw_ctx_->rx_ring.dma_base); - ${Log::info("free_rx_tx: rx ring free'ed")}; - - /* - * Free the tx ring: - * - Free the descriptors array. - */ -- dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->tx_ring.size, -- hw_ctx->tx_ring.base, hw_ctx->tx_ring.dma_base); -+ dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->tx_ring.size, -+ hw_ctx_->tx_ring.base, hw_ctx_->tx_ring.dma_base); - ${Log::info("free_rx_tx: tx ring free'ed")}; - } - } -@@ -1038,13 +980,13 @@ - ${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}*)${rtx_ether_ctx.device}; - - ${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 +1019,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 +1039,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 - } - -+ 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 - } - -- 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; -+ * -+ * Also, using ${PCI::AbstractDevice} instead of directly struct -+ * pci_dev doesn't work. -+ */ -+ 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 -+ } -+ - 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,10 +210,24 @@ - { - 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}; -- ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; -+ -+ /* 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 +249,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 +285,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 +316,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 +333,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 +359,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,20 +97,20 @@ - { - ${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; -+ irq: ((struct pci_dev *)(${self})->pdev)->irq; - bars: ${self}->bars; - ioaddr: ${self}->ioaddr; - BAR_0: 0; -@@ -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}); - } - } - -@@ -46,11 +46,12 @@ - */ - ${Socket::AbstractSKBuff} *skb = self->skbuff; - ${cast local.skb as Socket::AbstractSKBuff}; -- ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.data}.protocol) }; -+ ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.k_sk_buff}->protocol) }; -+ - static const char * const ip_summed_values[] = { - "none", "unnecessary", "complete", "partial" - }; -- struct skb_shared_info *shinfo = skb_shinfo(&${local.skb.data}); -+ struct skb_shared_info *shinfo = skb_shinfo(${local.skb.k_sk_buff}); - - pr_info( - "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n" -@@ -59,8 +60,8 @@ - "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u", - /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */ - ethernet_proto.id, ${local.ethernet_proto.str}, -- ${local.skb.data}.ip_summed, ip_summed_values[${local.skb.data}.ip_summed], -- ${local.skb.data}.len, ${local.skb.data}.data_len, skb_headlen(&${local.skb.data}), -+ ${local.skb.k_sk_buff}->ip_summed, ip_summed_values[${local.skb.k_sk_buff}->ip_summed], -+ ${local.skb.k_sk_buff}->len, ${local.skb.k_sk_buff}->data_len, skb_headlen(${local.skb.k_sk_buff}), - shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type - ); - } -@@ -72,14 +73,13 @@ - ${Socket::AbstractSKBuff} *skb = self->skbuff; - ${cast local.skb as Socket::AbstractSKBuff}; - -- WARN_ON(!skb); -- WARN_ON(!${local.skb.data}.data); -+ WARN_ON(!${local.skb.k_sk_buff}); - WARN_ON(self->dma_handle); - - self->dma_handle = dma_map_single( - dev, -- &${local.skb.data}.data, -- skb_headlen(&${local.skb.data}), -+ ${local.skb.k_sk_buff}, -+ skb_headlen(${local.skb.k_sk_buff}), - direction); - int err = dma_mapping_error(dev, self->dma_handle); - if (err) -@@ -97,18 +97,17 @@ - ${Socket::AbstractSKBuff} *skb = self->skbuff; - ${cast local.skb as Socket::AbstractSKBuff}; - -- WARN_ON(!${local.skb}); -- WARN_ON(!${local.skb.data}.data); -+ WARN_ON(!${local.skb.k_sk_buff}); - - if (self->dma_handle) - { - dma_unmap_single(dev, - self->dma_handle, -- skb_headlen(&${local.skb.data}), -+ skb_headlen(${local.skb.k_sk_buff}), - direction); - self->dma_handle = 0; - } -- dev_kfree_skb_any(&${local.skb.data}); -+ dev_kfree_skb_any(${local.skb.k_sk_buff}); - self->skbuff = 0; - } - } -@@ -131,22 +130,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,8 @@ - { - chunk LKM::includes(); - decl data_types(); -- attribute Builtin::symbol data; -+ -+ attribute Builtin::symbol k_sk_buff; - } - - provided type SKBuff diff -r d9af98faac8a -r c4c33ac02b93 series --- a/series Tue Mar 19 23:16:02 2013 -0700 +++ b/series Fri Mar 22 00:06:00 2013 -0700 @@ -1,2 +1,3 @@ maintainers_fix_indentation_in_use_rathaxes.patch -rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch +rathaxes_e1000_move_the_interrupt_init_and_cleanup_into_ethernet.patch +rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch