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

📄 iucv.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	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(1, "entering");	iucv_debug(1, "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) {		if (handle)			printk(KERN_WARNING			       "%s: Handler not found in iucv_handler_table.\n",			       __FUNCTION__);		else			printk(KERN_WARNING			       "%s: NULL handle passed by application.\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) {		if (msglim)			*msglim = parm->ipmsglim;		if (pgm_data)			h->pgm_data = pgm_data;		if (flags1_out)			*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;	}	release_param(parm);	iucv_debug(1, "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;	iparml_control local_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(1, "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;		}	}	spin_unlock_irqrestore (&iucv_lock, flags);	if (!h) {		if (handle)			printk(KERN_WARNING			       "%s: Handler not found in iucv_handler_table.\n",			       __FUNCTION__);		else			printk(KERN_WARNING			       "%s: NULL handle passed by application.\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));	}	/* In order to establish an IUCV connection, the procedure is:         *         * b2f0(CONNECT)         * take the ippathid from the b2f0 call         * register the handler to the ippathid         *         * Unfortunately, the ConnectionEstablished message gets sent after the         * b2f0(CONNECT) call but before the register is handled.         *         * In order for this race condition to be eliminated, the IUCV Control         * Interrupts must be disabled for the above procedure.         *         * David Kennedy <dkennedy@linuxcare.com>         */	/* Enable everything but IUCV Control messages */	iucv_setmask(~(AllInterrupts));	messagesDisabled = 1;	spin_lock_irqsave (&iucv_lock, flags);	parm->ipflags1 = (__u8)flags1;	b2f0_result = b2f0(CONNECT, parm);	memcpy(&local_parm, parm, sizeof(local_parm));	release_param(parm);	parm = &local_parm;	if (!b2f0_result)		add_pathid_result = __iucv_add_pathid(parm->ippathid, h);	spin_unlock_irqrestore (&iucv_lock, flags);	if (b2f0_result) {		iucv_setmask(~0);		messagesDisabled = 0;		return b2f0_result;	}	*pathid = parm->ippathid;	/* Enable everything again */	iucv_setmask(IUCVControlInterruptsFlag);	if (msglim)		*msglim = parm->ipmsglim;	if (flags1_out)		*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;	if (add_pathid_result) {		iucv_sever(*pathid, no_memory);		printk(KERN_WARNING "%s: add_pathid failed with rc ="			" %d\n", __FUNCTION__, add_pathid_result);		return(add_pathid_result);	}	iucv_debug(1, "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(1, "entering");	iucv_debug(1, "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 && audit) {		memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit));		/* parm->ipaudit has only 3 bytes */		*audit >>= 8;	}		release_param(parm);	iucv_debug(1, "b2f0_result = %ld", b2f0_result);	iucv_debug(1, "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(1, "entering");	iucv_debug(1, "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(1, "b2f0_result = %ld", b2f0_result);	iucv_debug(1, "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(2, "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 || b2f0_result == 5) {		if (flags1_out) {			iucv_debug(2, "*flags1_out = %d", *flags1_out);			*flags1_out = (parm->ipflags1 & (~0x07));			iucv_debug(2, "*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(2, "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:

⌨️ 快捷键说明

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