# HG changeset patch # User Louis Opter # Date 1363760162 25200 # Node ID d9af98faac8a2e20e574d6f3a4d7dc4983f5d71e # Parent 8e8aa342078bac76dde3260c0f37a3d38e6baaf5 Wip on abstract type nightmare diff -r 8e8aa342078b -r d9af98faac8a rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch --- a/rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch Thu Feb 28 23:30:59 2013 -0800 +++ b/rathaxes_trying_to_fix_the_abstract_type_nightmare_in_e1000.patch Tue Mar 19 23:16:02 2013 -0700 @@ -1,5 +1,6 @@ # HG changeset patch -# Parent 21cb4b0b59ebfc3350ded6f9cea2b44203437ab2 +# 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 @@ -26,7 +27,48 @@ 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 @@ +@@ -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; @@ -34,7 +76,7 @@ ${e1000::RxRing} rx_ring; ${e1000::TxRing} tx_ring; -@@ -267,14 +266,12 @@ +@@ -267,14 +268,12 @@ chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, Builtin::number bars, @@ -50,7 +92,7 @@ } } -@@ -606,68 +603,6 @@ +@@ -606,68 +605,6 @@ } } @@ -119,7 +161,16 @@ template sequence activate_device_interruption(Ethernet::Device rtx_ether_ctx) { chunk ::CALL() -@@ -816,12 +751,10 @@ +@@ -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. */ @@ -130,20 +181,41 @@ - 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}, ++ ${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) { -@@ -830,7 +763,7 @@ +@@ -829,11 +764,11 @@ + goto err_skbuffs_alloc; } hw_ctx->rx_ring.skbuffs[i].dma_handle = dma_map_single( - &${rtx_ether_ctx.device}, +- &${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}, -@@ -933,7 +866,8 @@ +- 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: @@ -152,8 +224,64 @@ + dev_kfree_skb((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff); } - dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->rx_ring.size, -@@ -1042,9 +976,9 @@ +- 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:")}; /* @@ -166,7 +294,7 @@ */ /* * XXX: doesn't work (I tried to pass self explicitely too): -@@ -1077,8 +1011,8 @@ +@@ -1077,8 +1019,8 @@ /* 2. Map the data */ @@ -177,12 +305,12 @@ { ${Log::info("xmit: can't DMA map a SKbuff")}; goto err_skb_map_to; -@@ -1097,7 +1031,7 @@ +@@ -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); ++ rtx_socket_skbuff_unmap_and_free(&skb, ${devp.k_device}, DMA_TO_DEVICE); return NETDEV_TX_OK; } } @@ -282,10 +410,10 @@ + * XXX: I'd like to be able to do things like: + * device: ${self.pci_dev.k_pci_dev}->dev; + * -+ * Btw, should this be ${PCI::AbstractDevice} instead of directly -+ * struct pci_dev? ++ * Also, using ${PCI::AbstractDevice} instead of directly struct ++ * pci_dev doesn't work. + */ -+ device: ((struct pci_dev *)(${self})->pci_dev)->dev; ++ device: (&((struct pci_dev *)(${self})->pci_dev)->dev); pci_device: ${self}->pci_dev; net_device: ${self}->net_dev; - perm_addr: ${self}->net_dev->ndev.perm_addr; @@ -348,7 +476,7 @@ } } } -@@ -162,11 +210,23 @@ +@@ -162,10 +210,24 @@ { static int rtx_ethernet_close(struct net_device *dev) { @@ -361,19 +489,21 @@ + ${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)}; - ++ { ++ ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; ++ } ++ + free_irq(${local.rtx_ether_ctx.irq}, ${local.rtx_net_dev.k_net_dev}); + { + ${Log::info("interrupt handler free'ed")}; + } -+ + return 0; } - } -@@ -187,9 +247,13 @@ +@@ -187,9 +249,13 @@ { static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) { @@ -388,7 +518,7 @@ ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; return IRQ_NONE; -@@ -219,23 +283,26 @@ +@@ -219,23 +285,26 @@ */ chunk PCI::pci_probe_hook(PCI::Device rtx_pci_dev) { @@ -424,7 +554,7 @@ if (error) { ${Log::info("cannot register the driver in the net subsystem")}; -@@ -247,14 +314,11 @@ +@@ -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. @@ -443,7 +573,7 @@ } /* Register ourselves in the parent context: */ -@@ -267,19 +331,16 @@ +@@ -267,19 +333,16 @@ */ int bars = ${rtx_pci_dev.bars}; unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr}; @@ -465,7 +595,7 @@ } /* This chunk should be removed (see #26) */ -@@ -296,15 +357,15 @@ +@@ -296,15 +359,15 @@ */ chunk PCI::pci_remove_hook(PCI::Device rtx_pci_dev) { @@ -622,7 +752,7 @@ ${self}->ioaddr = NULL; ${self}->context = NULL; } -@@ -97,18 +97,18 @@ +@@ -97,20 +97,20 @@ { ${PCI::AbstractDevice} *select_ioaddr_pdev = ${self}->pdev; ${cast local.select_ioaddr_pdev as PCI::AbstractDevice}; @@ -641,10 +771,13 @@ - context: ${self}->context; - device: &${self}->pdev->data.dev; + rtx_drv_context: ${self}->context; -+ device: &((struct pci_dev *)(${self})->pdev->dev); ++ device: &((struct pci_dev *)(${self})->pdev)->dev; pci_device: ${self}->pdev; - irq: ${self}->pdev->data.irq; +- 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)}; } @@ -718,7 +851,73 @@ } } -@@ -131,22 +131,22 @@ +@@ -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) { @@ -748,11 +947,12 @@ diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti --- a/rathaxes/samples/e1000/socket.rti +++ b/rathaxes/samples/e1000/socket.rti -@@ -5,7 +5,7 @@ +@@ -5,7 +5,8 @@ { chunk LKM::includes(); decl data_types(); - attribute Builtin::symbol data; ++ + attribute Builtin::symbol k_sk_buff; }