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

📄 iucv.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	spin_lock_irqsave (&iucv_lock, flags);	list_del(&handler->list);	spin_unlock_irqrestore (&iucv_lock, flags);	iucv_debug("exiting");	return;}/** * b2f0: * @code: identifier of IUCV call to CP. * @parm: pointer to 40 byte iparml area passed to CP * * Calls CP to execute IUCV commands. * * Returns: return code from CP's IUCV call */static __inline__ ulongb2f0(__u32 code, void *parm){	iucv_debug("iparml before b2f0 call:");	iucv_dumpit(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"		);	iucv_debug("iparml after b2f0 call:");	iucv_dumpit(parm, sizeof(iucv_param));	return (unsigned long)*((__u8 *)(parm + 3));}/* * Name: iucv_add_pathid * Purpose: Adds a path id to the system. * Input: pathid -  pathid that is going to be entered into system *        handle -  address of handler that the pathid will be associated *		   with. *        pgm_data - token passed in by application. * Output: 0: successful addition of pathid *	   - EINVAL - pathid entry is being used by another application *	   - ENOMEM - storage allocation for a new pathid table failed*/static intiucv_add_pathid(__u16 pathid, handler *handler){	ulong flags;	iucv_debug("entering");	iucv_debug("handler is pointing to %p", handler);	if (pathid > (max_connections - 1))		return -EINVAL;	spin_lock_irqsave (&iucv_lock, flags);	if (iucv_pathid_table[pathid]) {		spin_unlock_irqrestore (&iucv_lock, flags);		iucv_debug("pathid entry is %p", iucv_pathid_table[pathid]);		printk(KERN_WARNING		       "%s: Pathid being used, error.\n", __FUNCTION__);		return -EINVAL;	}	iucv_pathid_table[pathid] = handler;	spin_unlock_irqrestore (&iucv_lock, flags);	iucv_debug("exiting");	return 0;}				/* end of add_pathid function */static voidiucv_remove_pathid(__u16 pathid){	ulong flags;	if (pathid > (max_connections - 1))		return;	spin_lock_irqsave (&iucv_lock, flags);	iucv_pathid_table[pathid] = NULL;	spin_unlock_irqrestore (&iucv_lock, flags);}/* * Name: iucv_declare_buffer * Purpose: Specifies the guests real address of an external *          interrupt. * Input: void * Output: iprcode - return code from b2f0 call*/intiucv_declare_buffer (void){	ulong b2f0_result;	iparml_db *parm = (iparml_db *)grab_param();	parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer);	b2f0_result = b2f0(DECLARE_BUFFER, parm);	release_param(parm);	iucv_debug("Address of EIB = %p", iucv_external_int_buffer);	iucv_debug("exiting");	return b2f0_result;}/** * iucv_retrieve_buffer: * * Terminates all use of IUCV. * Returns: return code from CP */intiucv_retrieve_buffer (void){	ulong b2f0_result = 0;	iparml_control *parm = (iparml_control *)grab_param();	iucv_debug("entering");	b2f0_result = b2f0(RETRIEVE_BUFFER, parm);	release_param(parm);	if (b2f0_result == 0) {		kfree(iucv_pathid_table);		iucv_pathid_table = NULL;		declare_flag = 0;	}	iucv_debug("exiting");	return b2f0_result;}/** * iucv_register_program: * @pgmname:  user identification * @userid:   machine identification * @pgmmask:  Indicates which bits in the pgmname and userid combined will be *            used to determine who is given control. * @ops:      Address of interrupt handler table. * @pgm_data: Application data to be passed to interrupt handlers. * * Registers an application with IUCV. * Returns: *           The address of handler, or NULL on failure. * NOTE on pgmmask: *   If pgmname, userid and pgmmask are provided, pgmmask is entered into the *   handler as is. *   If pgmmask is NULL, the internal mask is set to all 0xff's *   When userid is NULL, the first 8 bytes of the internal mask are forced *   to 0x00. *   If pgmmask and userid are NULL, the first 8 bytes of the internal mask *   are forced to 0x00 and the last 16 bytes to 0xff. */iucv_handle_tiucv_register_program (__u8 pgmname[16],		       __u8 userid[8],		       __u8 pgmmask[24],		       iucv_interrupt_ops_t * ops, void *pgm_data){	ulong rc = 0;		/* return code from function calls */	handler *new_handler;	iucv_debug("entering");	if (ops == NULL) {		/* interrupt table is not defined */		printk(KERN_WARNING "%s: Interrupt table is not defined, "		       "exiting\n", __FUNCTION__);		return NULL;	}	if (!pgmname) {		printk(KERN_WARNING "%s: pgmname not provided\n", __FUNCTION__);		return NULL;	}	/* Allocate handler entry */	new_handler = (handler *)kmalloc(sizeof(handler), GFP_KERNEL);	if (new_handler == NULL) {		printk(KERN_WARNING "%s: storage allocation for new handler "		       "failed.\n", __FUNCTION__);		return NULL;	}	if (!iucv_pathid_table) {		if (iucv_init()) {			kfree(new_handler);			return NULL;		}		max_connections = iucv_query_maxconn();		iucv_pathid_table = kmalloc(max_connections * sizeof(handler *),				       GFP_KERNEL);		if (iucv_pathid_table == NULL) {			printk(KERN_WARNING "%s: iucv_pathid_table storage "			       "allocation failed\n", __FUNCTION__);			return NULL;		}		memset (iucv_pathid_table, 0, max_connections * sizeof(handler *));	}	memset(new_handler, 0, sizeof (handler));	memcpy(new_handler->id.user_data, pgmname,		sizeof (new_handler->id.user_data));	if (userid) {		memcpy (new_handler->id.userid, userid,			sizeof (new_handler->id.userid));		ASCEBC (new_handler->id.userid,			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));		} else {			memset (new_handler->id.mask, 0xFF,				sizeof (new_handler->id.mask));		}	} else {		if (pgmmask) {			memcpy (new_handler->id.mask, pgmmask,				sizeof (new_handler->id.mask));		} else {			memset (new_handler->id.mask, 0xFF,				sizeof (new_handler->id.mask));		}		memset (new_handler->id.mask, 0x00,			sizeof (new_handler->id.userid));	}	/* fill in the rest of handler */	new_handler->pgm_data = pgm_data;	new_handler->interrupt_table = ops;	/*	 * Check if someone else is registered with same pgmname, userid	 * and mask. If someone is already registered with same pgmname,	 * userid and mask, registration will fail and NULL will be returned	 * to the application.	 * If identical handler not found, then handler is added to list.	 */	rc = iucv_add_handler(new_handler);	if (rc) {		printk(KERN_WARNING "%s: Someone already registered with same "		       "pgmname, userid, pgmmask\n", __FUNCTION__);		kfree (new_handler);		return NULL;	}	if (declare_flag == 0) {		rc = iucv_declare_buffer();		if (rc) {			iucv_remove_handler(new_handler);			kfree(new_handler);			printk(KERN_WARNING "%s: iucv_declare_buffer "			       "returned %ld\n", __FUNCTION__, rc);			return NULL;		}		/* request the 0x4000 external interrupt */		rc = register_external_interrupt (0x4000, iucv_irq_handler);		if (rc) {			iucv_remove_handler(new_handler);			iucv_retrieve_buffer();			kfree (new_handler);			printk(KERN_WARNING "%s: "			       "register_external_interrupt returned %ld\n",			       __FUNCTION__, rc);			return NULL;		}		declare_flag = 1;	}	iucv_debug("exiting");	return new_handler;}				/* end of register function *//** * iucv_unregister_program: * @handle: address of handler * * Unregister application with IUCV. * Returns: *   Always 0 */intiucv_unregister_program (iucv_handle_t handle){	handler *h = (handler *)handle;	int i;	ulong flags;	iucv_debug("entering");	iucv_debug("address of handler is %p", h);	/**	 * First, walk thru iucv_pathid_table and sever any pathid which is	 * still pointing to the handler to be removed.	 */	spin_lock_irqsave (&iucv_lock, flags);	for (i = 0; i < max_connections; i++)		if (iucv_pathid_table[i] == h) {			spin_unlock_irqrestore (&iucv_lock, flags);			iucv_sever(i, h->id.user_data);			spin_lock_irqsave(&iucv_lock, flags);		}	spin_unlock_irqrestore (&iucv_lock, flags);	iucv_remove_handler(h);	kfree(h);	iucv_debug("exiting");	return 0;}/** * iucv_accept: * @pathid:             Path identification number * @msglim_reqstd:      The number of outstanding messages requested. * @user_data:          Data specified by the iucv_connect function. * @flags1:             Contains options for this path. *     - IPPRTY (0x20)   Specifies if you want to send priority message. *     - IPRMDATA (0x80) Specifies whether your program can handle a message *                       in the parameter list. *     - IPQUSCE (0x40)  Specifies whether you want to quiesce the path being *		         established. * @handle:             Address of handler. * @pgm_data:           Application data passed to interrupt handlers. * @flags1_out:         Pointer to an int. If not NULL, on return the options for *                      the path are stored at the given location: *     - IPPRTY (0x20)  Indicates you may send a priority message. * @msglim:             Pointer to an __u16. If not NULL, on return the maximum *                      number of outstanding messages is stored at the given *                      location. * * This function is issued after the user receives a Connection Pending external * interrupt and now wishes to complete the IUCV communication path. * Returns: *   return code from CP */intiucv_accept(__u16 pathid, __u16 msglim_reqstd,	     __u8 user_data[16], int flags1,	     iucv_handle_t handle, void *pgm_data,	     int *flags1_out, __u16 * msglim){	ulong b2f0_result = 0;	ulong flags;	struct list_head *lh;	handler *h = NULL;	iparml_control *parm;	iucv_debug("entering");	iucv_debug("pathid = %d", pathid);	/* Checking if handle is valid  */	spin_lock_irqsave (&iucv_lock, flags);	list_for_each(lh, &iucv_handler_table) {		if ((handler *)handle == list_entry(lh, handler, list)) {			h = (handler *)handle;			break;		}	}	spin_unlock_irqrestore (&iucv_lock, flags);	if (!h) {		printk(KERN_WARNING "%s: NULL handle passed by application "		       "or handler not found in iucv_handler_table\n",		       __FUNCTION__);		return -EINVAL;	}	parm = (iparml_control *)grab_param();	parm->ippathid = pathid;	parm->ipmsglim = msglim_reqstd;	if (user_data)		memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));	parm->ipflags1 = (__u8)flags1;	b2f0_result = b2f0(ACCEPT, parm);	if (b2f0_result == 0) {		if (pgm_data)			h->pgm_data = pgm_data;		if (flags1_out)			*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;	}	release_param(parm);	iucv_debug("exiting");	return b2f0_result;}/** * iucv_connect: * @pathid:        Path identification number * @msglim_reqstd: Number of outstanding messages requested * @user_data:     16-byte user data * @userid:        8-byte of user identification * @system_name:   8-byte identifying the system name * @flags1:        Specifies options for this path: *     - IPPRTY (0x20)   Specifies if you want to send priority message. *     - IPRMDATA (0x80) Specifies whether your program can handle a message *                       in  the parameter list. *     - IPQUSCE (0x40)  Specifies whether you want to quiesce the path being *                       established. *     - IPLOCAL (0x01)  Allows an application to force the partner to be on the *                       local system. If local is specified then target class *                       cannot be specified. * @flags1_out:    Pointer to an int. If not NULL, on return the options for *                 the path are stored at the given location: *     - IPPRTY (0x20)   Indicates you may send a priority message. * @msglim:        Pointer to an __u16. If not NULL, on return the maximum *                 number of outstanding messages is stored at the given *                 location. * @handle:        Address of handler. * @pgm_data:      Application data to be passed to interrupt handlers. * * This function establishes an IUCV path. Although the connect may complete * successfully, you are not able to use the path until you receive an IUCV * Connection Complete external interrupt. * Returns: return code from CP, or one of the following *     - ENOMEM *     - return code from iucv_declare_buffer *     - EINVAL - invalid handle passed by application *     - EINVAL - pathid address is NULL *     - ENOMEM - pathid table storage allocation failed *     - return code from internal function add_pathid */intiucv_connect (__u16 *pathid, __u16 msglim_reqstd,	      __u8 user_data[16], __u8 userid[8],	      __u8 system_name[8], int flags1,	      int *flags1_out, __u16 * msglim,	      iucv_handle_t handle, void *pgm_data){	iparml_control *parm;	struct list_head *lh;	ulong b2f0_result = 0;	ulong flags;	int add_pathid_result = 0;	handler *h = NULL;	__u8 no_memory[16] = "NO MEMORY";	iucv_debug("entering");	/* Checking if handle is valid  */	spin_lock_irqsave (&iucv_lock, flags);	list_for_each(lh, &iucv_handler_table) {		if ((handler *)handle == list_entry(lh, handler, list)) {			h = (handler *)handle;			break;		}	}

⌨️ 快捷键说明

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