X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fnet%2Fiucv.c;h=229aeb5fc399b79cf34bd4c5a68f174e16c58b68;hb=refs%2Fheads%2Fvserver;hp=8c63753c35e669cd4f2d44fc835a3c97c95f5732;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index 8c63753c3..229aeb5fc 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c @@ -1,6 +1,4 @@ -/* - * $Id: iucv.c,v 1.40 2004/08/04 12:29:33 cborntra Exp $ - * +/* * IUCV network driver * * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation @@ -29,15 +27,12 @@ * 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 $ - * */ - + /* #define DEBUG */ #include #include -#include #include #include @@ -54,7 +49,7 @@ #include #include #include -#include //for root device stuff +#include /* FLAGS: * All flags are defined in the field IPFLAGS1 of each function @@ -85,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; @@ -103,7 +98,7 @@ static iucv_GeneralInterrupt *iucv_external_int_buffer = NULL; /* Spin Lock declaration */ -static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(iucv_lock); static int messagesDisabled = 0; @@ -115,13 +110,13 @@ typedef struct { } iucv_irqdata; static struct list_head iucv_irq_queue; -static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED; +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); @@ -301,7 +296,7 @@ MODULE_LICENSE("GPL"); /* * Debugging stuff *******************************************************************************/ - + #ifdef DEBUG static int debuglevel = 0; @@ -340,32 +335,22 @@ 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 *******************************************************************************/ - + /** * print start banner */ static void iucv_banner(void) { - char vbuf[] = "$Revision: 1.40 $"; - char *version = vbuf; - - if ((version = strchr(version, ':'))) { - char *p = strchr(version + 1, '$'); - if (p) - *p = '\0'; - } else - version = " ??? "; - printk(KERN_INFO - "IUCV lowlevel driver Version%s initialized\n", version); + printk(KERN_INFO "IUCV lowlevel driver initialized\n"); } /** @@ -400,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 @@ -410,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", @@ -424,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); @@ -447,14 +430,10 @@ static void iucv_exit(void) { iucv_retrieve_buffer(); - if (iucv_external_int_buffer) { - kfree(iucv_external_int_buffer); - iucv_external_int_buffer = NULL; - } - if (iucv_param_pool) { - kfree(iucv_param_pool); - iucv_param_pool = NULL; - } + kfree(iucv_external_int_buffer); + iucv_external_int_buffer = NULL; + kfree(iucv_param_pool); + iucv_param_pool = NULL; s390_root_dev_unregister(iucv_root); bus_unregister(&iucv_bus); printk(KERN_INFO "IUCV lowlevel driver unloaded\n"); @@ -481,7 +460,7 @@ grab_param(void) ptr++; if (ptr >= iucv_param_pool + PARAM_POOL_SIZE) ptr = iucv_param_pool; - } while (atomic_compare_and_swap(0, 1, &ptr->in_use)); + } while (atomic_cmpxchg(&ptr->in_use, 0, 1) != 0); hint = ptr - iucv_param_pool; memset(&ptr->param, 0, sizeof(ptr->param)); @@ -555,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)); @@ -713,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; @@ -797,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__); @@ -811,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, @@ -831,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)); @@ -1250,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); @@ -1270,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; @@ -1278,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) @@ -2278,14 +2251,13 @@ 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; irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC); if (!irqdata) { printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); - irq_exit(); return; } @@ -2352,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; @@ -2390,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); @@ -2409,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); @@ -2420,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); @@ -2442,7 +2414,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf) "ConnectionQuiesced not called"); } break; - + case 0x05: /* connection resumed */ if (messagesDisabled) { iucv_setmask(~0); @@ -2458,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) { @@ -2471,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) { @@ -2489,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); @@ -2526,7 +2498,7 @@ iucv_tasklet_handler(unsigned long ignored) return; } -module_init(iucv_init); +subsys_initcall(iucv_init); module_exit(iucv_exit); /** @@ -2550,16 +2522,16 @@ EXPORT_SYMBOL (iucv_reject); #if 0 EXPORT_SYMBOL (iucv_reply); EXPORT_SYMBOL (iucv_reply_array); -EXPORT_SYMBOL (iucv_reply_prmmsg); EXPORT_SYMBOL (iucv_resume); #endif +EXPORT_SYMBOL (iucv_reply_prmmsg); EXPORT_SYMBOL (iucv_send); -#if 0 EXPORT_SYMBOL (iucv_send2way); EXPORT_SYMBOL (iucv_send2way_array); -EXPORT_SYMBOL (iucv_send_array); EXPORT_SYMBOL (iucv_send2way_prmmsg); EXPORT_SYMBOL (iucv_send2way_prmmsg_array); +#if 0 +EXPORT_SYMBOL (iucv_send_array); EXPORT_SYMBOL (iucv_send_prmmsg); EXPORT_SYMBOL (iucv_setmask); #endif