/*
*
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.121 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.125 $)
*
* Linux on zSeries OSA Express and HiperSockets support
*
* Frank Pavlic (pavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com>
*
- * $Revision: 1.121 $ $Date: 2004/06/11 16:32:15 $
+ * $Revision: 1.125 $ $Date: 2004/06/29 17:28:24 $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "qeth_mpc.h"
#include "qeth_fs.h"
-#define VERSION_QETH_C "$Revision: 1.121 $"
+#define VERSION_QETH_C "$Revision: 1.125 $"
static const char *version = "qeth S/390 OSA-Express driver";
/**
static void qeth_add_multicast_ipv6(struct qeth_card *);
#endif
-static void
+static inline int
qeth_set_thread_start_bit(struct qeth_card *card, unsigned long thread)
{
unsigned long flags;
spin_lock_irqsave(&card->thread_mask_lock, flags);
+ if ( !(card->thread_allowed_mask & thread) ||
+ (card->thread_start_mask & thread) ) {
+ spin_unlock_irqrestore(&card->thread_mask_lock, flags);
+ return -EPERM;
+ }
card->thread_start_mask |= thread;
spin_unlock_irqrestore(&card->thread_mask_lock, flags);
+ return 0;
}
static void
{
QETH_DBF_TEXT(trace,2,"startrec");
- qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
}
static int
QETH_DBF_TEXT(trace, 2, "rstipadd");
qeth_clear_ip_list(card, 0, 1);
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if ( (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) ||
+ (qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD) == 0) )
+ schedule_work(&card->kernel_thread_starter);
}
static struct qeth_ipa_cmd *
if (card->vlangrp)
card->vlangrp->vlan_devices[vid] = NULL;
spin_unlock_irqrestore(&card->vlanlock, flags);
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- /* delete mc addresses for this vlan dev */
- qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if ( (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) ||
+ (qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD) == 0) )
+ schedule_work(&card->kernel_thread_starter);
}
#endif
QETH_DBF_TEXT(trace,3,"setmulti");
card = (struct qeth_card *) dev->priv;
- qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
}
static void
rtnl_lock();
dev_open(card->dev);
rtnl_unlock();
- qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_MC_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
}
static int
}
if (!qeth_add_ip(card, ipaddr))
kfree(ipaddr);
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
return rc;
}
return;
if (!qeth_delete_ip(card, ipaddr))
kfree(ipaddr);
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
}
/*
}
if (!qeth_add_ip(card, ipaddr))
kfree(ipaddr);
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
return 0;
}
return;
if (!qeth_delete_ip(card, ipaddr))
kfree(ipaddr);
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
}
/**
default:
break;
}
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
out:
return NOTIFY_DONE;
}
default:
break;
}
- qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD);
- schedule_work(&card->kernel_thread_starter);
+ if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
+ schedule_work(&card->kernel_thread_starter);
out:
return NOTIFY_DONE;
}