--- a/drivers/ec_module.c Fri Dec 16 09:44:54 2005 +0000
+++ b/drivers/ec_module.c Fri Dec 16 12:04:59 2005 +0000
@@ -30,6 +30,7 @@
int ecat_master_count = 1;
EtherCAT_master_t *ecat_masters = NULL;
+int *ecat_masters_reserved = NULL;
/******************************************************************************/
@@ -44,7 +45,10 @@
module_init(ecat_init_module);
module_exit(ecat_cleanup_module);
-EXPORT_SYMBOL(EtherCAT_master);
+EXPORT_SYMBOL(EtherCAT_register_device);
+EXPORT_SYMBOL(EtherCAT_unregister_device);
+EXPORT_SYMBOL(EtherCAT_request);
+EXPORT_SYMBOL(EtherCAT_release);
/******************************************************************************/
@@ -82,9 +86,18 @@
return -1;
}
+ if ((ecat_masters_reserved = (int *) kmalloc(sizeof(int) * ecat_master_count,
+ GFP_KERNEL)) == NULL)
+ {
+ printk(KERN_ERR "EtherCAT: Could not allocate memory for reservation flags!\n");
+ kfree(ecat_masters);
+ return -1;
+ }
+
for (i = 0; i < ecat_master_count; i++)
{
EtherCAT_master_init(&ecat_masters[i]);
+ ecat_masters_reserved[i] = 0;
}
printk(KERN_ERR "EtherCAT: Master driver initialized.\n");
@@ -110,6 +123,10 @@
{
for (i = 0; i < ecat_master_count; i++)
{
+ if (ecat_masters_reserved[i]) {
+ printk(KERN_WARNING "EtherCAT: Warning - Master %i is still in use!\n", i);
+ }
+
EtherCAT_master_clear(&ecat_masters[i]);
}
@@ -119,24 +136,129 @@
printk(KERN_ERR "EtherCAT: Master driver cleaned up.\n");
}
-/******************************************************************************/
-
-/**
- Gibt einen Zeiger auf einen bestimmten EtherCAT-Master zurueck.
+/***************************************************************/
+
+/**
+ Setzt das EtherCAT-Geraet, auf dem der Master arbeitet.
+
+ Registriert das Geraet beim Master, der es daraufhin oeffnet.
+
+ @param master Der EtherCAT-Master
+ @param device Das EtherCAT-Geraet
+ @return 0, wenn alles o.k.,
+ < 0, wenn bereits ein Geraet registriert
+ oder das Geraet nicht geoeffnet werden konnte.
+*/
+
+int EtherCAT_register_device(int index, EtherCAT_device_t *device)
+{
+ if (index < 0 || index >= ecat_master_count)
+ {
+ printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index);
+ return -1;
+ }
+
+ return EtherCAT_master_open(&ecat_masters[index], device);
+}
+
+/***************************************************************/
+
+/**
+ Loescht das EtherCAT-Geraet, auf dem der Master arbeitet.
+
+ @param master Der EtherCAT-Master
+ @param device Das EtherCAT-Geraet
+*/
+
+void EtherCAT_unregister_device(int index, EtherCAT_device_t *device)
+{
+ if (index < 0 || index >= ecat_master_count)
+ {
+ printk(KERN_WARNING "EtherCAT: Master %i does not exist!\n", index);
+ return;
+ }
+
+ EtherCAT_master_close(&ecat_masters[index], device);
+}
+
+/******************************************************************************/
+
+/**
+ Reserviert einen bestimmten EtherCAT-Master und das zugehörige Gerät.
+
+ Gibt einen Zeiger auf den reservierten EtherCAT-Master zurueck.
@param index Index des gewuenschten Masters
@returns Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig.
*/
-EtherCAT_master_t *EtherCAT_master(int index)
-{
- if (index < 0 || index >= ecat_master_count)
- {
+EtherCAT_master_t *EtherCAT_request(int index)
+{
+ if (index < 0 || index >= ecat_master_count) {
printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index);
return NULL;
}
+ if (ecat_masters_reserved[index]) {
+ printk(KERN_ERR "EtherCAT: Master %i already in use!\n", index);
+ return NULL;
+ }
+
+ if (!ecat_masters[index].dev) {
+ printk(KERN_ERR "EtherCAT: Master %i has no device assigned yet!\n", index);
+ return NULL;
+ }
+
+ if (!ecat_masters[index].dev->module) {
+ printk(KERN_ERR "EtherCAT: Master %i device module is not set!\n", index);
+ return NULL;
+ }
+
+ if (!try_module_get(ecat_masters[index].dev->module)) {
+ printk(KERN_ERR "EtherCAT: Could not reserve device module!\n");
+ return NULL;
+ }
+
+ ecat_masters_reserved[index] = 1;
+
+ printk(KERN_INFO "EtherCAT: Reserved master %i.\n", index);
+
return &ecat_masters[index];
}
/******************************************************************************/
+
+/**
+ Gibt einen zuvor reservierten EtherCAT-Master wieder frei.
+
+ @param master Zeiger auf den freizugebenden EtherCAT-Master.
+*/
+
+void EtherCAT_release(EtherCAT_master_t *master)
+{
+ unsigned int i;
+
+ for (i = 0; i < ecat_master_count; i++)
+ {
+ if (&ecat_masters[i] == master)
+ {
+ if (!ecat_masters[i].dev) {
+ printk(KERN_WARNING "EtherCAT: Could not release device"
+ "module because of no device!\n");
+ return;
+ }
+
+ module_put(ecat_masters[i].dev->module);
+ ecat_masters_reserved[i] = 0;
+
+ printk(KERN_INFO "EtherCAT: Released master %i.\n", i);
+
+ return;
+ }
+ }
+
+ printk(KERN_WARNING "EtherCAT: Master %X was never reserved!\n",
+ (unsigned int) master);
+}
+
+/******************************************************************************/