/*
- * $Id: iucv.c,v 1.40 2004/08/04 12:29:33 cborntra Exp $
+ * $Id: iucv.c,v 1.33 2004/05/24 10:19:18 braunu Exp $
*
* IUCV network driver
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.40 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.33 $
*
*/
\f
#include <asm/io.h>
#include <asm/s390_ext.h>
#include <asm/ebcdic.h>
-#include <asm/smp.h>
#include <asm/ccwdev.h> //for root device stuff
/* FLAGS:
static unsigned long max_connections;
/**
- * iucv_cpuid: contains the logical cpu number of the cpu which
- * has declared the iucv buffer by issuing DECLARE_BUFFER.
- * If no cpu has done the initialization iucv_cpuid contains -1.
+ * declare_flag: is 0 when iucv_declare_buffer has not been called
*/
-static int iucv_cpuid = -1;
+static int declare_flag;
/**
* register_flag: is 0 when external interrupt has not been registered
*/
static void
iucv_banner(void)
{
- char vbuf[] = "$Revision: 1.40 $";
+ char vbuf[] = "$Revision: 1.33 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
}
ret = bus_register(&iucv_bus);
- if (ret) {
+ if (ret != 0) {
printk(KERN_ERR "IUCV: failed to register bus.\n");
return ret;
}
*/
list_for_each(lh, &iucv_handler_table) {
handler *h = list_entry(lh, handler, list);
- if (!memcmp(&new->id, &h->id, sizeof(h->id))) {
+ if (memcmp(&new->id, &h->id, sizeof(h->id)) == 0) {
iucv_debug(1, "ret 1");
spin_unlock_irqrestore (&iucv_lock, flags);
return 1;
}
/**
- * iucv_declare_buffer_cpuid
- * Register at VM for subsequent IUCV operations. This is executed
- * on the reserved CPU iucv_cpuid. Called from iucv_declare_buffer().
+ * iucv_declare_buffer_cpu0
+ * Register at VM for subsequent IUCV operations. This is always
+ * executed on CPU 0. Called from iucv_declare_buffer().
*/
static void
-iucv_declare_buffer_cpuid (void *result)
+iucv_declare_buffer_cpu0 (void *result)
{
iparml_db *parm;
+ if (!(result && (smp_processor_id() == 0)))
+ return;
parm = (iparml_db *)grab_param();
parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer);
if ((*((ulong *)result) = b2f0(DECLARE_BUFFER, parm)) == 1)
}
/**
- * iucv_retrieve_buffer_cpuid:
- * Unregister IUCV usage at VM. This is always executed on the same
- * cpu that registered the buffer to VM.
+ * iucv_retrieve_buffer_cpu0:
+ * Unregister IUCV usage at VM. This is always executed on CPU 0.
* Called from iucv_retrieve_buffer().
*/
static void
-iucv_retrieve_buffer_cpuid (void *cpu)
+iucv_retrieve_buffer_cpu0 (void *result)
{
iparml_control *parm;
+ if (smp_processor_id() != 0)
+ return;
parm = (iparml_control *)grab_param();
b2f0(RETRIEVE_BUFFER, parm);
release_param(parm);
static int
iucv_declare_buffer (void)
{
- unsigned long flags;
- ulong b2f0_result;
+ ulong b2f0_result = 0x0deadbeef;
iucv_debug(1, "entering");
- b2f0_result = -ENODEV;
- spin_lock_irqsave (&iucv_lock, flags);
- if (iucv_cpuid == -1) {
- /* Reserve any cpu for use by iucv. */
- iucv_cpuid = smp_get_cpu(CPU_MASK_ALL);
- spin_unlock_irqrestore (&iucv_lock, flags);
- smp_call_function_on(iucv_declare_buffer_cpuid,
- &b2f0_result, 0, 1, iucv_cpuid);
- if (b2f0_result) {
- smp_put_cpu(iucv_cpuid);
- iucv_cpuid = -1;
- }
- iucv_debug(1, "Address of EIB = %p", iucv_external_int_buffer);
- } else {
- spin_unlock_irqrestore (&iucv_lock, flags);
- b2f0_result = 0;
- }
+ preempt_disable();
+ if (smp_processor_id() == 0)
+ iucv_declare_buffer_cpu0(&b2f0_result);
+ else
+ smp_call_function(iucv_declare_buffer_cpu0, &b2f0_result, 0, 1);
+ preempt_enable();
+ iucv_debug(1, "Address of EIB = %p", iucv_external_int_buffer);
+ if (b2f0_result == 0x0deadbeef)
+ b2f0_result = 0xaa;
iucv_debug(1, "exiting");
return b2f0_result;
}
iucv_retrieve_buffer (void)
{
iucv_debug(1, "entering");
- if (iucv_cpuid != -1) {
- smp_call_function_on(iucv_retrieve_buffer_cpuid,
- 0, 0, 1, iucv_cpuid);
- /* Release the cpu reserved by iucv_declare_buffer. */
- smp_put_cpu(iucv_cpuid);
- iucv_cpuid = -1;
+ if (declare_flag) {
+ preempt_disable();
+ if (smp_processor_id() == 0)
+ iucv_retrieve_buffer_cpu0(0);
+ else
+ smp_call_function(iucv_retrieve_buffer_cpu0, 0, 0, 1);
+ declare_flag = 0;
+ preempt_enable();
}
iucv_debug(1, "exiting");
return 0;
return NULL;
}
- rc = iucv_declare_buffer();
- if (rc) {
- char *err = "Unknown";
- iucv_remove_handler(new_handler);
- kfree(new_handler);
- switch(rc) {
- case 0x03:
- err = "Directory error";
- break;
- case 0x0a:
- err = "Invalid length";
- break;
- case 0x13:
- err = "Buffer already exists";
- break;
- case 0x3e:
- err = "Buffer overlap";
- break;
- case 0x5c:
- err = "Paging or storage error";
- break;
+ if (declare_flag == 0) {
+ rc = iucv_declare_buffer();
+ if (rc) {
+ char *err = "Unknown";
+ iucv_remove_handler(new_handler);
+ kfree(new_handler);
+ switch(rc) {
+ case 0x03:
+ err = "Directory error";
+ break;
+ case 0x0a:
+ err = "Invalid length";
+ break;
+ case 0x13:
+ err = "Buffer already exists";
+ break;
+ case 0x3e:
+ err = "Buffer overlap";
+ break;
+ case 0x5c:
+ err = "Paging or storage error";
+ break;
+ case 0xaa:
+ err = "Function not called";
+ break;
+ }
+ printk(KERN_WARNING "%s: iucv_declare_buffer "
+ "returned error 0x%02lx (%s)\n", __FUNCTION__, rc,
+ err);
+ return NULL;
}
- printk(KERN_WARNING "%s: iucv_declare_buffer "
- "returned error 0x%02lx (%s)\n", __FUNCTION__, rc, err);
- return NULL;
+ declare_flag = 1;
}
- if (!register_flag) {
+ if (register_flag == 0) {
/* request the 0x4000 external interrupt */
rc = register_external_interrupt (0x4000, iucv_irq_handler);
if (rc) {
parm->ipflags1 = (__u8)flags1;
b2f0_result = b2f0(ACCEPT, parm);
- if (!b2f0_result) {
+ if (b2f0_result == 0) {
if (msglim)
*msglim = parm->ipmsglim;
if (pgm_data)
memcpy(&local_parm, parm, sizeof(local_parm));
release_param(parm);
parm = &local_parm;
- if (!b2f0_result)
+ if (b2f0_result == 0)
add_pathid_result = __iucv_add_pathid(parm->ippathid, h);
spin_unlock_irqrestore (&iucv_lock, flags);
parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID);
b2f0_result = b2f0(PURGE, parm);
- if (!b2f0_result && audit) {
+ if ((b2f0_result == 0) && audit) {
memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit));
/* parm->ipaudit has only 3 bytes */
*audit >>= 8;
b2f0_result = b2f0(RECEIVE, parm);
- if (!b2f0_result || b2f0_result == 5) {
+ if (b2f0_result == 0 || b2f0_result == 5) {
if (flags1_out) {
iucv_debug(2, "*flags1_out = %d", *flags1_out);
*flags1_out = (parm->ipflags1 & (~0x07));
b2f0_result = b2f0(RECEIVE, parm);
- if (!b2f0_result || b2f0_result == 5) {
+ if (b2f0_result == 0 || b2f0_result == 5) {
if (flags1_out) {
iucv_debug(2, "*flags1_out = %d", *flags1_out);
*residual_length = abs (buflen - 8);
if (residual_buffer) {
- if (!moved)
+ if (moved == 0)
*residual_buffer = (ulong) buffer;
else
*residual_buffer =
b2f0_result = b2f0(REPLY, parm);
- if ((!b2f0_result) || (b2f0_result == 5)) {
+ if ((b2f0_result == 0) || (b2f0_result == 5)) {
if (ipbfadr2)
*ipbfadr2 = parm->ipbfadr2;
if (ipbfln2f)
b2f0_result = b2f0(REPLY, parm);
- if ((!b2f0_result) || (b2f0_result == 5)) {
+ if ((b2f0_result == 0) || (b2f0_result == 5)) {
if (ipbfadr2)
*ipbfadr2 = parm->ipbfadr2;
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
parm->ipflags1 = (IPNORPY | IPBUFLST | flags1);
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
parm->ipmsgtag = msgtag;
parm->ipflags1 = (IPBUFLST | IPANSLST | flags1);
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
parm->ipflags1 = (IPRMDATA | IPANSLST | flags1);
memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));
b2f0_result = b2f0(SEND, parm);
- if ((!b2f0_result) && (msgid))
+ if ((b2f0_result == 0) && (msgid))
*msgid = parm->ipmsgid;
release_param(parm);
}
void
-iucv_setmask_cpuid (void *result)
+iucv_setmask_cpu0 (void *result)
{
iparml_set_mask *parm;
+ if (smp_processor_id() != 0)
+ return;
+
iucv_debug(1, "entering");
parm = (iparml_set_mask *)grab_param();
parm->ipmask = *((__u8*)result);
ulong result;
__u8 param;
} u;
- int cpu;
u.param = SetMaskFlag;
- cpu = get_cpu();
- smp_call_function_on(iucv_setmask_cpuid, &u, 0, 1, iucv_cpuid);
- put_cpu();
+ preempt_disable();
+ if (smp_processor_id() == 0)
+ iucv_setmask_cpu0(&u);
+ else
+ smp_call_function(iucv_setmask_cpu0, &u, 0, 1);
+ preempt_enable();
return u.result;
}
iucv_dumpit("temp_buff2",
temp_buff2, sizeof(temp_buff2));
- if (!memcmp (temp_buff1, temp_buff2, 24)) {
+ if (memcmp (temp_buff1, temp_buff2, 24) == 0) {
iucv_debug(2,
"found a matching handler");