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

📄 iucv.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;	}	if (pathid == NULL) {		printk(KERN_WARNING "%s: NULL pathid pointer\n",		       __FUNCTION__);		return -EINVAL;	}	parm = (iparml_control *)grab_param();	parm->ipmsglim = msglim_reqstd;	if (user_data)		memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));	if (userid) {		memcpy(parm->ipvmid, userid, sizeof(parm->ipvmid));		ASCEBC(parm->ipvmid, sizeof(parm->ipvmid));		EBC_TOUPPER(parm->ipvmid, sizeof(parm->ipvmid));	}	if (system_name) {		memcpy(parm->iptarget, system_name, sizeof(parm->iptarget));		ASCEBC(parm->iptarget, sizeof(parm->iptarget));		EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget));	}	parm->ipflags1 = (__u8)flags1;	b2f0_result = b2f0(CONNECT, parm);	if (b2f0_result) {		release_param(parm);		return b2f0_result;	}	add_pathid_result = iucv_add_pathid(parm->ippathid, h);	*pathid = parm->ippathid;	if (msglim)		*msglim = parm->ipmsglim;	if (flags1_out)		*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;	if (add_pathid_result) {		iucv_sever(parm->ippathid, no_memory);		printk(KERN_WARNING "%s: add_pathid failed with rc ="			" %d\n", __FUNCTION__, add_pathid_result);		return(add_pathid_result);	}	iucv_debug("exiting");	return b2f0_result;}/** * iucv_purge: * @pathid: Path identification number * @msgid:  Message ID of message to purge. * @srccls: Message class of the message to purge. * @audit:  Pointer to an __u32. If not NULL, on return, information about *          asynchronous errors that may have affected the normal completion *          of this message ist stored at the given location. * * Cancels a message you have sent. * Returns: return code from CP */intiucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit){	iparml_purge *parm;	ulong b2f0_result = 0;	iucv_debug("entering");	iucv_debug("pathid = %d", pathid);	parm = (iparml_purge *)grab_param();	parm->ipmsgid = msgid;	parm->ippathid = pathid;	parm->ipsrccls = srccls;	parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID);	b2f0_result = b2f0(PURGE, parm);	if ((b2f0_result == 0) && audit) {		memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit));		/* parm->ipaudit has only 3 bytes */		*audit >>= 8;	}		release_param(parm);	iucv_debug("b2f0_result = %ld", b2f0_result);	iucv_debug("exiting");	return b2f0_result;}/** * iucv_query_generic: * @want_maxconn: Flag, describing which value is to be returned. * * Helper function for iucv_query_maxconn() and iucv_query_bufsize(). * * Returns: The buffersize, if want_maxconn is 0; the maximum number of *           connections, if want_maxconn is 1 or an error-code < 0 on failure. */static intiucv_query_generic(int want_maxconn){	iparml_purge *parm = (iparml_purge *)grab_param();	int bufsize, maxconn;	int ccode;	/**	 * 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"		);	release_param(parm);	if (ccode)		return -EPERM;	if (want_maxconn)		return maxconn;	return bufsize;}/** * iucv_query_maxconn: * * Determines the maximum number of connections thay may be established. * * Returns: Maximum number of connections that can be. */ulongiucv_query_maxconn(void){	return iucv_query_generic(1);}/** * iucv_query_bufsize: * * Determines the size of the external interrupt buffer. * * Returns: Size of external interrupt buffer. */ulongiucv_query_bufsize (void){	return iucv_query_generic(0);}/** * iucv_quiesce: * @pathid:    Path identification number * @user_data: 16-byte user data * * Temporarily suspends incoming messages on an IUCV path. * You can later reactivate the path by invoking the iucv_resume function. * Returns: return code from CP */intiucv_quiesce (__u16 pathid, __u8 user_data[16]){	iparml_control *parm;	ulong b2f0_result = 0;	iucv_debug("entering");	iucv_debug("pathid = %d", pathid);	parm = (iparml_control *)grab_param();	memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));	parm->ippathid = pathid;	b2f0_result = b2f0(QUIESCE, parm);	release_param(parm);	iucv_debug("b2f0_result = %ld", b2f0_result);	iucv_debug("exiting");	return b2f0_result;}/** * iucv_receive: * @pathid: Path identification number. * @buffer: Address of buffer to receive. Must be below 2G. * @buflen: Length of buffer to receive. * @msgid:  Specifies the message ID. * @trgcls: Specifies target class. * @flags1_out: Receives options for path on return. *    - IPNORPY (0x10)  Specifies whether a reply is required *    - IPPRTY (0x20)   Specifies if you want to send priority message *    - IPRMDATA (0x80) Specifies the data is contained in the parameter list * @residual_buffer: Receives the address of buffer updated by the number *                   of bytes you have received on return. * @residual_length: On return, receives one of the following values: *    - 0                          If the receive buffer is the same length as *                                 the message. *    - Remaining bytes in buffer  If the receive buffer is longer than the *                                 message. *    - Remaining bytes in message If the receive buffer is shorter than the *                                 message. * * This function receives messages that are being sent to you over established * paths. * Returns: return code from CP IUCV call; If the receive buffer is shorter *   than the message, always 5 *   -EINVAL - buffer address is pointing to NULL */intiucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls,	      void *buffer, ulong buflen,	      int *flags1_out, ulong * residual_buffer, ulong * residual_length){	iparml_db *parm;	ulong b2f0_result;	int moved = 0;	/* number of bytes moved from parmlist to buffer */	iucv_debug("entering");	if (!buffer)		return -EINVAL;	parm = (iparml_db *)grab_param();	parm->ipbfadr1 = (__u32) (addr_t) buffer;	parm->ipbfln1f = (__u32) ((ulong) buflen);	parm->ipmsgid = msgid;	parm->ippathid = pathid;	parm->iptrgcls = trgcls;	parm->ipflags1 = (IPFGPID | IPFGMID | IPFGMCL);	b2f0_result = b2f0(RECEIVE, parm);	if (b2f0_result == 0 || b2f0_result == 5) {		if (flags1_out) {			iucv_debug("*flags1_out = %d", *flags1_out);			*flags1_out = (parm->ipflags1 & (~0x07));			iucv_debug("*flags1_out = %d", *flags1_out);		}		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */			if (residual_length)				*residual_length = parm->ipbfln1f;			if (residual_buffer)				*residual_buffer = parm->ipbfadr1;		} else {			moved = min_t (unsigned long, buflen, 8);			memcpy ((char *) buffer,				(char *) &parm->ipbfadr1, moved);			if (buflen < 8)				b2f0_result = 5;			if (residual_length)				*residual_length = abs (buflen - 8);			if (residual_buffer)				*residual_buffer = (ulong) (buffer + moved);		}	}	release_param(parm);	iucv_debug("exiting");	return b2f0_result;}/* * Name: iucv_receive_array * Purpose: This function receives messages that are being sent to you *          over established paths. * Input: pathid - path identification number *        buffer - address of array of buffers *        buflen - total length of buffers *        msgid - specifies the message ID. *        trgcls - specifies target class * Output: *        flags1_out: Options for path. *          IPNORPY - 0x10 specifies whether a reply is required *          IPPRTY - 0x20 specifies if you want to send priority message *         IPRMDATA - 0x80 specifies the data is contained in the parameter list *       residual_buffer - address points to the current list entry IUCV *                         is working on. *       residual_length - *              Contains one of the following values, if the receive buffer is: *               The same length as the message, this field is zero. *               Longer than the message, this field contains the number of *                bytes remaining in the buffer. *               Shorter than the message, this field contains the residual *                count (that is, the number of bytes remaining in the *                message that does not fit into the buffer. In this case *		  b2f0_result = 5. * Return: b2f0_result - return code from CP *         (-EINVAL) - buffer address is NULL */intiucv_receive_array (__u16 pathid,		    __u32 msgid, __u32 trgcls,		    iucv_array_t * buffer, ulong buflen,		    int *flags1_out,		    ulong * residual_buffer, ulong * residual_length){	iparml_db *parm;	ulong b2f0_result;	int i = 0, moved = 0, need_to_move = 8, dyn_len;	iucv_debug("entering");	if (!buffer)		return -EINVAL;	parm = (iparml_db *)grab_param();	parm->ipbfadr1 = (__u32) ((ulong) buffer);	parm->ipbfln1f = (__u32) buflen;	parm->ipmsgid = msgid;	parm->ippathid = pathid;	parm->iptrgcls = trgcls;	parm->ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL);	b2f0_result = b2f0(RECEIVE, parm);	if (b2f0_result == 0 || b2f0_result == 5) {		if (flags1_out) {			iucv_debug("*flags1_out = %d", *flags1_out);			*flags1_out = (parm->ipflags1 & (~0x07));			iucv_debug("*flags1_out = %d", *flags1_out);		}		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */			if (residual_length)				*residual_length = parm->ipbfln1f;			if (residual_buffer)				*residual_buffer = parm->ipbfadr1;		} else {			/* copy msg from parmlist to users array. */			while ((moved < 8) && (moved < buflen)) {				dyn_len =				    min_t (unsigned int,					 (buffer + i)->length, need_to_move);				memcpy ((char *)((ulong)((buffer + i)->address)),					((char *) &parm->ipbfadr1) + moved,					dyn_len);				moved += dyn_len;				need_to_move -= dyn_len;				(buffer + i)->address =				    	(__u32)				((ulong)(__u8 *) ((ulong)(buffer + i)->address)						+ dyn_len);				(buffer + i)->length -= dyn_len;				i++;			}			if (need_to_move)	/* buflen < 8 bytes */				b2f0_result = 5;			if (residual_length)				*residual_length = abs (buflen - 8);			if (residual_buffer) {				if (moved == 0)					*residual_buffer = (ulong) buffer;				else					*residual_buffer =					    (ulong) (buffer + (i - 1));			}		}	}	release_param(parm);	iucv_debug("exiting");	return b2f0_result;}/** * iucv_reject: * @pathid: Path identification number. * @msgid:  Message ID of the message to reject. * @trgcls: Target class of the message to reject. * Returns: return code from CP * * Refuses a specified message. Between the time you are notified of a * message and the time that you complete the message, the message may * be rejected. */intiucv_reject (__u16 pathid, __u32 msgid, __u32 trgcls){	iparml_db *parm;	ulong b2f0_result = 0;	iucv_debug("entering");	iucv_debug("pathid = %d", pathid);	parm = (iparml_db *)grab_param();	parm->ippathid = pathid;	parm->ipmsgid = msgid;	parm->iptrgcls = trgcls;	parm->ipflags1 = (IPFGMCL | IPFGMID | IPFGPID);	b2f0_result = b2f0(REJECT, parm);	release_param(parm);	iucv_debug("b2f0_result = %ld", b2f0_result);	iucv_debug("exiting");	return b2f0_result;}/* * Name: iucv_reply * Purpose: This function responds to the two-way messages that you *          receive. You must identify completely the message to *          which you wish to reply. ie, pathid, msgid, and trgcls. * Input: pathid - path identification number *        msgid - specifies the message ID. *        trgcls - specifies target class *        flags1 - option for path *                 IPPRTY- 0x20 - specifies if you want to send priority message *        buffer - address of reply buffer *        buflen - length of reply buffer * Output: ipbfadr2 - Address of buffer updated by the number *                    of bytes you have moved. *         ipbfln2f - Contains on the the following values *              If the answer buffer is the same length as the reply, this field

⌨️ 快捷键说明

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