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

📄 iucv.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * $Id: iucv.c,v 1.45 2005/04/26 22:59:06 braunu Exp $ * * 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: 1.45 $ * *//* #define DEBUG */#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/config.h>#include <linux/spinlock.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/list.h>#include <linux/errno.h>#include <linux/err.h>#include <linux/device.h>#include <asm/atomic.h>#include "iucv.h"#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: * 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        0x40static intiucv_bus_match (struct device *dev, struct device_driver *drv){	return 0;}struct bus_type iucv_bus = {	.name = "iucv",	.match = iucv_bus_match,};	struct device *iucv_root;/* 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 = NULL;/* Spin Lock declaration */static DEFINE_SPINLOCK(iucv_lock);static int messagesDisabled = 0;/***************INTERRUPT HANDLING ***************/typedef struct {	struct list_head queue;	iucv_GeneralInterrupt data;} iucv_irqdata;static struct list_head  iucv_irq_queue;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 DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0);/************ 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;/** * 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. */static int iucv_cpuid = -1;/** * register_flag: is 0 when external interrupt has not been registered */static int register_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;	__u32    res;}  __attribute__ ((aligned(8))) iucv_param;#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param))static iucv_param * iucv_param_pool;MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)");MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver");MODULE_LICENSE("GPL");/* * Debugging stuff *******************************************************************************/#ifdef DEBUGstatic int debuglevel = 0;module_param(debuglevel, int, 0);MODULE_PARM_DESC(debuglevel, "Specifies the debug level (0=off ... 3=all)");static voidiucv_dumpit(char *title, void *buf, int len){	int i;	__u8 *p = (__u8 *)buf;	if (debuglevel < 3)		return;	printk(KERN_DEBUG "%s\n", title);	printk("  ");	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(lvl, fmt, args...) \do { \	if (debuglevel >= lvl) \		printk(KERN_DEBUG "%s: " fmt "\n", __FUNCTION__ , ## args); \} while (0)#else#define iucv_debug(lvl, fmt, args...)#define iucv_dumpit(title, buf, len)#endif/* * Internal functions *******************************************************************************//** * print start banner */static voidiucv_banner(void){	char vbuf[] = "$Revision: 1.45 $";	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);}/** * iucv_init - Initialization * * Allocates and initializes various data structures. */static intiucv_init(void){	int ret;	if (iucv_external_int_buffer)		return 0;	if (!MACHINE_IS_VM) {		printk(KERN_ERR "IUCV: IUCV connection needs VM as base\n");		return -EPROTONOSUPPORT;	}	ret = bus_register(&iucv_bus);	if (ret) {		printk(KERN_ERR "IUCV: failed to register bus.\n");		return ret;	}	iucv_root = s390_root_dev_register("iucv");	if (IS_ERR(iucv_root)) {		printk(KERN_ERR "IUCV: failed to register iucv root.\n");		bus_unregister(&iucv_bus);		return PTR_ERR(iucv_root);	}	/* 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__);		s390_root_dev_unregister(iucv_root);		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,				  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;		s390_root_dev_unregister(iucv_root);		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);	/* Initialize handler table */	INIT_LIST_HEAD(&iucv_handler_table);	iucv_banner();	return 0;}/** * iucv_exit - De-Initialization * * Frees everything allocated from iucv_init. */static int iucv_retrieve_buffer (void);static voidiucv_exit(void){	iucv_retrieve_buffer();	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");}/** * grab_param: - Get a parameter buffer from the pre-allocated pool. * * This function searches for an unused element in 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 *ptr;        static int hint = 0;	ptr = iucv_param_pool + hint;	do {		ptr++;		if (ptr >= iucv_param_pool + PARAM_POOL_SIZE)			ptr = iucv_param_pool;	} while (atomic_compare_and_swap(0, 1, &ptr->in_use));	hint = ptr - iucv_param_pool;	memset(&ptr->param, 0, sizeof(ptr->param));	return ptr;

⌨️ 快捷键说明

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