⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iucv.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * $Id$ * * IUCV network driver * * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): *    Original source: *      Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 2000 *      Xenia Tkatschow (xenia@us.ibm.com) *    2Gb awareness and general cleanup: *      Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) * * Documentation used: *    The original source *    CP Programming Service, IBM document # SC24-5760 * * 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 * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * 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$ * */#include <linux/module.h>#include <linux/config.h>#include <linux/version.h>#include <linux/spinlock.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/tqueue.h>#include <linux/interrupt.h>#include <linux/list.h>#include <asm/atomic.h>#include "iucv.h"#include <asm/io.h>#include <asm/irq.h>#include <asm/s390_ext.h>#include <asm/ebcdic.h>#undef DEBUG/* FLAGS: * All flags are defined in the field IPFLAGS1 of each function * and can be found in CP Programming Services. * IPSRCCLS - Indicates you have specified a source class * IPFGMCL  - Indicates you have specified a target class * IPFGPID  - Indicates you have specified a pathid * IPFGMID  - Indicates you have specified a message ID * IPANSLST - Indicates that you are using an address list for *            reply data * IPBUFLST - Indicates that you are using an address list for *            message data */#define IPSRCCLS 	0x01#define IPFGMCL         0x01#define IPFGPID         0x02#define IPFGMID         0x04#define IPANSLST        0x08#define IPBUFLST        0x40/* General IUCV interrupt structure */typedef struct {	__u16 ippathid;	__u8  res1;	__u8  iptype;	__u32 res2;	__u8  ipvmid[8];	__u8  res3[24];} iucv_GeneralInterrupt;static iucv_GeneralInterrupt *iucv_external_int_buffer;/* Spin Lock declaration */static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED;/***************INTERRUPT HANDLING ***************/typedef struct {	struct list_head queue;	iucv_GeneralInterrupt data;} iucv_irqdata;struct list_head  iucv_irq_queue;static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED;struct tq_struct  iucv_tq;static atomic_t   iucv_bh_scheduled = ATOMIC_INIT (0);/* *Internal function prototypes */static void iucv_bh_handler(void);static void iucv_irq_handler(struct pt_regs *, __u16);/************ FUNCTION ID'S ****************************/#define ACCEPT          10#define CONNECT         11#define DECLARE_BUFFER  12#define PURGE           9#define QUERY           0#define QUIESCE         13#define RECEIVE         5#define REJECT          8#define REPLY           6#define RESUME          14#define RETRIEVE_BUFFER 2#define SEND            4#define SETMASK         16#define SEVER           15/** * Structure: handler * members: list - list management. *          structure: id *             userid - 8 char array of machine identification *             user_data - 16 char array for user identification *             mask - 24 char array used to compare the 2 previous *          interrupt_table - vector of interrupt functions. *          pgm_data -  ulong, application data that is passed *                      to the interrupt handlers*/typedef struct handler_t {	struct list_head list;	struct {		__u8 userid[8];		__u8 user_data[16];		__u8 mask[24];	}                    id;	iucv_interrupt_ops_t *interrupt_table;	void                 *pgm_data;} handler;/** * iucv_handler_table: List of registered handlers. */static struct list_head iucv_handler_table;/** * iucv_pathid_table: an array of *handler pointing into *                    iucv_handler_table for fast indexing by pathid; */static handler **iucv_pathid_table;static unsigned long max_connections;/** * declare_flag: is 0 when iucv_declare_buffer has not been called */static int declare_flag;/****************FIVE 40-BYTE PARAMETER STRUCTURES******************//* Data struct 1: iparml_control * Used for iucv_accept *          iucv_connect *          iucv_quiesce *          iucv_resume *          iucv_sever *          iucv_retrieve_buffer * Data struct 2: iparml_dpl     (data in parameter list) * Used for iucv_send_prmmsg *          iucv_send2way_prmmsg *          iucv_send2way_prmmsg_array *          iucv_reply_prmmsg * Data struct 3: iparml_db       (data in a buffer) * Used for iucv_receive *          iucv_receive_array *          iucv_reject *          iucv_reply *          iucv_reply_array *          iucv_send *          iucv_send_array *          iucv_send2way *          iucv_send2way_array *          iucv_declare_buffer * Data struct 4: iparml_purge * Used for iucv_purge *          iucv_query * Data struct 5: iparml_set_mask * Used for iucv_set_mask */typedef struct {	__u16 ippathid;	__u8  ipflags1;	__u8  iprcode;	__u16 ipmsglim;	__u16 res1;	__u8  ipvmid[8];	__u8  ipuser[16];	__u8  iptarget[8];} iparml_control;typedef struct {	__u16 ippathid;	__u8  ipflags1;	__u8  iprcode;	__u32 ipmsgid;	__u32 iptrgcls;	__u8  iprmmsg[8];	__u32 ipsrccls;	__u32 ipmsgtag;	__u32 ipbfadr2;	__u32 ipbfln2f;	__u32 res;} iparml_dpl;typedef struct {	__u16 ippathid;	__u8  ipflags1;	__u8  iprcode;	__u32 ipmsgid;	__u32 iptrgcls;	__u32 ipbfadr1;	__u32 ipbfln1f;	__u32 ipsrccls;	__u32 ipmsgtag;	__u32 ipbfadr2;	__u32 ipbfln2f;	__u32 res;} iparml_db;typedef struct {	__u16 ippathid;	__u8  ipflags1;	__u8  iprcode;	__u32 ipmsgid;	__u8  ipaudit[3];	__u8  res1[5];	__u32 res2;	__u32 ipsrccls;	__u32 ipmsgtag;	__u32 res3[3];} iparml_purge;typedef struct {	__u8  ipmask;	__u8  res1[2];	__u8  iprcode;	__u32 res2[9];} iparml_set_mask;typedef struct {	union {		iparml_control  p_ctrl;		iparml_dpl      p_dpl;		iparml_db       p_db;		iparml_purge    p_purge;		iparml_set_mask p_set_mask;	} param;	atomic_t in_use;}  __attribute__ ((aligned(8))) iucv_param;#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param))static iucv_param * iucv_param_pool;/* * Debugging stuff *******************************************************************************/#ifdef DEBUGstatic voidiucv_dumpit(void *buf, int len){	int i;	__u8 *p = (__u8 *)buf;	printk(KERN_DEBUG "  ");	for (i = 0; i < len; i++) {		if (!(i % 16) && i != 0)			printk ("\n  ");		else if (!(i % 4) && i != 0)			printk (" ");		printk ("%02X", *p++);	}	if (len % 16)		printk ("\n");	return;}#define iucv_debug(fmt, args...) \printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args);#else#define iucv_debug(fmt, args...)#define iucv_dumpit(buf, len)#endif/* * Internal functions *******************************************************************************//** * iucv_init - Initialization * * Allocates and initializes various data structures. */static intiucv_init(void){	if (iucv_external_int_buffer)		return 0;	/* Note: GFP_DMA used used to get memory below 2G */	iucv_external_int_buffer = kmalloc(sizeof(iucv_GeneralInterrupt),					   GFP_KERNEL|GFP_DMA);	if (!iucv_external_int_buffer) {		printk(KERN_WARNING		       "%s: Could not allocate external interrupt buffer\n",		       __FUNCTION__);		return -ENOMEM;	}	memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt));	/* Initialize parameter pool */	iucv_param_pool = kmalloc(sizeof(iucv_param) * PARAM_POOL_SIZE,				  GFP_KERNEL|GFP_DMA);	if (!iucv_param_pool) {		printk(KERN_WARNING "%s: Could not allocate param pool\n",		       __FUNCTION__);		kfree(iucv_external_int_buffer);		iucv_external_int_buffer = NULL;		return -ENOMEM;	}	memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);	/* Initialize task queue */	INIT_LIST_HEAD(&iucv_tq.list);	iucv_tq.sync = 0;	iucv_tq.routine = (void *)iucv_bh_handler;	/* Initialize irq queue */	INIT_LIST_HEAD(&iucv_irq_queue);	/* Initialize handler table */	INIT_LIST_HEAD(&iucv_handler_table);	return 0;}/** * grab_param: - Get a parameter buffer from the pre-allocated pool. * * This function searches for an unused element in the the pre-allocated pool * of parameter buffers. If one is found, it marks it "in use" and returns * a pointer to it. The calling function is responsible for releasing it * when it has finished its usage. * * Returns: A pointer to iucv_param. */static __inline__ iucv_param *grab_param(void){	iucv_param *ret;	static int i = 0;	while (atomic_compare_and_swap(0, 1, &iucv_param_pool[i].in_use)) {		i++;		if (i >= PARAM_POOL_SIZE)			i = 0;	}	ret = &iucv_param_pool[i];	memset(&ret->param, 0, sizeof(ret->param));	return ret;}/** * release_param - Release a parameter buffer. * @p: A pointer to a struct iucv_param, previously obtained by calling *     grab_param(). * * This function marks the specified parameter buffer "unused". */static __inline__ voidrelease_param(void *p){	atomic_set(&((iucv_param *)p)->in_use, 0);}/** * iucv_add_handler: - Add a new handler * @new_handler: handle that is being entered into chain. * * Places new handle on iucv_handler_table, if identical handler is not * found. * * Returns: 0 on success, !0 on failure (handler already in chain). */static intiucv_add_handler (handler *new){	ulong flags;	iucv_debug("entering");	iucv_dumpit(new, sizeof(handler));	spin_lock_irqsave (&iucv_lock, flags);	if (!list_empty(&iucv_handler_table)) {		struct list_head *lh;		/**		 * Search list for handler with identical id. If one		 * is found, the new handler is _not_ added.		 */		list_for_each(lh, &iucv_handler_table) {			handler *h = list_entry(lh, handler, list);			if (memcmp(&new->id, &h->id, sizeof(h->id)) == 0) {				iucv_debug("ret 1");				spin_unlock_irqrestore (&iucv_lock, flags);				return 1;			}		}	}	/**	 * If we get here, no handler was found.	 */	INIT_LIST_HEAD(&new->list);	list_add(&new->list, &iucv_handler_table);	spin_unlock_irqrestore (&iucv_lock, flags);	iucv_debug("exiting");	return 0;}/** * iucv_remove_handler: * @users_handler: handler to be removed * * Remove handler when application unregisters. */static voidiucv_remove_handler(handler *handler){	unsigned long flags;	if ((!iucv_pathid_table) || (!handler))		return;	iucv_debug("entering");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -