This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / s390 / net / iucv.c
index 8c63753..36790af 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * $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
  *
@@ -29,7 +29,7 @@
  * 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
@@ -53,7 +53,6 @@
 #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:
@@ -178,11 +177,9 @@ static handler **iucv_pathid_table;
 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
  */
@@ -355,7 +352,7 @@ do { \
 static void
 iucv_banner(void)
 {
-       char vbuf[] = "$Revision: 1.40 $";
+       char vbuf[] = "$Revision: 1.33 $";
        char *version = vbuf;
 
        if ((version = strchr(version, ':'))) {
@@ -387,7 +384,7 @@ iucv_init(void)
        }
 
        ret = bus_register(&iucv_bus);
-       if (ret) {
+       if (ret != 0) {
                printk(KERN_ERR "IUCV: failed to register bus.\n");
                return ret;
        }
@@ -528,7 +525,7 @@ iucv_add_handler (handler *new)
                 */
                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;
@@ -634,15 +631,17 @@ iucv_remove_pathid(__u16 pathid)
 }
 
 /**
- * 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)
@@ -651,16 +650,17 @@ iucv_declare_buffer_cpuid (void *result)
 }
 
 /**
- * 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);
@@ -676,27 +676,18 @@ iucv_retrieve_buffer_cpuid (void *cpu)
 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;
 }
@@ -711,12 +702,14 @@ static int
 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;
@@ -869,33 +862,40 @@ iucv_register_program (__u8 pgmname[16],
                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) {
@@ -1045,7 +1045,7 @@ iucv_accept(__u16 pathid, __u16 msglim_reqstd,
        parm->ipflags1 = (__u8)flags1;
        b2f0_result = b2f0(ACCEPT, parm);
 
-       if (!b2f0_result) {
+       if (b2f0_result == 0) {
                if (msglim)
                        *msglim = parm->ipmsglim;
                if (pgm_data)
@@ -1185,7 +1185,7 @@ iucv_connect (__u16 *pathid, __u16 msglim_reqstd,
        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);
 
@@ -1245,7 +1245,7 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
        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;
@@ -1409,7 +1409,7 @@ iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls,
 
        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));
@@ -1499,7 +1499,7 @@ iucv_receive_array (__u16 pathid,
 
        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);
@@ -1546,7 +1546,7 @@ iucv_receive_array (__u16 pathid,
                                *residual_length = abs (buflen - 8);
 
                        if (residual_buffer) {
-                               if (!moved)
+                               if (moved == 0)
                                        *residual_buffer = (ulong) buffer;
                                else
                                        *residual_buffer =
@@ -1648,7 +1648,7 @@ iucv_reply (__u16 pathid,
 
        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)
@@ -1714,7 +1714,7 @@ iucv_reply_array (__u16 pathid,
 
        b2f0_result = b2f0(REPLY, parm);
 
-       if ((!b2f0_result) || (b2f0_result == 5)) {
+       if ((b2f0_result == 0) || (b2f0_result == 5)) {
 
                if (ipbfadr2)
                        *ipbfadr2 = parm->ipbfadr2;
@@ -1840,7 +1840,7 @@ iucv_send (__u16 pathid, __u32 * msgid,
 
        b2f0_result = b2f0(SEND, parm);
 
-       if ((!b2f0_result) && (msgid))
+       if ((b2f0_result == 0) && (msgid))
                *msgid = parm->ipmsgid;
        release_param(parm);
 
@@ -1894,7 +1894,7 @@ iucv_send_array (__u16 pathid,
        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);
 
@@ -1940,7 +1940,7 @@ iucv_send_prmmsg (__u16 pathid,
 
        b2f0_result = b2f0(SEND, parm);
 
-       if ((!b2f0_result) && (msgid))
+       if ((b2f0_result == 0) && (msgid))
                *msgid = parm->ipmsgid;
        release_param(parm);
 
@@ -2001,7 +2001,7 @@ iucv_send2way (__u16 pathid,
 
        b2f0_result = b2f0(SEND, parm);
 
-       if ((!b2f0_result) && (msgid))
+       if ((b2f0_result == 0) && (msgid))
                *msgid = parm->ipmsgid;
        release_param(parm);
 
@@ -2062,7 +2062,7 @@ iucv_send2way_array (__u16 pathid,
        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);
 
@@ -2120,7 +2120,7 @@ iucv_send2way_prmmsg (__u16 pathid,
 
        b2f0_result = b2f0(SEND, parm);
 
-       if ((!b2f0_result) && (msgid))
+       if ((b2f0_result == 0) && (msgid))
                *msgid = parm->ipmsgid;
        release_param(parm);
 
@@ -2181,7 +2181,7 @@ iucv_send2way_prmmsg_array (__u16 pathid,
        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);
 
@@ -2190,10 +2190,13 @@ iucv_send2way_prmmsg_array (__u16 pathid,
 }
 
 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);
@@ -2225,12 +2228,14 @@ iucv_setmask (int SetMaskFlag)
                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;
 }
@@ -2358,7 +2363,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                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");