📄 iucv.c
字号:
b2f0_result = b2f0(SEND, parm); if ((!b2f0_result) && (msgid)) *msgid = parm->ipmsgid; release_param(parm); iucv_debug(2, "exiting"); return b2f0_result;}/* * Name: iucv_send2way * Purpose: This function transmits data to another application. * Data to be transmitted is in a buffer. The receiver * of the send is expected to reply to the message and * a buffer is provided into which IUCV moves the reply * to this message. * Input: pathid - path identification number * trgcls - specifies target class * srccls - specifies the source message class * msgtag - specifies a tag associated with the message * flags1 - option for path * IPPRTY- specifies if you want to send priority message * buffer - address of send buffer * buflen - length of send buffer * ansbuf - address of buffer to reply with * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - buffer or ansbuf address is NULL */intiucv_send2way (__u16 pathid, __u32 * msgid, __u32 trgcls, __u32 srccls, __u32 msgtag, int flags1, void *buffer, ulong buflen, void *ansbuf, ulong anslen){ iparml_db *parm; ulong b2f0_result; iucv_debug(2, "entering"); if (!buffer || !ansbuf) return -EINVAL; parm = (iparml_db *)grab_param(); parm->ippathid = pathid; parm->iptrgcls = trgcls; parm->ipbfadr1 = (__u32) ((ulong) buffer); parm->ipbfln1f = (__u32) buflen; /* length of message */ parm->ipbfadr2 = (__u32) ((ulong) ansbuf); parm->ipbfln2f = (__u32) anslen; parm->ipsrccls = srccls; parm->ipmsgtag = msgtag; parm->ipflags1 = flags1; /* priority message */ b2f0_result = b2f0(SEND, parm); if ((!b2f0_result) && (msgid)) *msgid = parm->ipmsgid; release_param(parm); iucv_debug(2, "exiting"); return b2f0_result;}/* * Name: iucv_send2way_array * Purpose: This function transmits data to another application. * The contents of buffer is the address of the array of * addresses and lengths of discontiguous buffers that hold * the message text. The receiver of the send is expected to * reply to the message and a buffer is provided into which * IUCV moves the reply to this message. * Input: pathid - path identification number * trgcls - specifies target class * srccls - specifies the source message class * msgtag - spcifies a tag to be associated with the message * flags1 - option for path * IPPRTY- specifies if you want to send priority message * buffer - address of array of send buffers * buflen - total length of send buffers * ansbuf - address of buffer to reply with * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - buffer address is NULL */intiucv_send2way_array (__u16 pathid, __u32 * msgid, __u32 trgcls, __u32 srccls, __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen, iucv_array_t * ansbuf, ulong anslen){ iparml_db *parm; ulong b2f0_result; iucv_debug(2, "entering"); if (!buffer || !ansbuf) return -EINVAL; parm = (iparml_db *)grab_param(); parm->ippathid = pathid; parm->iptrgcls = trgcls; parm->ipbfadr1 = (__u32) ((ulong) buffer); parm->ipbfln1f = (__u32) buflen; /* length of message */ parm->ipbfadr2 = (__u32) ((ulong) ansbuf); parm->ipbfln2f = (__u32) anslen; parm->ipsrccls = srccls; parm->ipmsgtag = msgtag; parm->ipflags1 = (IPBUFLST | IPANSLST | flags1); b2f0_result = b2f0(SEND, parm); if ((!b2f0_result) && (msgid)) *msgid = parm->ipmsgid; release_param(parm); iucv_debug(2, "exiting"); return b2f0_result;}/* * Name: iucv_send2way_prmmsg * Purpose: This function transmits data to another application. * Prmmsg specifies that the 8-bytes of data are to be moved * into the parameter list. This is a two-way message and the * receiver of the message is expected to reply. A buffer * is provided into which IUCV moves the reply to this * message. * Input: pathid - path identification number * trgcls - specifies target class * srccls - specifies the source message class * msgtag - specifies a tag to be associated with the message * flags1 - option for path * IPPRTY- specifies if you want to send priority message * prmmsg - 8-bytes of data to be placed in parameter list * ansbuf - address of buffer to reply with * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - buffer address is NULL*/intiucv_send2way_prmmsg (__u16 pathid, __u32 * msgid, __u32 trgcls, __u32 srccls, __u32 msgtag, ulong flags1, __u8 prmmsg[8], void *ansbuf, ulong anslen){ iparml_dpl *parm; ulong b2f0_result; iucv_debug(2, "entering"); if (!ansbuf) return -EINVAL; parm = (iparml_dpl *)grab_param(); parm->ippathid = pathid; parm->iptrgcls = trgcls; parm->ipsrccls = srccls; parm->ipmsgtag = msgtag; parm->ipbfadr2 = (__u32) ((ulong) ansbuf); parm->ipbfln2f = (__u32) anslen; parm->ipflags1 = (IPRMDATA | flags1); /* message in prmlist */ memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); b2f0_result = b2f0(SEND, parm); if ((!b2f0_result) && (msgid)) *msgid = parm->ipmsgid; release_param(parm); iucv_debug(2, "exiting"); return b2f0_result;}/* * Name: iucv_send2way_prmmsg_array * Purpose: This function transmits data to another application. * Prmmsg specifies that the 8-bytes of data are to be moved * into the parameter list. This is a two-way message and the * receiver of the message is expected to reply. A buffer * is provided into which IUCV moves the reply to this * message. The contents of ansbuf is the address of the * array of addresses and lengths of discontiguous buffers * that contain the reply. * Input: pathid - path identification number * trgcls - specifies target class * srccls - specifies the source message class * msgtag - specifies a tag to be associated with the message * flags1 - option for path * IPPRTY- specifies if you want to send priority message * prmmsg - 8-bytes of data to be placed into the parameter list * ansbuf - address of buffer to reply with * anslen - length of buffer to reply with * Output: msgid - specifies the message ID. * Return: b2f0_result - return code from CP * (-EINVAL) - ansbuf address is NULL */intiucv_send2way_prmmsg_array (__u16 pathid, __u32 * msgid, __u32 trgcls, __u32 srccls, __u32 msgtag, int flags1, __u8 prmmsg[8], iucv_array_t * ansbuf, ulong anslen){ iparml_dpl *parm; ulong b2f0_result; iucv_debug(2, "entering"); if (!ansbuf) return -EINVAL; parm = (iparml_dpl *)grab_param(); parm->ippathid = pathid; parm->iptrgcls = trgcls; parm->ipsrccls = srccls; parm->ipmsgtag = msgtag; parm->ipbfadr2 = (__u32) ((ulong) ansbuf); parm->ipbfln2f = (__u32) anslen; parm->ipflags1 = (IPRMDATA | IPANSLST | flags1); memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); b2f0_result = b2f0(SEND, parm); if ((!b2f0_result) && (msgid)) *msgid = parm->ipmsgid; release_param(parm); iucv_debug(2, "exiting"); return b2f0_result;}voidiucv_setmask_cpuid (void *result){ iparml_set_mask *parm; iucv_debug(1, "entering"); parm = (iparml_set_mask *)grab_param(); parm->ipmask = *((__u8*)result); *((ulong *)result) = b2f0(SETMASK, parm); release_param(parm); iucv_debug(1, "b2f0_result = %ld", *((ulong *)result)); iucv_debug(1, "exiting");}/* * Name: iucv_setmask * Purpose: This function enables or disables the following IUCV * external interruptions: Nonpriority and priority message * interrupts, nonpriority and priority reply interrupts. * Input: SetMaskFlag - options for interrupts * 0x80 - Nonpriority_MessagePendingInterruptsFlag * 0x40 - Priority_MessagePendingInterruptsFlag * 0x20 - Nonpriority_MessageCompletionInterruptsFlag * 0x10 - Priority_MessageCompletionInterruptsFlag * 0x08 - IUCVControlInterruptsFlag * Output: NA * Return: b2f0_result - return code from CP*/intiucv_setmask (int SetMaskFlag){ union { ulong result; __u8 param; } u; int cpu; u.param = SetMaskFlag; cpu = get_cpu(); smp_call_function_on(iucv_setmask_cpuid, &u, 0, 1, iucv_cpuid); put_cpu(); return u.result;}/** * iucv_sever: * @pathid: Path identification number * @user_data: 16-byte of user data * * This function terminates an iucv path. * Returns: return code from CP */intiucv_sever(__u16 pathid, __u8 user_data[16]){ iparml_control *parm; ulong b2f0_result = 0; iucv_debug(1, "entering"); parm = (iparml_control *)grab_param(); memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); parm->ippathid = pathid; b2f0_result = b2f0(SEVER, parm); if (!b2f0_result) iucv_remove_pathid(pathid); release_param(parm); iucv_debug(1, "exiting"); return b2f0_result;}/* * Interrupt Handlers *******************************************************************************//** * iucv_irq_handler: * @regs: Current registers * @code: irq code * * Handles external interrupts coming in from CP. * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler(). */static voidiucv_irq_handler(struct pt_regs *regs, __u16 code){ iucv_irqdata *irqdata; irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC); if (!irqdata) { printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); return; } memcpy(&irqdata->data, iucv_external_int_buffer, sizeof(iucv_GeneralInterrupt)); spin_lock(&iucv_irq_queue_lock); list_add_tail(&irqdata->queue, &iucv_irq_queue); spin_unlock(&iucv_irq_queue_lock); tasklet_schedule(&iucv_tasklet);}/** * iucv_do_int: * @int_buf: Pointer to copy of external interrupt buffer * * The workhorse for handling interrupts queued by iucv_irq_handler(). * This function is called from the bottom half iucv_tasklet_handler(). */static voidiucv_do_int(iucv_GeneralInterrupt * int_buf){ handler *h = NULL; struct list_head *lh; ulong flags; iucv_interrupt_ops_t *interrupt = NULL; /* interrupt addresses */ __u8 temp_buff1[24], temp_buff2[24]; /* masked handler id. */ int rc = 0, j = 0; __u8 no_listener[16] = "NO LISTENER"; iucv_debug(2, "entering, pathid %d, type %02X", int_buf->ippathid, int_buf->iptype); iucv_dumpit("External Interrupt Buffer:", int_buf, sizeof(iucv_GeneralInterrupt)); ASCEBC (no_listener, 16); if (int_buf->iptype != 01) { if ((int_buf->ippathid) > (max_connections - 1)) { printk(KERN_WARNING "%s: Got interrupt with pathid %d" " > max_connections (%ld)\n", __FUNCTION__, int_buf->ippathid, max_connections - 1); } else { h = iucv_pathid_table[int_buf->ippathid]; interrupt = h->interrupt_table; iucv_dumpit("Handler:", h, sizeof(handler)); } } /* end of if statement */ switch (int_buf->iptype) { case 0x01: /* connection pending */ if (messagesDisabled) { iucv_setmask(~0); messagesDisabled = 0; } spin_lock_irqsave(&iucv_lock, flags); list_for_each(lh, &iucv_handler_table) { h = list_entry(lh, handler, list); memcpy(temp_buff1, &(int_buf->ipvmid), 24); memcpy(temp_buff2, &(h->id.userid), 24); for (j = 0; j < 24; j++) { temp_buff1[j] &= (h->id.mask)[j]; temp_buff2[j] &= (h->id.mask)[j]; } iucv_dumpit("temp_buff1:", temp_buff1, sizeof(temp_buff1)); iucv_dumpit("temp_buff2", temp_buff2, sizeof(temp_buff2)); if (!memcmp (temp_buff1, temp_buff2, 24)) { iucv_debug(2, "found a matching handler"); break; } else h = NULL; } spin_unlock_irqrestore (&iucv_lock, flags); if (h) { /* ADD PATH TO PATHID TABLE */ rc = iucv_add_pathid(int_buf->ippathid, h); if (rc) { iucv_sever (int_buf->ippathid, no_listener); iucv_debug(1, "add_pathid failed, rc = %d", rc); } else { interrupt = h->interrupt_table; if (interrupt->ConnectionPending) { EBCASC (int_buf->ipvmid, 8); interrupt->ConnectionPending( (iucv_ConnectionPending *)int_buf, h->pgm_data); } else iucv_sever(int_buf->ippathid, no_listener); } } else iucv_sever(int_buf->ippathid, no_listener); break; case 0x02: /*connection complete */ if (messagesDisabled) { iucv_setmask(~0); messagesDisabled = 0; } if (h) { if (interrupt->ConnectionComplete) { interrupt->ConnectionComplete( (iucv_ConnectionComplete *)int_buf, h->pgm_data); } else iucv_debug(1, "ConnectionComplete not called"); } else iucv_sever(int_buf->ippathid, no_listener); break; case 0x03: /* connection severed */ if (messagesDisabled) { iucv_setmask(~0); messagesDisabled = 0; } if (h) { if (interrupt->ConnectionSevered) interrupt->ConnectionSevered( (iucv_ConnectionSevered *)int_buf, h->pgm_data); else iucv
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -