Mercurial > archived > louis > epitech > mq > rathaxes
view rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch @ 103:d9af98faac8a
Wip on abstract type nightmare
author | Louis Opter <louis@lse.epita.fr> |
---|---|
date | Tue, 19 Mar 2013 23:16:02 -0700 |
parents | 8e8aa342078b |
children |
line wrap: on
line source
# 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 <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() @@ -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 <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; + * + * 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 <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,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