Mercurial > archived > louis > epitech > mq > rathaxes
view rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch @ 14:4aac69287060
Fixes + comment in the Ethernet part
author | Louis Opter <louis@lse.epitech.net> |
---|---|
date | Fri, 06 Jan 2012 19:09:16 +0100 |
parents | d00a5829811d |
children | 74d9d18d4732 |
line wrap: on
line source
# HG changeset patch # Parent 93035f60f6725e2e0f25dcb5276c45d3a44d12fa rathaxes: start to implement the Ethernet subsystem in linux LKM sample diff --git a/rathaxes/samples/lkm/CMakeLists.txt b/rathaxes/samples/lkm/CMakeLists.txt --- a/rathaxes/samples/lkm/CMakeLists.txt +++ b/rathaxes/samples/lkm/CMakeLists.txt @@ -1,6 +1,6 @@ ADD_RATHAXES_SOURCES(lkm lkm.rtx - RTI log.rti lkm.rti pci.rti - BLT log.blt lkm.blt pci.blt) + RTI log.rti lkm.rti pci.rti ethernet.rti + BLT log.blt lkm.blt pci.blt ethernet.blt) # We can't name lkm since it's already used as the target name to generate the # source (with ADD_RATHAXES_SOURCES). diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt new file mode 100644 --- /dev/null +++ b/rathaxes/samples/lkm/ethernet.blt @@ -0,0 +1,144 @@ +with Ethernet, PCI, LKM +{ + template type Ethernet::Device() + { + chunk LKM::includes() + { + #include <linux/netdevice.h> + #include <linux/etherdevice.h> + + typedef int include_linux_net_system_stamp; + } + + chunk ::decl() + { + struct net_device; + } + + chunk ::init(net_dev) + { + ${self} = ${net_dev}; + } + + map + { + } + } + + template sequence Ethernet::open(Ethernet::Device dev) + { + chunk LKM::prototypes() + { + static int rtx_ethernet_open(struct net_device *); + } + + chunk LKM::code() + { + static int rtx_ethernet_open(struct net_device *dev) + { + ${pointcut ::IMPLEMENTATION}; + + return 0; + } + } + } + + template sequence Ethernet::close(Ethernet::Device dev) + { + chunk LKM::prototypes() + { + static int rtx_ethernet_close(struct net_device *); + } + + chunk LKM::code() + { + static int rtx_ethernet_close(struct net_device *dev) + { + ${pointcut ::IMPLEMENTATION}; + + return 0; + } + } + } + + 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). + */ + + chunk LKM::prototypes() + { + static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); + } + + chunk LKM::code() + { + static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) + { + ${pointcut ::IMPLEMENTATION}; + + return IRQ_NONE; + } + } + } + + template sequence Ethernet::init(PCI::Device dev) + { + chunk LKM::data() + { + /* + * This typedef is needed to workaround a bug in CNorm __std__ + * dialect. + */ + typedef int ${Ethernet::Device}; + + static ${Ethernet::Device} *rtx_net_dev = NULL; + static const struct net_device_ops rtx_ether_ops = + { + .ndo_open = rtx_ethernet_open, + .ndo_stop = rtx_ethernet_close, + .ndo_start_xmit = NULL, + }; + + } + + chunk ::CALL + { + /* + * int should be replaced by the sizeof of an hypothetic "context" + * structure defined in the front-end. + */ + rtx_net_dev = alloc_etherdev(sizeof(int)); + /* + * if (rtx_net_dev == NULL) + * { + * // What can we do here? + * } + */ + + /* + * The substitution of ${dev} fails here. I also tried to add a + * "substitute method" to the PCI::Device that was just doing + * "${self}" but it didn't work either (it was subsituted by a + * placeholder, e.g: _1). + */ + //SET_NETDEV_DEV(rtx_net_dev, &${dev}->dev); + rtx_net_dev->netdev_ops = &rtx_ether_ops; + + /* if (*/register_netdev(rtx_net_dev);/*)*/ + /* { + * XXX: handle the error + * } + */ + } + } + + template sequence Ethernet::exit(PCI::Device dev) + { + chunk ::CALL + { + } + } +} diff --git a/rathaxes/samples/lkm/ethernet.rti b/rathaxes/samples/lkm/ethernet.rti new file mode 100644 --- /dev/null +++ b/rathaxes/samples/lkm/ethernet.rti @@ -0,0 +1,33 @@ +interface Ethernet : PCI, LKM +{ + provided type Ethernet::Device; + + required sequence Ethernet::open(Ethernet::Device) + { + provided chunk LKM::prototypes; + provided chunk LKM::code; + } + + required sequence Ethernet::close(Ethernet::Device) + { + provided chunk LKM::prototypes; + provided chunk LKM::code; + } + + required sequence Ethernet::interrupt_handler(Ethernet::Device) + { + provided chunk LKM::prototypes; + provided chunk LKM::code; + } + + provided sequence Ethernet::init(PCI::Device) + { + provided chunk LKM::data; + provided chunk ::CALL; + } + + provided sequence Ethernet::exit(PCI::Device) + { + provided chunk ::CALL; + } +} 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,13 +1,24 @@ device LKM use LKM, PCI, Log { + Ethernet::open(Ethernet::Device dev) + { + } + + Ethernet::close(Ethernet::Device dev) + { + } + + Ethernet::interrupt_handler(Ethernet::Device dev) + { + } + PCI::probe(PCI::Device dev) { - + Ethernet::init(dev); } PCI::remove(PCI::Device dev) { - } LKM::init() 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 @@ -11,15 +11,12 @@ chunk ::decl() { - struct rtx_pci_device - { - struct pci_dev *pci_dev; - }; + struct pci_dev; } chunk ::init(pci_dev) { - ${self}.pci_dev = pci_dev; + ${self} = ${pci_dev}; } map @@ -27,6 +24,16 @@ } } + /* + * 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 dev) { chunk LKM::prototypes() @@ -40,11 +47,7 @@ static int /* __devinit */ rtx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { - /* workaround for CNorm __std__ dialect, shouldn't be here */ - typedef int ${PCI::Device}; - int err; - ${PCI::Device} *dev = NULL; err = pci_enable_device(pdev); // if (err < 0) /* `if' doesn't work */ @@ -52,8 +55,6 @@ ${pointcut ::IMPLEMENTATION}; - pci_set_drvdata(pdev, dev); - return 0; fail: @@ -88,9 +89,10 @@ * CNorm doesn't seem to like "dynamic" arrays (i.e: you always * have to specify the exact size). */ - static struct pci_device_id rtx_pci_device_table[2] = { - { ${config.vendor_id}, ${config.product_id}, 0, PCI_ANY_ID, PCI_ANY_ID }, - { 0, } + static struct pci_device_id rtx_pci_device_table[2] = + { + { ${config.vendor_id}, ${config.product_id}, PCI_ANY_ID, PCI_ANY_ID }, + { 0, } /* Doesn't work with just { } */ }; static struct pci_driver rtx_pci_driver = {