# HG changeset patch # User Louis Opter # Date 1325983520 -3600 # Node ID 9433dec37a52a0132f1fe24fb529dd3cf41a3443 # Parent 791c7fa1f05586159b1bc244f979e10d89d2f05b Commit diff -r 791c7fa1f055 -r 9433dec37a52 rathaxes_add_lkm_ethernet_sample.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rathaxes_add_lkm_ethernet_sample.patch Sun Jan 08 01:45:20 2012 +0100 @@ -0,0 +1,218 @@ +# HG changeset patch +# Parent a109185dcd773ae92b98a8195b7cc91f1c1cee47 +rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver + +diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt +--- a/rathaxes/samples/lkm/e1000.blt ++++ b/rathaxes/samples/lkm/e1000.blt +@@ -5,7 +5,7 @@ + chunk LKM::includes() + { + /* +- * Force the generation of the structure in the "headers part, we ++ * Force the generation of the structure in the "headers" part, we + * have to do this since we do not use the structure in this blt + * (we hacked a bit and used it in ethernet.blt directly). + */ +@@ -64,8 +64,10 @@ + { + chunk Ethernet::destroy_device + { +- // XXX: add a check in order to avoid freeing none allocated +- // resources. ++ /* ++ * Here, we should have some checks to avoid to free resources that ++ * haven't been allocated. (e.g: in case of previous errors). ++ */ + struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev); + iounmap(rtx_ether_ctx->hw_ctx.ioaddr); + pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars); +diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti +--- a/rathaxes/samples/lkm/e1000.rti ++++ b/rathaxes/samples/lkm/e1000.rti +@@ -2,7 +2,14 @@ + { + provided type e1000::Context; + +- /* Not sure if we need the argument */ ++ /* ++ * This sequence should receive an argument like Ethernet::Device, but it is ++ * unclear about how this argument should be bound to a variable/argument in ++ * the instrumented C code. ++ * ++ * Here again, we rely on the fact that *we* wrote the parent context and ++ * named the C variables we need/use with the same name everywhere. ++ */ + provided sequence e1000::create_device() + { + provided chunk Ethernet::create_device; +diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt +--- a/rathaxes/samples/lkm/ethernet.blt ++++ b/rathaxes/samples/lkm/ethernet.blt +@@ -6,8 +6,6 @@ + { + #include + #include +- +- typedef int include_linux_net_system_stamp; + } + + chunk ::decl() +@@ -93,10 +91,9 @@ + template sequence Ethernet::interrupt_handler(Ethernet::Device dev) + { + /* +- * Why we can't use irqreturn_t here? (we are forced to use enum +- * irqreturn, which is the real type). ++ * We can't use the irqreturn_t type here because CNornm doesn't know ++ * it. + */ +- + chunk LKM::prototypes() + { + static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); +@@ -141,7 +138,12 @@ + if (net_dev == 0) + { + ${Log::info("Cannot allocate memory")}; +- // is it the thing to do? ++ /* ++ * Again, the error should be "raised" in the parent context. ++ * ++ * Here we know that we should return ENOMEM because *we* wrote ++ * the parent context. ++ */ + return -ENOMEM; + } + strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name)); +@@ -166,13 +168,13 @@ + if ((error = register_netdev(net_dev))) + { + ${Log::info("Cannot register the driver")}; +- // is it the thing to do? + return error; + } + + /* same problem as above with ${pdev} */ + //pci_set_drvdata(${pdev}, net_dev); + pci_set_drvdata(pdev, net_dev); ++ + ${pointcut Ethernet::create_device}; + } + +diff --git a/rathaxes/samples/lkm/ethernet.rti b/rathaxes/samples/lkm/ethernet.rti +--- a/rathaxes/samples/lkm/ethernet.rti ++++ b/rathaxes/samples/lkm/ethernet.rti +@@ -37,7 +37,6 @@ + provided pointcut Ethernet::create_device; + } + +- /* Likely extends PCI::remove */ + provided sequence Ethernet::exit(PCI::Device) + { + provided chunk ::CALL; +diff --git a/rathaxes/samples/lkm/lkm.blt b/rathaxes/samples/lkm/lkm.blt +--- a/rathaxes/samples/lkm/lkm.blt ++++ b/rathaxes/samples/lkm/lkm.blt +@@ -12,9 +12,6 @@ + { + #include + #include +- +- typedef int include_linux_module_stamp; +- typedef int include_linux_kernel_stamp; + } + + chunk LKM::data() +diff --git a/rathaxes/samples/lkm/lkm.rtx b/rathaxes/samples/lkm/lkm.rtx +--- a/rathaxes/samples/lkm/lkm.rtx ++++ b/rathaxes/samples/lkm/lkm.rtx +@@ -1,4 +1,4 @@ +-device LKM use LKM, PCI, Log ++device LKM use LKM, PCI, Ethernet, Log + { + Ethernet::open(Ethernet::Device dev) + { +diff --git a/rathaxes/samples/lkm/pci.blt b/rathaxes/samples/lkm/pci.blt +--- a/rathaxes/samples/lkm/pci.blt ++++ b/rathaxes/samples/lkm/pci.blt +@@ -5,8 +5,6 @@ + chunk LKM::includes() + { + #include +- +- typedef int include_linux_pci_stamp; + } + + chunk ::decl() +@@ -24,16 +22,6 @@ + } + } + +- /* +- * The PCI::probe sequence is a "required" sequence which means that its +- * implementation will be done in the .rtx. Here we just define the context +- * were this implementation will be inserted. The implementation should be +- * able to access to the struct pci_dev (here marked as the "argument" +- * PCI::Device). How do we bind this PCI::Device argument with the pdev +- * struct pci_dev pointer defined in the LKM::code chunk? +- * +- * The only thing I can imagine is: ${pointcut ::IMPLEMENTATION(pdev)}; +- */ + template sequence PCI::probe(PCI::Device pdev) + { + chunk LKM::prototypes() +@@ -112,22 +100,32 @@ + + chunk LKM::init_bus_hook() + { +- /* +- * So how do we use the return value in the parent context? +- */ + int error; + if ((error = pci_register_driver(&rtx_pci_driver))) + { + ${Log::info("Cannot register pci driver")}; +- // should we return here. +- // error managmement procedure has to be determined ASAP. ++ /* ++ * So we catched the error but how do we return it to the ++ * parent context? ++ * ++ * Here we know that we can just return error, but that's just ++ * a coincidence (and, in this case, *we* wrote the parent ++ * context). ++ */ + return error; + } + } + + chunk ::CALL() + { +- // no implementation, we just need to instrument the lkm::bus_hook ++ /* ++ * The implementation of ::CALL is empty. This template sequence is ++ * actually not provided nor required. ++ * ++ * This sequence is just "intermediate" code that will just inject ++ * itself in the hook LKM::init_bus_hook for which this sequence ++ * has a chunk (see above chunk). ++ */ + } + } + +diff --git a/rathaxes/samples/lkm/pci.rti b/rathaxes/samples/lkm/pci.rti +--- a/rathaxes/samples/lkm/pci.rti ++++ b/rathaxes/samples/lkm/pci.rti +@@ -7,11 +7,6 @@ + + provided sequence PCI::register() + { +- // it is impossible to provide a "dummy" sequence +- // which just hook itself. The PCI:register juste +- // inject its code in the module_init function +- // in order to load the pci driver. +- // Everything is done with the configuration. + provided chunk ::CALL; + provided chunk LKM::data; + provided chunk LKM::init_bus_hook; diff -r 791c7fa1f055 -r 9433dec37a52 series --- a/series Sun Jan 08 01:10:20 2012 +0100 +++ b/series Sun Jan 08 01:45:20 2012 +0100 @@ -7,3 +7,4 @@ pci_rework_without_explicit_call.patch ethernet_rework_without_explicit_call.patch e1000_rework_without_explicit_call.patch +rathaxes_add_lkm_ethernet_sample.patch