Merged changes from Martin Troxler.

This commit is contained in:
Florian Pose
2009-12-14 13:11:36 +01:00
12 changed files with 5533 additions and 19 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -393,7 +393,7 @@ int __init init_mini_module(void)
goto out_return;
}
init_MUTEX(&master_sem);
sema_init(&master_sem, 1);
ecrt_master_callbacks(master, send_callback, receive_callback, master);
printk(KERN_INFO PFX "Registering domain...\n");

View File

@@ -459,7 +459,7 @@ int __init init_mini_module(void)
goto out_tty;
}
init_MUTEX(&master_sem);
sema_init(&master_sem, 1);
ecrt_master_callbacks(master, send_callback, receive_callback, master);
printk(KERN_INFO PFX "Registering domain...\n");

View File

@@ -219,6 +219,7 @@ typedef struct {
typedef struct {
unsigned int slave_count; /**< Number of slaves in the bus. */
unsigned int link_up : 1; /**< \a true, if the network link is up. */
uint8_t scan_busy; /**< \a true, while the master is scanning the bus */
uint64_t app_time; /**< Application time. */
} ec_master_info_t;

View File

@@ -125,6 +125,7 @@ int ecrt_master(ec_master_t* master, ec_master_info_t *master_info)
master_info->slave_count = data.slave_count;
master_info->link_up = data.devices[0].link_state;
master_info->scan_busy = data.scan_busy;
master_info->app_time = data.app_time;
return 0;
}

View File

@@ -34,6 +34,7 @@
/*****************************************************************************/
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -48,6 +49,16 @@ int ec_dbgdev_stop(struct net_device *);
int ec_dbgdev_tx(struct sk_buff *, struct net_device *);
struct net_device_stats *ec_dbgdev_stats(struct net_device *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
static const struct net_device_ops ec_dbg_netdev_ops =
{
.ndo_open = ec_dbgdev_open,
.ndo_stop = ec_dbgdev_stop,
.ndo_start_xmit = ec_dbgdev_tx,
.ndo_get_stats = ec_dbgdev_stats,
};
#endif
/*****************************************************************************/
/** Debug interface constructor.
@@ -74,10 +85,14 @@ int ec_debug_init(
}
// initialize net_device
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
dbg->dev->netdev_ops = &ec_dbg_netdev_ops;
#else
dbg->dev->open = ec_dbgdev_open;
dbg->dev->stop = ec_dbgdev_stop;
dbg->dev->hard_start_xmit = ec_dbgdev_tx;
dbg->dev->get_stats = ec_dbgdev_stats;
#endif
// initialize private data
*((ec_debug_t **) netdev_priv(dbg->dev)) = dbg;

View File

@@ -34,6 +34,7 @@
/*****************************************************************************/
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -118,7 +119,8 @@ int ec_eoe_init(
eoe->tx_queue_active = 0;
eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE;
eoe->tx_queued_frames = 0;
init_MUTEX(&eoe->tx_queue_sem);
sema_init(&eoe->tx_queue_sem, 1);
eoe->tx_frame_number = 0xFF;
memset(&eoe->stats, 0, sizeof(struct net_device_stats));

View File

@@ -344,7 +344,7 @@ int ec_fsm_master_action_process_sii(
/*****************************************************************************/
/** Check for pending register requests and process one.
*
*
* \return non-zero, if a register request is processed.
*/
int ec_fsm_master_action_process_register(
@@ -949,6 +949,7 @@ void ec_fsm_master_state_write_sii(
if (request->offset <= 4 && request->offset + request->nwords > 4) {
// alias was written
slave->sii.alias = EC_READ_U16(request->words + 4);
// TODO: read alias from register 0x0012
}
// TODO: Evaluate other SII contents!
@@ -1089,7 +1090,7 @@ void ec_fsm_master_state_reg_request(
ec_fsm_master_restart(fsm);
return;
}
if (datagram->working_counter == 1) {
if (request->dir == EC_DIR_INPUT) { // read request
if (request->data)

View File

@@ -52,6 +52,7 @@ void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_regalias(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_sync(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *);
@@ -60,6 +61,7 @@ void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_enter_regalias(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *);
@@ -313,7 +315,7 @@ void ec_fsm_slave_scan_state_base(
for (i = 0; i < EC_MAX_PORTS; i++) {
slave->ports[i].desc = (octet >> (2 * i)) & 0x03;
}
octet = EC_READ_U8(datagram->data + 8);
slave->base_fmmu_bit_operation = octet & 0x01;
slave->base_dc_supported = (octet >> 2) & 0x01;
@@ -600,7 +602,7 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
}
// Evaluate SII contents
ec_slave_clear_sync_managers(slave);
slave->sii.alias =
@@ -711,11 +713,7 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
}
}
if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
ec_fsm_slave_scan_enter_preop(fsm);
} else {
fsm->state = ec_fsm_slave_scan_state_end;
}
ec_fsm_slave_scan_enter_regalias(fsm);
return;
end:
@@ -724,6 +722,74 @@ end:
fsm->state = ec_fsm_slave_scan_state_error;
}
/*****************************************************************************/
/**
Slave scan entry function: REGALIAS.
*/
void ec_fsm_slave_scan_enter_regalias(
ec_fsm_slave_scan_t *fsm /**< slave state machine */
)
{
ec_datagram_t *datagram = fsm->datagram;
ec_slave_t *slave = fsm->slave;
// read alias from register 0x0012
if (slave->master->debug_level)
EC_DBG("Reading alias from register 0x0012 of slave %u.\n",
slave->ring_position);
ec_datagram_fprd(datagram, slave->station_address, 0x0012, 2);
ec_datagram_zero(datagram);
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_slave_scan_state_regalias;
}
/*****************************************************************************/
/**
Slave scan state: REGALIAS.
*/
void ec_fsm_slave_scan_state_regalias(
ec_fsm_slave_scan_t *fsm /**< slave state machine */
)
{
ec_datagram_t *datagram = fsm->datagram;
ec_slave_t *slave = fsm->slave;
if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
return;
if (datagram->state != EC_DATAGRAM_RECEIVED) {
fsm->state = ec_fsm_slave_scan_state_error;
EC_ERR("Failed to receive get reg alias datagram from slave %u"
" (datagram state %u).\n",
fsm->slave->ring_position, datagram->state);
return;
}
if (datagram->working_counter != 1) {
fsm->slave->error_flag = 1;
fsm->state = ec_fsm_slave_scan_state_error;
EC_ERR("Failed to read reg alias of slave %u: ",
fsm->slave->ring_position);
ec_datagram_print_wc_error(datagram);
return;
}
slave->sii.alias = EC_READ_U16(datagram->data);
if (slave->master->debug_level)
EC_DBG("Alias of slave %u is %u.\n",
slave->ring_position,slave->sii.alias);
if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
ec_fsm_slave_scan_enter_preop(fsm);
} else {
fsm->state = ec_fsm_slave_scan_state_end;
}
}
/*****************************************************************************/
/** Enter slave scan state PREOP.

View File

@@ -114,11 +114,12 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
master->index = index;
master->reserved = 0;
init_MUTEX(&master->master_sem);
sema_init(&master->master_sem, 1);
master->main_mac = main_mac;
master->backup_mac = backup_mac;
init_MUTEX(&master->device_sem);
sema_init(&master->device_sem, 1);
master->phase = EC_ORPHANED;
master->active = 0;
@@ -136,19 +137,19 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
master->scan_busy = 0;
master->allow_scan = 1;
init_MUTEX(&master->scan_sem);
sema_init(&master->scan_sem, 1);
init_waitqueue_head(&master->scan_queue);
master->config_busy = 0;
master->allow_config = 1;
init_MUTEX(&master->config_sem);
sema_init(&master->config_sem, 1);
init_waitqueue_head(&master->config_queue);
INIT_LIST_HEAD(&master->datagram_queue);
master->datagram_index = 0;
INIT_LIST_HEAD(&master->ext_datagram_queue);
init_MUTEX(&master->ext_queue_sem);
sema_init(&master->ext_queue_sem, 1);
INIT_LIST_HEAD(&master->domains);
@@ -166,7 +167,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
INIT_LIST_HEAD(&master->eoe_handlers);
#endif
init_MUTEX(&master->io_sem);
sema_init(&master->io_sem, 1);
master->send_cb = NULL;
master->receive_cb = NULL;
master->cb_data = NULL;

View File

@@ -101,7 +101,7 @@ int __init ec_init_module(void)
EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
init_MUTEX(&master_sem);
sema_init(&master_sem, 1);
if (master_count) {
if (alloc_chrdev_region(&device_number, 0, master_count, "EtherCAT")) {