# HG changeset patch # User Louis Opter # Date 1348470795 -7200 # Node ID e9736ab709953cc2694a0ee0860cd2a19a29aa9c # Parent c99e69966dd3a75751b605db564a4c653cb47f14 Add a couple of patches to the build system and WIP on the e1000 code architecture to implement the tranmission diff -r c99e69966dd3 -r e9736ab70995 e1000_implement_the_frame_transmission_chunk.patch --- a/e1000_implement_the_frame_transmission_chunk.patch Tue Sep 18 08:57:14 2012 +0200 +++ b/e1000_implement_the_frame_transmission_chunk.patch Mon Sep 24 09:13:15 2012 +0200 @@ -1,22 +1,166 @@ # HG changeset patch -# Parent 42d6e2a573d077772c1a9c697cc066337569b129 +# Parent 87ba2a19a59fb7be346ad40a57439b6b752b152e rathaxes: start to queue up packets in the TX ring on the e1000 sample -diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in ---- a/maintainers/CMakeScripts/Templates/MakefileLKM.in -+++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in -@@ -1,6 +1,6 @@ - # Disable this "coding-style" warning (seriously, you have to compile with - # -pedantic to get it...) --EXTRA_CFLAGS = -Wno-declaration-after-statement -+EXTRA_CFLAGS = -Wno-declaration-after-statement -std=gnu99 +diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt +--- a/rathaxes/samples/e1000/CMakeLists.txt ++++ b/rathaxes/samples/e1000/CMakeLists.txt +@@ -1,6 +1,22 @@ +-ADD_RATHAXES_SOURCES(e1000_src lkm.rtx +- RTI builtin.rti log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti +- BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt) ++ADD_RATHAXES_SOURCES(e1000_src ++ lkm.rtx ++ RTI ++ builtin.rti ++ log.rti ++ lkm.rti ++ device.rti ++ pci.rti ++ socket.rti ++ ethernet.rti ++ e1000.rti ++ BLT ++ log.blt ++ lkm.blt ++ pci.blt ++ device.blt ++ socket.blt ++ ethernet.blt ++ e1000.blt) - KDIR = /lib/modules/$(shell uname -r)/build - obj-m := @LKM_OBJECTS@ + IF (LINUX_KBUILD_DIR) + ADD_RATHAXES_LKM(e1000 e1000_src) +diff --git a/rathaxes/samples/e1000/device.blt b/rathaxes/samples/e1000/device.blt +new file mode 100644 +--- /dev/null ++++ b/rathaxes/samples/e1000/device.blt +@@ -0,0 +1,25 @@ ++with Device, LKM ++{ ++ template type Device::Device() ++ { ++ chunk LKM::includes() ++ { ++ #include ++ ++ static const ${Device::Device} force_rtx_device_decl; ++ } ++ ++ chunk decl() ++ { ++ typedef struct device *rtx_device_p; ++ } ++ ++ chunk init() ++ { ++ } ++ ++ map ++ { ++ } ++ } ++} +diff --git a/rathaxes/samples/e1000/device.rti b/rathaxes/samples/e1000/device.rti +new file mode 100644 +--- /dev/null ++++ b/rathaxes/samples/e1000/device.rti +@@ -0,0 +1,9 @@ ++interface Device : LKM ++{ ++ provided type Device ++ { ++ chunk LKM::includes(); ++ method decl(); ++ method init(); ++ } ++} 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 -@@ -332,6 +332,30 @@ +@@ -110,9 +110,9 @@ + { + unsigned int size; + struct rtx_e1000_rx_descriptor *base; +- void* /* dma_addr_t */ dma_base; ++ dma_addr_t dma_base; + struct sk_buff *skbuffs[256 /* ${config.rx_ring_size} */]; +- void* /* dma_addr_t */ dma_skbuffs[256 /* ${config.rx_ring_size} */]; ++ dma_addr_t dma_skbuffs[256 /* ${config.rx_ring_size} */]; + }; + } + +@@ -148,11 +148,59 @@ + struct rtx_e1000_tx_ring + { + unsigned int size; ++ /* We should probably use ${e1000::TxDescriptor} here: */ + struct rtx_e1000_tx_descriptor *base; +- void* /* dma_addr_t */ dma_base; ++ dma_addr_t dma_base; ++ /* indexes on base */ ++ unsigned int head; ++ unsigned int tail; + }; + } + ++ chunk LKM::prototypes() ++ { ++ static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *); ++ static int rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *); ++ static int rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *, struct rtx_socket_skbuff *); ++ } ++ ++ chunk LKM::code() ++ { ++ static unsigned int rtx_e1000_tx_ring_descriptors_remaining(struct rtx_e1000_tx_ring *self) ++ { ++ if (self->tail == self->head) /* ring is empty */ ++ return 256; /* XXX: ${config.tx_ring_size}; */ ++ if (self->tail > self->head) ++ /* XXX: ${config.tx_ring_size} */ ++ return 256 - (self->tail - self->head); ++ return self->head - self->tail; ++ } ++ ++ static int rtx_e1000_tx_ring_tso_cksum_offload(struct rtx_e1000_tx_ring *self, struct rtx_socket_skbuff *skb) ++ { ++ return skb_is_gso(skb->skbuff) || skb->skbuff->ip_summed == CHECKSUM_PARTIAL; ++ } ++ ++ static int rtx_e1000_tx_ring_put(struct rtx_e1000_tx_ring *self, struct rtx_socket_skbuff *skb) ++ { ++ return NETDEV_TX_OK; ++ } ++ } ++ ++ chunk descriptors_remaining() ++ { ++ rtx_e1000_tx_ring_descriptors_remaining(${self}); ++ } ++ ++ chunk tso_cksum_offload(Socket::SKBuff skb) ++ { ++ } ++ ++ chunk put(Socket::SKBuff skb) ++ { ++ rtx_e1000_tx_ring_put(${self}, &${skb}); ++ } ++ + chunk ::init() + { + } +@@ -183,7 +231,7 @@ + struct rtx_e1000_ctx + { + int bars; +- unsigned char /* __iomem */ *ioaddr; ++ unsigned char __iomem *ioaddr; + int irq; + + /* we can't use the Rathaxes type here (#8) */ +@@ -334,6 +382,30 @@ } } @@ -47,7 +191,63 @@ template sequence e1000::create_device() { chunk Ethernet::create_device(PCI::Device pdev, Ethernet::Device rtx_ether_ctx) -@@ -964,4 +988,86 @@ +@@ -358,8 +430,8 @@ + ${Log::info("e1000::create: pci_enable_device_mem failed")}; + if (pci_request_selected_regions(${pdev}, ${rtx_ether_ctx}->hw_ctx.bars, ${config.name})) + ${Log::info("e1000::create: pci_request_selected_regions failed")}; +- if (${config.set_master}) +- pci_set_master(${pdev}); ++// XXX if (${config.set_master}) ++// XXX pci_set_master(${pdev}); + + /* 0 here is for BAR_0: */ + ${rtx_ether_ctx}->hw_ctx.ioaddr = pci_ioremap_bar(${pdev}, 0); +@@ -630,8 +702,6 @@ + { + chunk ::CALL() + { +- typedef unsigned long int dma_addr_t; +- + /* + * This part is documented in the Intel Gigabit Ethernet Controller + * Software Developper manual. (You can find it in the doc/hardware +@@ -733,7 +803,7 @@ + hw_ctx->rx_ring.base = dma_alloc_coherent( + &${ctx}->pci_dev->dev, + hw_ctx->rx_ring.size, +- (dma_addr_t *)&hw_ctx->rx_ring.dma_base, ++ &hw_ctx->rx_ring.dma_base, + GFP_KERNEL); + if (!hw_ctx->rx_ring.base) + { +@@ -758,7 +828,7 @@ + ${Log::info("cannot allocate a skbuff for the rx ring")}; + goto err_skbuffs_alloc; + } +- hw_ctx->rx_ring.dma_skbuffs[i] = (void *)dma_map_single( ++ hw_ctx->rx_ring.dma_skbuffs[i] = dma_map_single( + &${ctx}->pci_dev->dev, + hw_ctx->rx_ring.skbuffs[i]->data, + ${config.rx_buffer_len}, +@@ -820,7 +890,7 @@ + hw_ctx->tx_ring.base = dma_alloc_coherent( + &${ctx}->pci_dev->dev, + hw_ctx->tx_ring.size, +- (dma_addr_t *)&hw_ctx->tx_ring.dma_base, ++ &hw_ctx->tx_ring.dma_base, + GFP_KERNEL); + if (!hw_ctx->rx_ring.base) + { +@@ -838,6 +908,8 @@ + /* 3. Setup TDH/TDT to zero: the queue is empty */ + rtx_e1000_register_write32(hw_ctx, E1000_TDH, 0); + rtx_e1000_register_write32(hw_ctx, E1000_TDT, 0); ++ hw_ctx->tx_ring.head = 0; ++ hw_ctx->tx_ring.tail = 0; + + /* 4. Set TCTL.PSP and enable the transmitter */ + rtx_e1000_register_set32(hw_ctx, E1000_TCTL, E1000_TCTL_PSP|E1000_TCTL_PSP); +@@ -930,4 +1002,81 @@ } } } @@ -56,53 +256,43 @@ + { + chunk ::CALL() + { -+ if (skb_is_gso(${skb}) || ${skb}->ip_summed == CHECKSUM_PARTIAL) -+ { -+ ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")}; -+ return NETDEV_TX_OK; -+ } + } + } + -+ template sequence e1000::_xmit_map_skbuff(Ethernet::Device ctx, Socket::SKBuff skb) ++ template sequence e1000::xmit(Ethernet::Device ctx, Socket::KernelSKBuff kernel_skb) + { + chunk ::CALL() + { -+ dma_addr_t buff_addr = dma_map_single( -+ &${ctx}->pci_dev->dev, -+ ${skb}->data, -+ skb_headlen(${skb}), -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(&${ctx}->pci_dev->dev, buff_addr)) -+ { -+ ${Log::info("xmit: can't DMA map a SKBuff")}; -+ goto err_dma_map; -+ } -+ } -+ } -+ -+ template sequence e1000::_xmit_update_tx_ring(Ethernet::Device, Socket::SKBuff skb) -+ { -+ chunk ::CALL() -+ { -+ } -+ } -+ -+ template sequence e1000::xmit(Ethernet::Device ctx, Socket::SKBuff skb) -+ { -+ chunk ::CALL() -+ { -+ typedef unsigned long int dma_addr_t; -+ -+ (void)1; // Issue 10 + /* + * Put packets on the TX ring, must return NETDEV_TX_OK or + * NETDEV_TX_BUSY. + */ -+ { -+ ${Log::info("xmit: skbuff details:")}; -+ ${skb.dump_infos()}; -+ } ++ ++ /* ++ * XXX: This leaves a placeholder if I cast local.tx_ring as ++ * e1000::TxRing below. ++ */ ++ ${Socket::SKBuff} skb; ++ ${local.skb.init(kernel_skb)}; ++ ++ /* ++ * XXX: can't write ${e1000::TxRing} * (the placeholder isn't ++ * resolved). ++ */ ++ struct rtx_e1000_tx_ring *tx_ring = &${ctx}->hw_ctx.tx_ring; ++ //${cast local.tx_ring as e1000::TxRing}; ++ ++ ${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. ++ */ ++ /* ++ * XXX: doesn't work (I tried to pass self explicitely too): ++ * ${local.skb.dump_infos()}; ++ */ ++ rtx_socket_skbuff_dump_infos(&skb); + + /* + * The transmission is going to be several steps: @@ -114,22 +304,27 @@ + * 3. Signal the hardware that data is available via a tx desc. + */ + ++ /* XXX: same thing wanted to use: ${local.tx_ring.descriptors_remaining()} */ ++ if (!rtx_e1000_tx_ring_descriptors_remaining(tx_ring)) ++ return NETDEV_TX_BUSY; ++ + /* 1. Offloading */ -+ { // workaround #10 (and it's useful to workaround #47 too) -+ ${e1000::_xmit_tso_cksum_offload(ctx, skb)}; ++ /* XXX: ${local.tx_ring.tso_cksum_offload(skb)}; */ ++ if (rtx_e1000_tx_ring_tso_cksum_offload(tx_ring, &skb)) ++ { ++ ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")}; ++ return NETDEV_TX_OK; + } + + /* 2. Map the data */ -+ { -+ ${e1000::_xmit_map_skbuff(ctx, skb)}; -+ } ++ ${Device::Device} dev = &${ctx}->pci_dev->dev; ++ /* XXX: ${local.skb.dma_map(local.dev)}; */ ++ rtx_socket_dma_map(&skb, dev); + + /* 3. Update the TX Ring */ -+ { -+ ${e1000::_xmit_update_tx_ring(ctx, skb)}; -+ } ++ /* XXX: ${local.tx_ring.put(skb)}; */ ++ rtx_e1000_tx_ring_put(tx_ring, &skb); + -+ err_dma_map: + return NETDEV_TX_OK; + } + } @@ -137,7 +332,22 @@ 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 -@@ -51,6 +51,12 @@ +@@ -31,8 +31,14 @@ + provided type TxRing + { + chunk LKM::includes(); ++ chunk LKM::prototypes(); ++ chunk LKM::code(); + method decl(); + method init(); ++ ++ method descriptors_remaining(); ++ method tso_cksum_offload(Socket::SKBuff); ++ method put(Socket::SKBuff); + } + + /* +@@ -51,6 +57,12 @@ method decl(); } @@ -150,7 +360,7 @@ provided sequence create_device() { provided chunk Ethernet::create_device(PCI::Device, Ethernet::Device); -@@ -109,6 +115,26 @@ +@@ -109,6 +121,16 @@ provided chunk ::CALL(); } @@ -159,17 +369,7 @@ + provided chunk ::CALL(); + } + -+ provided sequence _xmit_map_skbuff(Ethernet::Device, Socket::SKBuff) -+ { -+ provided chunk ::CALL(); -+ } -+ -+ provided sequence _xmit_update_tx_ring(Ethernet::Device, Socket::SKBuff) -+ { -+ provided chunk ::CALL(); -+ } -+ -+ provided sequence xmit(Ethernet::Device, Socket::SKBuff) ++ provided sequence xmit(Ethernet::Device, Socket::KernelSKBuff) + { + provided chunk ::CALL(); + } @@ -180,7 +380,7 @@ 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,6 +1,51 @@ +@@ -1,6 +1,56 @@ with Ethernet, PCI, LKM, Log { - template type Ethernet::Net() @@ -219,6 +419,11 @@ + } + } + ++ chunk decl() ++ { ++ typedef unsigned short rtx_ether_protocol_id; ++ } ++ + chunk to_str() + { + rtx_ethernet_protocol_id_to_str(${self}); @@ -233,7 +438,7 @@ { chunk LKM::includes() { -@@ -17,11 +62,6 @@ +@@ -17,11 +67,6 @@ } } @@ -245,7 +450,19 @@ template type Ethernet::Device() { chunk LKM::includes() -@@ -52,7 +92,7 @@ +@@ -47,15 +92,15 @@ + struct pci_dev *pci_dev; + struct net_device *net_dev; + +- /* while waiting on issue #8 */ +- //${e1000::Context} hw_ctx; +- // In the long-term, this may disappear for a new concept allowing +- // to embbed a descriptor defined and manipulated by the front-end ++ /* ++ * In the long-term, this may disappear for a new concept allowing ++ * to embbed a descriptor defined and manipulated by the front-end ++ */ + ${pointcut Ethernet::SubContext()}; } *rtx_ethernet_dev_p; } @@ -254,45 +471,89 @@ { ${self} = netdev_priv(${net_dev}); /* -@@ -100,11 +140,11 @@ +@@ -82,9 +127,8 @@ { - static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev) + static int rtx_ethernet_open(struct net_device *dev) + { +- struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev); ++ ${Ethernet::Device} rtx_ether_dev = netdev_priv(dev); + +- ${cast local.rtx_ether_dev as Ethernet::Device}; + ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; + + return 0; +@@ -92,7 +136,7 @@ + } + } + +- template sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) ++ template sequence Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb) + { + chunk LKM::prototypes() + { +@@ -101,13 +145,11 @@ + + chunk LKM::code() + { +- static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev) ++ static int rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev) { - ${cast local.dev as Ethernet::Device}; -+ struct rtx_ethernet_dev* rtx_ethernet_dev = netdev_priv(dev); -+ -+ ${cast local.rtx_ethernet_dev as Ethernet::Device}; - ${cast local.skb as Socket::SKBuff}; +- ${cast local.skb as Socket::SKBuff}; - ${pointcut ::IMPLEMENTATION(local.dev, local.skb)}; - - return 0; -+ ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.skb)}; ++ ${Ethernet::Device} rtx_ethernet_dev = netdev_priv(net_dev); ++ ${cast local.kernel_skb as Socket::KernelSKBuff}; ++ ${pointcut ::IMPLEMENTATION(local.rtx_ethernet_dev, local.kernel_skb)}; } } } +@@ -123,9 +165,8 @@ + { + static int rtx_ethernet_close(struct net_device *dev) + { +- struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev); ++ ${Ethernet::Device} rtx_ether_dev = netdev_priv(dev); + +- ${cast local.rtx_ether_dev as Ethernet::Device}; + ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; + + return 0; +@@ -148,11 +189,8 @@ + { + static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) + { +- struct rtx_ethernet_dev* rtx_ether_dev; +- struct rtx_e1000_ctx* ctx; ++ ${Ethernet::Device} rtx_ether_dev = dev_id; + +- rtx_ether_dev = dev_id; +- ${cast local.rtx_ether_dev as Ethernet::Device}; + ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; + + return IRQ_NONE; 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 -@@ -1,16 +1,33 @@ +@@ -1,16 +1,30 @@ interface Ethernet : Socket, PCI, LKM { - provided type Net -+ provided type ProtocolId -+ { -+ chunk LKM::prototypes(); -+ chunk LKM::data(); -+ chunk LKM::code(); -+ method ::to_str(); -+ } ++ provided type ProtocolId ++ { ++ chunk LKM::prototypes(); ++ chunk LKM::data(); ++ chunk LKM::code(); ++ method decl(); ++ method to_str(); ++ } + -+ /* -+ * This is the abstract type used by the Kernel to represent an ethernet -+ * device. -+ */ + provided type AbstractDevice { chunk LKM::includes(); - method decl(); +- method decl(); ++ method decl(); } + /* @@ -306,14 +567,33 @@ method decl(); - method init(Ethernet::Net, PCI::Device); + method init(Ethernet::AbstractDevice, PCI::Device); + pointcut Ethernet::SubContext(); } - required variable ::string ifname; +@@ -22,7 +36,7 @@ + provided chunk LKM::code(); + } + +- required sequence send(Ethernet::Device dev, Socket::SKBuff skb) ++ required sequence send(Ethernet::Device, Socket::KernelSKBuff) + { + provided chunk LKM::prototypes(); + provided chunk LKM::code(); 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 -@@ -46,6 +46,7 @@ - Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) +@@ -1,4 +1,4 @@ +-device LKM use LKM, PCI, Ethernet, Log ++device LKM use LKM, PCI, Ethernet, Log, Socket + { + Ethernet::open(Ethernet::Device dev) + { +@@ -43,9 +43,10 @@ + e1000::handle_interrupt(dev); + } + +- Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) ++ Ethernet::send(Ethernet::Device dev, Socket::KernelSKBuff skb) { Log::info("we have one packet to transmit!"); + e1000::xmit(dev, skb); @@ -334,69 +614,141 @@ 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 -@@ -1,4 +1,4 @@ +@@ -1,20 +1,104 @@ -with Socket, LKM -+with Socket, LKM, Ethernet ++with Socket, LKM, Device, Ethernet { ++ template type Socket::KernelSKBuff() ++ { ++ chunk LKM::includes() ++ { ++ #include ++ ++ static const ${Socket::KernelSKBuff} force_rtx_socket_kernel_skbuff_decl; ++ } ++ ++ chunk ::decl() ++ { ++ typedef struct sk_buff *rtx_socket_kernel_skbuff_p; ++ } ++ ++ map ++ { ++ } ++ } ++ template type Socket::SKBuff() { -@@ -10,13 +10,41 @@ + chunk LKM::includes() + { +- #include +- static const ${Socket::SKBuff} force_rtx_lnux_skbuf_decl; ++ static const ${Socket::SKBuff} force_rtx_socket_skbuff_decl; + } chunk ::decl() { - struct sk_buff; -+ typedef struct sk_buff *rtx_socket_skbuff_p; - } - - chunk ::init() - { ++ struct rtx_socket_skbuff ++ { ++ struct sk_buff *skbuff; ++ dma_addr_t dma_handle; ++ }; } -+ chunk ::dump_infos() -+ { -+ /* -+ * We should use a Rathaxes log abstraction instead of pr_info here, -+ * but Rathaxes doesn't support functions with a variable number of -+ * arguments yet. -+ */ -+ unsigned short ethernet_proto = be16_to_cpu(${self}->protocol); -+ ${cast local.ethernet_proto as Ethernet::ProtocolId}; -+ -+ static const char * const ip_summed_values[] = { -+ "none", "unnecessary", "complete", "partial" -+ }; -+ -+ pr_info( -+ "\t protocol = %#-5x (%s)\n" -+ "\t len = %-5u data_len = %-5u head_len = %-5u\n" -+ "\t nr_frags = %u\n" -+ "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n" -+ "\tip_summed = %d (%s)", -+ ethernet_proto, "", // XXX: ${local.ethernet_proto.to_str()}, -+ ${self}->len, ${self}->data_len, skb_headlen(${self}), -+ skb_shinfo(${self})->nr_frags, -+ skb_shinfo(${self})->gso_size, skb_shinfo(${self})->gso_segs, skb_shinfo(${self})->gso_type, -+ ${self}->ip_summed, ip_summed_values[${self}->ip_summed] -+ ); +- chunk ::init() ++ chunk LKM::prototypes() + { ++ static void rtx_socket_skbuff_dump_infos(struct rtx_socket_skbuff *); ++ static int rtx_socket_dma_map(struct rtx_socket_skbuff *, struct device *); + } + ++ chunk LKM::code() ++ { ++ static void rtx_socket_skbuff_dump_infos(struct rtx_socket_skbuff *self) ++ { ++ /* ++ * We should use a Rathaxes log abstraction instead of pr_info here, ++ * but Rathaxes doesn't support functions with a variable number of ++ * arguments yet. ++ */ ++ ${Ethernet::ProtocolId} ethernet_proto = be16_to_cpu(self->skbuff->protocol); ++ static const char * const ip_summed_values[] = { ++ "none", "unnecessary", "complete", "partial" ++ }; ++ struct skb_shared_info *shinfo = skb_shinfo(self->skbuff); ++ ++ pr_info( ++ "\t protocol = %#-5x (%s)\n" ++ "\t len = %-5u data_len = %-5u head_len = %-5u\n" ++ "\t nr_frags = %u\n" ++ "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u\n" ++ "\tip_summed = %d (%s)", ++ ethernet_proto, rtx_ethernet_protocol_id_to_str(ethernet_proto) /* XXX: ${local.ethernet_proto.to_str()} */, ++ self->skbuff->len, self->skbuff->data_len, skb_headlen(self->skbuff), ++ shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type, ++ self->skbuff->ip_summed, ip_summed_values[self->skbuff->ip_summed] ++ ); ++ } ++ ++ static int rtx_socket_dma_map(struct rtx_socket_skbuff *self, struct device *dev) ++ { ++ self->dma_handle = dma_map_single( ++ dev, ++ self->skbuff->data, ++ skb_headlen(self->skbuff), ++ DMA_TO_DEVICE); ++ return dma_mapping_error(dev, self->dma_handle); ++ } ++ } ++ ++ /* ++ * XXX: the rathaxes argument kernel_skb is not actually bound to the ++ * correct C variable from Ethernet::send() (so I named it as the C ++ * variable I needed) ++ */ ++ chunk ::init(Socket::KernelSKBuff kernel_skb) ++ { ++ ${self}.skbuff = kernel_skb; ++ ${self}.dma_handle = 0; ++ } ++ ++ chunk dump_infos() ++ { ++ rtx_socket_skbuff_dump_infos(${self}); ++ } ++ ++ chunk dma_map(Device::Device dev) ++ { ++ rtx_socket_dma_map(${self}, ${dev}); + } + map - { - // some work may have to be done here in order 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 -@@ -1,8 +1,10 @@ - interface Socket : LKM +@@ -1,8 +1,19 @@ +-interface Socket : LKM ++interface Socket : LKM, Device { - provided type Socket::SKBuff { -+ provided type Socket::SKBuff -+ { - chunk LKM::includes(); +- chunk LKM::includes(); - method decl(); - method init(); -+ chunk ::decl(); -+ method ::init(); -+ method ::dump_infos(); ++ provided type KernelSKBuff ++ { ++ chunk LKM::includes(); ++ method decl(); ++ } ++ ++ provided type SKBuff ++ { ++ chunk LKM::includes(); ++ chunk LKM::prototypes(); ++ chunk LKM::code(); ++ method decl(); ++ method init(Socket::KernelSKBuff); ++ method dump_infos(); ++ method dma_map(Device::Device); } } diff -r c99e69966dd3 -r e9736ab70995 maintainers_build_lkm_in_gnu99.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/maintainers_build_lkm_in_gnu99.patch Mon Sep 24 09:13:15 2012 +0200 @@ -0,0 +1,15 @@ +# HG changeset patch +# Parent c53df313fbe2c5f971327b697cfcf506941b9b80 +maintainers: use the gnu99 "standard" to build Linux kernel modules + +diff --git a/maintainers/CMakeScripts/Templates/MakefileLKM.in b/maintainers/CMakeScripts/Templates/MakefileLKM.in +--- a/maintainers/CMakeScripts/Templates/MakefileLKM.in ++++ b/maintainers/CMakeScripts/Templates/MakefileLKM.in +@@ -1,6 +1,6 @@ + # Disable this "coding-style" warning (seriously, you have to compile with + # -pedantic to get it...) +-EXTRA_CFLAGS = -Wno-declaration-after-statement ++EXTRA_CFLAGS = -Wno-declaration-after-statement -std=gnu99 + + KDIR = /lib/modules/$(shell uname -r)/build + obj-m := @LKM_OBJECTS@ diff -r c99e69966dd3 -r e9736ab70995 maintainers_remove_tarte_workaround.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/maintainers_remove_tarte_workaround.patch Mon Sep 24 09:13:15 2012 +0200 @@ -0,0 +1,16 @@ +# HG changeset patch +# Parent 05a7e20d2dc9dbce3f3877da1db7c743448c000e +maintainers: remove the workaround used to generate source without CNorm unstrict + +diff --git a/maintainers/CMakeScripts/UseRathaxes.cmake b/maintainers/CMakeScripts/UseRathaxes.cmake +--- a/maintainers/CMakeScripts/UseRathaxes.cmake ++++ b/maintainers/CMakeScripts/UseRathaxes.cmake +@@ -185,8 +185,6 @@ + + SET(KERNEL_OBJECT_NAME "${RATHAXES_SOURCE}_${SYSTEM}.ko") + ADD_CUSTOM_COMMAND(OUTPUT "${KERNEL_OBJECT_NAME}" +- # … +- COMMAND "sed" "-i" "/TARTE/ d" "${RATHAXES_SOURCE}_${SYSTEM}.c" + # The linux Makefile to build kernel module is quite + # picky about file location and its own name. Let's + # copy our source side by side with the Makefile: diff -r c99e69966dd3 -r e9736ab70995 series --- a/series Tue Sep 18 08:57:14 2012 +0200 +++ b/series Mon Sep 24 09:13:15 2012 +0200 @@ -1,1 +1,3 @@ +maintainers_build_lkm_in_gnu99.patch +maintainers_remove_tarte_workaround.patch e1000_implement_the_frame_transmission_chunk.patch