diff -r 3213cbbd58b7 -r 6965c23a6826 drivers/ec_device.c --- a/drivers/ec_device.c Fri Dec 16 16:21:22 2005 +0000 +++ b/drivers/ec_device.c Mon Dec 19 08:13:11 2005 +0000 @@ -1,13 +1,12 @@ -/**************************************************************** +/****************************************************************************** * * e c _ d e v i c e . c * * Methoden für ein EtherCAT-Gerät. * - * $Date$ - * $Author$ + * $Id$ * - ***************************************************************/ + *****************************************************************************/ #include #include @@ -17,7 +16,7 @@ #include "ec_device.h" -/***************************************************************/ +/*****************************************************************************/ /** EtherCAT-Geräte-Konstuktor. @@ -42,9 +41,10 @@ ecd->rx_data_length = 0; ecd->isr = NULL; ecd->module = NULL; -} - -/***************************************************************/ + ecd->error_reported = 0; +} + +/*****************************************************************************/ /** EtherCAT-Geräte-Destuktor. @@ -59,20 +59,18 @@ { ecd->dev = NULL; - if (ecd->tx_skb) - { + if (ecd->tx_skb) { dev_kfree_skb(ecd->tx_skb); ecd->tx_skb = NULL; } - if (ecd->rx_skb) - { + if (ecd->rx_skb) { dev_kfree_skb(ecd->rx_skb); ecd->rx_skb = NULL; } } -/***************************************************************/ +/*****************************************************************************/ /** Weist einem EtherCAT-Gerät das entsprechende net_device zu. @@ -90,23 +88,19 @@ int EtherCAT_device_assign(EtherCAT_device_t *ecd, struct net_device *dev) { - if (!dev) - { + if (!dev) { printk("EtherCAT: Device is NULL!\n"); return -1; } - if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) - { + if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) { printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n"); return -1; } - if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) - { + if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) { dev_kfree_skb(ecd->tx_skb); ecd->tx_skb = NULL; - printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n"); return -1; } @@ -120,7 +114,7 @@ return 0; } -/***************************************************************/ +/*****************************************************************************/ /** Führt die open()-Funktion des Netzwerktreibers aus. @@ -137,14 +131,12 @@ int EtherCAT_device_open(EtherCAT_device_t *ecd) { - if (!ecd) - { + if (!ecd) { printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n"); return -1; } - if (!ecd->dev) - { + if (!ecd->dev) { printk(KERN_ERR "EtherCAT: No net_device to open!\n"); return -1; } @@ -157,7 +149,7 @@ return ecd->dev->open(ecd->dev); } -/***************************************************************/ +/*****************************************************************************/ /** Führt die stop()-Funktion des net_devices aus. @@ -169,8 +161,7 @@ int EtherCAT_device_close(EtherCAT_device_t *ecd) { - if (!ecd->dev) - { + if (!ecd->dev) { printk("EtherCAT: No device to close!\n"); return -1; } @@ -182,7 +173,7 @@ return ecd->dev->stop(ecd->dev); } -/***************************************************************/ +/*****************************************************************************/ /** Sendet einen Rahmen über das EtherCAT-Gerät. @@ -206,28 +197,34 @@ unsigned char *frame_data; struct ethhdr *eth; - if (ecd->state == ECAT_DS_SENT) - { - printk(KERN_WARNING "EtherCAT: Trying to send frame while last was not received!\n"); - } - - skb_trim(ecd->tx_skb, 0); // Clear transmit socket buffer - skb_reserve(ecd->tx_skb, ETH_HLEN); // Reserve space for Ethernet-II header + if (unlikely(ecd->state == ECAT_DS_SENT)) { + printk(KERN_WARNING "EtherCAT: Warning - Trying to send frame" + " while last was not received!\n"); + } + + // Clear transmit socket buffer and reserve + // space for Ethernet-II header + skb_trim(ecd->tx_skb, 0); + skb_reserve(ecd->tx_skb, ETH_HLEN); // Copy data to socket buffer frame_data = skb_put(ecd->tx_skb, length); memcpy(frame_data, data, length); // Add Ethernet-II-Header - if ((eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN)) == NULL) - { - printk(KERN_ERR "EtherCAT: device_send - Could not allocate Ethernet-II header!\n"); - return -1; - } - - eth->h_proto = htons(0x88A4); // Protocol type - memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len); // Hardware address - memset(eth->h_dest, 0xFF, ecd->dev->addr_len); // Broadcast address + if (unlikely((eth = (struct ethhdr *) + skb_push(ecd->tx_skb, ETH_HLEN)) == NULL)) { + printk(KERN_ERR "EtherCAT: device_send -" + " Could not allocate Ethernet-II header!\n"); + return -1; + } + + // Protocol type + eth->h_proto = htons(0x88A4); + // Hardware address + memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len); + // Broadcast address + memset(eth->h_dest, 0xFF, ecd->dev->addr_len); rdtscl(ecd->tx_time); // Get CPU cycles @@ -238,14 +235,14 @@ return 0; } -/***************************************************************/ +/*****************************************************************************/ /** Holt einen empfangenen Rahmen von der Netzwerkkarte. Zuerst wird geprüft, ob überhaupt ein Rahmen empfangen - wurde. Wenn ja, wird diesem mit Hilfe eines Spin-Locks - in den angegebenen Speicherbereich kopiert. + wurde. Wenn ja, wird dieser in den angegebenen + Speicherbereich kopiert. @param ecd EtherCAT-Gerät @param data Zeiger auf den Speicherbereich, in den die @@ -257,17 +254,26 @@ int EtherCAT_device_receive(EtherCAT_device_t *ecd, unsigned char *data) { - if (ecd->state != ECAT_DS_RECEIVED) - { - printk(KERN_ERR "EtherCAT: receive - Nothing received!\n"); - return -1; - } - - if (ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE) - { - printk(KERN_ERR "EtherCAT: receive - Reveived frame too long (%i Bytes)!\n", - ecd->rx_data_length); - return -1; + if (unlikely(ecd->state != ECAT_DS_RECEIVED)) { + if (likely(ecd->error_reported)) { + printk(KERN_ERR "EtherCAT: receive - Nothing received!\n"); + ecd->error_reported = 1; + } + return -1; + } + + if (unlikely(ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE)) { + if (likely(ecd->error_reported)) { + printk(KERN_ERR "EtherCAT: receive - " + " Reveived frame too long (%i Bytes)!\n", + ecd->rx_data_length); + ecd->error_reported = 1; + } + return -1; + } + + if (unlikely(ecd->error_reported)) { + ecd->error_reported = 0; } memcpy(data, ecd->rx_data, ecd->rx_data_length); @@ -275,7 +281,7 @@ return ecd->rx_data_length; } -/***************************************************************/ +/*****************************************************************************/ /** Ruft manuell die Interrupt-Routine der Netzwerkkarte auf. @@ -287,10 +293,10 @@ void EtherCAT_device_call_isr(EtherCAT_device_t *ecd) { - if (ecd->isr) ecd->isr(0, ecd->dev, NULL); -} - -/***************************************************************/ + if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL); +} + +/*****************************************************************************/ /** Gibt alle Informationen über das Device-Objekt aus. @@ -304,16 +310,26 @@ if (ecd) { - printk(KERN_DEBUG "Assigned net_device: %X\n", (unsigned) ecd->dev); - printk(KERN_DEBUG "Transmit socket buffer: %X\n", (unsigned) ecd->tx_skb); - printk(KERN_DEBUG "Receive socket buffer: %X\n", (unsigned) ecd->rx_skb); - printk(KERN_DEBUG "Time of last transmission: %u\n", (unsigned) ecd->tx_time); - printk(KERN_DEBUG "Time of last receive: %u\n", (unsigned) ecd->rx_time); - printk(KERN_DEBUG "Number of transmit interrupts: %u\n", (unsigned) ecd->tx_intr_cnt); - printk(KERN_DEBUG "Number of receive interrupts: %u\n", (unsigned) ecd->rx_intr_cnt); - printk(KERN_DEBUG "Total Number of interrupts: %u\n", (unsigned) ecd->intr_cnt); - printk(KERN_DEBUG "Actual device state: %i\n", (int) ecd->state); - printk(KERN_DEBUG "Receive buffer: %X\n", (unsigned) ecd->rx_data); + printk(KERN_DEBUG "Assigned net_device: %X\n", + (unsigned) ecd->dev); + printk(KERN_DEBUG "Transmit socket buffer: %X\n", + (unsigned) ecd->tx_skb); + printk(KERN_DEBUG "Receive socket buffer: %X\n", + (unsigned) ecd->rx_skb); + printk(KERN_DEBUG "Time of last transmission: %u\n", + (unsigned) ecd->tx_time); + printk(KERN_DEBUG "Time of last receive: %u\n", + (unsigned) ecd->rx_time); + printk(KERN_DEBUG "Number of transmit interrupts: %u\n", + (unsigned) ecd->tx_intr_cnt); + printk(KERN_DEBUG "Number of receive interrupts: %u\n", + (unsigned) ecd->rx_intr_cnt); + printk(KERN_DEBUG "Total Number of interrupts: %u\n", + (unsigned) ecd->intr_cnt); + printk(KERN_DEBUG "Actual device state: %i\n", + (int) ecd->state); + printk(KERN_DEBUG "Receive buffer: %X\n", + (unsigned) ecd->rx_data); printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n", (unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE); } @@ -325,7 +341,7 @@ printk(KERN_DEBUG "---EtherCAT device information end---\n"); } -/***************************************************************/ +/*****************************************************************************/ EXPORT_SYMBOL(EtherCAT_device_init); EXPORT_SYMBOL(EtherCAT_device_clear); @@ -333,4 +349,4 @@ EXPORT_SYMBOL(EtherCAT_device_open); EXPORT_SYMBOL(EtherCAT_device_close); -/***************************************************************/ +/*****************************************************************************/