Master-Reservierung und Use-Count für NIC-Treiber.
This commit is contained in:
parent
d0585af0c4
commit
c0a04f5109
|
|
@ -202,7 +202,7 @@ static int ec_device_index = -1;
|
|||
static int ec_device_master_index = 0;
|
||||
|
||||
static EtherCAT_device_t rtl_ecat_dev;
|
||||
static EtherCAT_master_t *rtl_ecat_master = NULL;
|
||||
int rtl_ecat_dev_registered = 0;
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
||||
|
|
@ -2966,6 +2966,7 @@ static int __init rtl8139_init_module (void)
|
|||
|
||||
EtherCAT_device_init(&rtl_ecat_dev);
|
||||
rtl_ecat_dev.isr = rtl8139_interrupt;
|
||||
rtl_ecat_dev.module = THIS_MODULE;
|
||||
|
||||
if (pci_module_init(&rtl8139_pci_driver) < 0)
|
||||
{
|
||||
|
|
@ -2977,20 +2978,15 @@ static int __init rtl8139_init_module (void)
|
|||
|
||||
if (rtl_ecat_dev.dev)
|
||||
{
|
||||
if ((rtl_ecat_master = EtherCAT_master(ec_device_master_index)) == NULL)
|
||||
{
|
||||
printk(KERN_ERR "Could not get EtherCAT master %i.\n",
|
||||
ec_device_master_index);
|
||||
goto out_module;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Registering EtherCAT device...\n");
|
||||
if (EtherCAT_register_device(rtl_ecat_master, &rtl_ecat_dev) < 0)
|
||||
if (EtherCAT_register_device(ec_device_master_index, &rtl_ecat_dev) < 0)
|
||||
{
|
||||
printk(KERN_ERR "Could not register device.\n");
|
||||
goto out_module;
|
||||
}
|
||||
|
||||
rtl_ecat_dev_registered = 1;
|
||||
|
||||
printk(KERN_INFO "EtherCAT device registered and opened.\n");
|
||||
}
|
||||
else
|
||||
|
|
@ -3015,10 +3011,10 @@ static void __exit rtl8139_cleanup_module (void)
|
|||
|
||||
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
|
||||
|
||||
if (rtl_ecat_master && rtl_ecat_dev.dev)
|
||||
if (rtl_ecat_dev_registered && rtl_ecat_dev.dev)
|
||||
{
|
||||
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
|
||||
EtherCAT_unregister_device(rtl_ecat_master, &rtl_ecat_dev);
|
||||
EtherCAT_unregister_device(ec_device_master_index, &rtl_ecat_dev);
|
||||
}
|
||||
|
||||
pci_unregister_driver(&rtl8139_pci_driver);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ void EtherCAT_device_init(EtherCAT_device_t *ecd)
|
|||
ecd->state = ECAT_DS_READY;
|
||||
ecd->rx_data_length = 0;
|
||||
ecd->isr = NULL;
|
||||
ecd->module = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ typedef struct
|
|||
volatile unsigned int rx_data_length; /**< Länge des zuletzt
|
||||
empfangenen Rahmens */
|
||||
irqreturn_t (*isr)(int, void *, struct pt_regs *); /**< Adresse der ISR */
|
||||
struct module *module; /**< Zeiger auf das Modul, das das Gerät zur
|
||||
Verfügung stellt. */
|
||||
}
|
||||
EtherCAT_device_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,9 @@ void EtherCAT_master_clear(EtherCAT_master_t *master)
|
|||
/***************************************************************/
|
||||
|
||||
/**
|
||||
Setzt das EtherCAT-Geraet, auf dem der Master arbeitet.
|
||||
Öffnet ein EtherCAT-Geraet für den Master.
|
||||
|
||||
Registriert das Geraet beim master, der es daraufhin oeffnet.
|
||||
Registriert das Geraet beim Master, der es daraufhin oeffnet.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
@param device Das EtherCAT-Geraet
|
||||
|
|
@ -80,12 +80,12 @@ void EtherCAT_master_clear(EtherCAT_master_t *master)
|
|||
oder das Geraet nicht geoeffnet werden konnte.
|
||||
*/
|
||||
|
||||
int EtherCAT_register_device(EtherCAT_master_t *master,
|
||||
EtherCAT_device_t *device)
|
||||
int EtherCAT_master_open(EtherCAT_master_t *master,
|
||||
EtherCAT_device_t *device)
|
||||
{
|
||||
if (!master || !device)
|
||||
{
|
||||
printk(KERN_ERR "EtherCAT: Illegal parameters for register_device()!\n");
|
||||
printk(KERN_ERR "EtherCAT: Illegal parameters for master_open()!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -110,18 +110,18 @@ int EtherCAT_register_device(EtherCAT_master_t *master,
|
|||
/***************************************************************/
|
||||
|
||||
/**
|
||||
Loescht das EtherCAT-Geraet, auf dem der Master arbeitet.
|
||||
Schliesst das EtherCAT-Geraet, auf dem der Master arbeitet.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
@param device Das EtherCAT-Geraet
|
||||
*/
|
||||
|
||||
void EtherCAT_unregister_device(EtherCAT_master_t *master,
|
||||
EtherCAT_device_t *device)
|
||||
void EtherCAT_master_close(EtherCAT_master_t *master,
|
||||
EtherCAT_device_t *device)
|
||||
{
|
||||
if (master->dev != device)
|
||||
{
|
||||
printk(KERN_WARNING "EtherCAT: Trying to unregister unknown device.\n");
|
||||
printk(KERN_WARNING "EtherCAT: Trying to close an unknown device!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1138,8 +1138,8 @@ void output_debug_data(const EtherCAT_master_t *master)
|
|||
|
||||
EXPORT_SYMBOL(EtherCAT_master_init);
|
||||
EXPORT_SYMBOL(EtherCAT_master_clear);
|
||||
EXPORT_SYMBOL(EtherCAT_register_device);
|
||||
EXPORT_SYMBOL(EtherCAT_unregister_device);
|
||||
EXPORT_SYMBOL(EtherCAT_master_open);
|
||||
EXPORT_SYMBOL(EtherCAT_master_close);
|
||||
EXPORT_SYMBOL(EtherCAT_read_process_data);
|
||||
EXPORT_SYMBOL(EtherCAT_write_process_data);
|
||||
EXPORT_SYMBOL(EtherCAT_check_slaves);
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ void EtherCAT_master_init(EtherCAT_master_t *);
|
|||
void EtherCAT_master_clear(EtherCAT_master_t *);
|
||||
|
||||
// Registration of devices
|
||||
int EtherCAT_register_device(EtherCAT_master_t *, EtherCAT_device_t *);
|
||||
void EtherCAT_unregister_device(EtherCAT_master_t *, EtherCAT_device_t *);
|
||||
int EtherCAT_master_open(EtherCAT_master_t *, EtherCAT_device_t *);
|
||||
void EtherCAT_master_close(EtherCAT_master_t *, EtherCAT_device_t *);
|
||||
|
||||
// Sending and receiving
|
||||
int EtherCAT_simple_send_receive(EtherCAT_master_t *, EtherCAT_command_t *);
|
||||
|
|
|
|||
|
|
@ -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_PARM_DESC(ecat_master_count, "Number of EtherCAT master to initialize.");
|
|||
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 @@ int __init ecat_init_module(void)
|
|||
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 @@ void __exit ecat_cleanup_module(void)
|
|||
{
|
||||
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 @@ void __exit ecat_cleanup_module(void)
|
|||
printk(KERN_ERR "EtherCAT: Master driver cleaned up.\n");
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
/**
|
||||
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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
Gibt einen Zeiger auf einen bestimmten EtherCAT-Master zurueck.
|
||||
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)
|
||||
EtherCAT_master_t *EtherCAT_request(int index)
|
||||
{
|
||||
if (index < 0 || index >= ecat_master_count)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@
|
|||
int __init ecat_init_module(void);
|
||||
void __exit ecat_cleanup_module(void);
|
||||
|
||||
EtherCAT_master_t *EtherCAT_master(int);
|
||||
// Registration of devices
|
||||
int EtherCAT_register_device(int, EtherCAT_device_t *);
|
||||
void EtherCAT_unregister_device(int, EtherCAT_device_t *);
|
||||
|
||||
EtherCAT_master_t *EtherCAT_request(int);
|
||||
void EtherCAT_release(EtherCAT_master_t *);
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -230,9 +230,9 @@ int __init init_module()
|
|||
{
|
||||
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
|
||||
|
||||
if ((ecat_master = EtherCAT_master(0)) == NULL)
|
||||
if ((ecat_master = EtherCAT_request(0)) == NULL)
|
||||
{
|
||||
printk(KERN_ERR "No EtherCAT master available!\n");
|
||||
printk(KERN_ERR "EtherCAT master 0 not available!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +290,8 @@ void __exit cleanup_module()
|
|||
|
||||
printk(KERN_INFO "Deactivating slaves.\n");
|
||||
EtherCAT_deactivate_all_slaves(ecat_master);
|
||||
|
||||
EtherCAT_release(ecat_master);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n");
|
||||
|
|
|
|||
|
|
@ -399,9 +399,9 @@ int __init init_module()
|
|||
msr_jitter_init();
|
||||
printk(KERN_INFO "=== Starting EtherCAT environment... ===\n");
|
||||
|
||||
if ((ecat_master = EtherCAT_master(0)) == NULL)
|
||||
if ((ecat_master = EtherCAT_request(0)) == NULL)
|
||||
{
|
||||
printk(KERN_ERR "No EtherCAT master available!\n");
|
||||
printk(KERN_ERR "EtherCAT master 0 not available!\n");
|
||||
msr_rtlib_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -469,6 +469,8 @@ void __exit cleanup_module()
|
|||
EtherCAT_clear_process_data(ecat_master);
|
||||
printk(KERN_INFO "Deactivating slaves.\n");
|
||||
EtherCAT_deactivate_all_slaves(ecat_master);
|
||||
|
||||
EtherCAT_release(ecat_master);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue