fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / s390 / net / iucv.c
index 760e77e..229aeb5 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * IUCV network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-\f
+
 /* #define DEBUG */
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/config.h>
 
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
@@ -81,7 +80,7 @@ iucv_bus_match (struct device *dev, struct device_driver *drv)
 struct bus_type iucv_bus = {
        .name = "iucv",
        .match = iucv_bus_match,
-};     
+};
 
 struct device *iucv_root;
 
@@ -117,7 +116,7 @@ static DEFINE_SPINLOCK(iucv_irq_queue_lock);
  *Internal function prototypes
  */
 static void iucv_tasklet_handler(unsigned long);
-static void iucv_irq_handler(struct pt_regs *, __u16);
+static void iucv_irq_handler(__u16);
 
 static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0);
 
@@ -297,7 +296,7 @@ MODULE_LICENSE("GPL");
 /*
  * Debugging stuff
  *******************************************************************************/
-\f
+
 
 #ifdef DEBUG
 static int debuglevel = 0;
@@ -336,15 +335,15 @@ do { \
 
 #else
 
-#define iucv_debug(lvl, fmt, args...)
-#define iucv_dumpit(title, buf, len)
+#define iucv_debug(lvl, fmt, args...)  do { } while (0)
+#define iucv_dumpit(title, buf, len)   do { } while (0)
 
 #endif
 
 /*
  * Internal functions
  *******************************************************************************/
-\f
+
 /**
  * print start banner
  */
@@ -386,7 +385,7 @@ iucv_init(void)
        }
 
        /* Note: GFP_DMA used used to get memory below 2G */
-       iucv_external_int_buffer = kmalloc(sizeof(iucv_GeneralInterrupt),
+       iucv_external_int_buffer = kzalloc(sizeof(iucv_GeneralInterrupt),
                                           GFP_KERNEL|GFP_DMA);
        if (!iucv_external_int_buffer) {
                printk(KERN_WARNING
@@ -396,10 +395,9 @@ iucv_init(void)
                bus_unregister(&iucv_bus);
                return -ENOMEM;
        }
-       memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt));
 
        /* Initialize parameter pool */
-       iucv_param_pool = kmalloc(sizeof(iucv_param) * PARAM_POOL_SIZE,
+       iucv_param_pool = kzalloc(sizeof(iucv_param) * PARAM_POOL_SIZE,
                                  GFP_KERNEL|GFP_DMA);
        if (!iucv_param_pool) {
                printk(KERN_WARNING "%s: Could not allocate param pool\n",
@@ -410,7 +408,6 @@ iucv_init(void)
                bus_unregister(&iucv_bus);
                return -ENOMEM;
        }
-       memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);
 
        /* Initialize irq queue */
        INIT_LIST_HEAD(&iucv_irq_queue);
@@ -537,19 +534,15 @@ iucv_add_handler (handler *new)
  *
  * Returns: return code from CP's IUCV call
  */
-static __inline__ ulong
-b2f0(__u32 code, void *parm)
+static inline ulong b2f0(__u32 code, void *parm)
 {
+       register unsigned long reg0 asm ("0");
+       register unsigned long reg1 asm ("1");
        iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));
 
-       asm volatile (
-               "LRA   1,0(%1)\n\t"
-               "LR    0,%0\n\t"
-               ".long 0xb2f01000"
-               :
-               : "d" (code), "a" (parm)
-               : "0", "1"
-               );
+       reg0 = code;
+       reg1 = virt_to_phys(parm);
+       asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1));
 
        iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param));
 
@@ -695,7 +688,7 @@ 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);
+                                    NULL, 0, 1, iucv_cpuid);
                /* Release the cpu reserved by iucv_declare_buffer. */
                smp_put_cpu(iucv_cpuid);
                iucv_cpuid = -1;
@@ -779,7 +772,7 @@ iucv_register_program (__u8 pgmname[16],
        }
 
        /* Allocate handler entry */
-       new_handler = (handler *)kmalloc(sizeof(handler), GFP_ATOMIC);
+       new_handler = kmalloc(sizeof(handler), GFP_ATOMIC);
        if (new_handler == NULL) {
                printk(KERN_WARNING "%s: storage allocation for new handler "
                       "failed.\n", __FUNCTION__);
@@ -793,15 +786,14 @@ iucv_register_program (__u8 pgmname[16],
                }
 
                max_connections = iucv_query_maxconn();
-               iucv_pathid_table = kmalloc(max_connections * sizeof(handler *),
-                                      GFP_ATOMIC);
+               iucv_pathid_table = kcalloc(max_connections, sizeof(handler *),
+                                       GFP_ATOMIC);
                if (iucv_pathid_table == NULL) {
                        printk(KERN_WARNING "%s: iucv_pathid_table storage "
                               "allocation failed\n", __FUNCTION__);
                        kfree(new_handler);
                        return NULL;
                }
-               memset (iucv_pathid_table, 0, max_connections * sizeof(handler *));
        }
        memset(new_handler, 0, sizeof (handler));
        memcpy(new_handler->id.user_data, pgmname,
@@ -813,7 +805,7 @@ iucv_register_program (__u8 pgmname[16],
                        sizeof (new_handler->id.userid));
                EBC_TOUPPER (new_handler->id.userid,
                             sizeof (new_handler->id.userid));
-               
+
                if (pgmmask) {
                        memcpy (new_handler->id.mask, pgmmask,
                                sizeof (new_handler->id.mask));
@@ -1232,7 +1224,7 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
                /* parm->ipaudit has only 3 bytes */
                *audit >>= 8;
        }
-       
+
        release_param(parm);
 
        iucv_debug(1, "b2f0_result = %ld", b2f0_result);
@@ -1252,6 +1244,8 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
 static int
 iucv_query_generic(int want_maxconn)
 {
+       register unsigned long reg0 asm ("0");
+       register unsigned long reg1 asm ("1");
        iparml_purge *parm = (iparml_purge *)grab_param();
        int bufsize, maxconn;
        int ccode;
@@ -1260,18 +1254,15 @@ iucv_query_generic(int want_maxconn)
         * Call b2f0 and store R0 (max buffer size),
         * R1 (max connections) and CC.
         */
-       asm volatile (
-               "LRA   1,0(%4)\n\t"
-               "LR    0,%3\n\t"
-               ".long 0xb2f01000\n\t"
-               "IPM   %0\n\t"
-               "SRL   %0,28\n\t"
-               "ST    0,%1\n\t"
-               "ST    1,%2\n\t"
-               : "=d" (ccode), "=m" (bufsize), "=m" (maxconn)
-               : "d" (QUERY), "a" (parm)
-               : "0", "1", "cc"
-               );
+       reg0 = QUERY;
+       reg1 = virt_to_phys(parm);
+       asm volatile(
+               "       .long   0xb2f01000\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
+               : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
+       bufsize = reg0;
+       maxconn = reg1;
        release_param(parm);
 
        if (ccode)
@@ -2260,7 +2251,7 @@ iucv_sever(__u16 pathid, __u8 user_data[16])
  * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler().
  */
 static void
-iucv_irq_handler(struct pt_regs *regs, __u16 code)
+iucv_irq_handler(__u16 code)
 {
        iucv_irqdata *irqdata;
 
@@ -2333,14 +2324,14 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                        temp_buff1[j] &= (h->id.mask)[j];
                                        temp_buff2[j] &= (h->id.mask)[j];
                                }
-                               
+
                                iucv_dumpit("temp_buff1:",
                                            temp_buff1, sizeof(temp_buff1));
                                iucv_dumpit("temp_buff2",
                                            temp_buff2, sizeof(temp_buff2));
-                               
+
                                if (!memcmp (temp_buff1, temp_buff2, 24)) {
-                                       
+
                                        iucv_debug(2,
                                                   "found a matching handler");
                                        break;
@@ -2371,7 +2362,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                        } else
                                iucv_sever(int_buf->ippathid, no_listener);
                        break;
-                       
+
                case 0x02:              /*connection complete */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2390,7 +2381,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                        } else
                                iucv_sever(int_buf->ippathid, no_listener);
                        break;
-                       
+
                case 0x03:              /* connection severed */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2401,13 +2392,13 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                        interrupt->ConnectionSevered(
                                                (iucv_ConnectionSevered *)int_buf,
                                                h->pgm_data);
-                               
+
                                else
                                        iucv_sever (int_buf->ippathid, no_listener);
                        } else
                                iucv_sever(int_buf->ippathid, no_listener);
                        break;
-                       
+
                case 0x04:              /* connection quiesced */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2423,7 +2414,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                                   "ConnectionQuiesced not called");
                        }
                        break;
-                       
+
                case 0x05:              /* connection resumed */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2439,7 +2430,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                                   "ConnectionResumed not called");
                        }
                        break;
-                       
+
                case 0x06:              /* priority message complete */
                case 0x07:              /* nonpriority message complete */
                        if (h) {
@@ -2452,7 +2443,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                                   "MessageComplete not called");
                        }
                        break;
-                       
+
                case 0x08:              /* priority message pending  */
                case 0x09:              /* nonpriority message pending  */
                        if (h) {
@@ -2470,7 +2461,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                               __FUNCTION__);
                        break;
        }                       /* end switch */
-       
+
        iucv_debug(2, "exiting pathid %d, type %02X",
                 int_buf->ippathid, int_buf->iptype);