1 /* QDIO.C       (c) Copyright Jan Jaeger, 2003-2009                  */
2 /*              Queued Direct Input Output                           */
3 
4 /*      This module contains the Signal Adapter instruction          */
5 
6 #include "hstdinc.h"
7 
8 #if !defined(_HENGINE_DLL_)
9 #define _HENGINE_DLL_
10 #endif
11 
12 #if !defined(_QDIO_C_)
13 #define _QDIO_C_
14 #endif
15 
16 #include "hercules.h"
17 
18 #include "opcode.h"
19 
20 #include "inline.h"
21 
22 #undef PTIO
23  #define PTIO(_class, _name) \
24  PTT(PTT_CL_ ## _class,_name,regs->GR_L(1),(U32)(effective_addr2 & 0xffffffff),regs->psw.IA_L)
25 
26 #if defined(FEATURE_QUEUED_DIRECT_IO)
27 
28 /*-------------------------------------------------------------------*/
29 /* B274 SIGA  - Signal Adapter                                   [S] */
30 /*-------------------------------------------------------------------*/
DEF_INST(signal_adapter)31 DEF_INST(signal_adapter)
32 {
33 int     b2;
34 RADR    effective_addr2;
35 DEVBLK *dev;                            /* -> device block           */
36 
37     S(inst, regs, b2, effective_addr2);
38 
39     PRIV_CHECK(regs);
40 
41     SIE_INTERCEPT(regs);
42 
43     PTIO(IO,"SIGA");
44 
45     /* Specification exception if invalid function code */
46     if(regs->GR_L(0) > SIGA_FC_MAX)
47         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
48 
49     /* Program check if the ssid including lcss is invalid */
50     SSID_CHECK(regs);
51 
52     /* Locate the device block for this subchannel */
53     dev = find_device_by_subchan (regs->GR_L(1));
54 
55     /* Condition code 3 if subchannel does not exist,
56        is not valid, or is not enabled or is not a QDIO subchannel */
57     if (dev == NULL
58         || (dev->pmcw.flag5 & PMCW5_V) == 0
59         || (dev->pmcw.flag5 & PMCW5_E) == 0
60         || (dev->pmcw.flag4 & PMCW4_Q) == 0)
61     {
62         PTIO(ERR,"*SIGA");
63 #if defined(_FEATURE_QUEUED_DIRECT_IO_ASSIST)
64         SIE_INTERCEPT(regs);
65 #endif
66         regs->psw.cc = 3;
67         return;
68     }
69 
70     /* Obtain the device lock */
71     obtain_lock (&dev->lock);
72 
73     /* Check that device is QDIO active */
74     if ((dev->scsw.flag2 & SCSW2_Q) == 0)
75     {
76         PTIO(ERR,"*SIGA");
77         release_lock (&dev->lock);
78         regs->psw.cc = 1;
79         return;
80     }
81 
82     switch(regs->GR_L(0)) {
83 
84     case SIGA_FC_R:
85     if(dev->hnd->siga_r)
86             regs->psw.cc = (dev->hnd->siga_r) (dev, regs->GR_L(2) );
87         else
88         {
89             PTIO(ERR,"*SIGA");
90             regs->psw.cc = 3;
91         }
92         break;
93 
94     case SIGA_FC_W:
95     if(dev->hnd->siga_w)
96             regs->psw.cc = (dev->hnd->siga_w) (dev, regs->GR_L(2) );
97         else
98         {
99             PTIO(ERR,"*SIGA");
100             regs->psw.cc = 3;
101         }
102         break;
103 
104     case SIGA_FC_S:
105         /* No signalling required for sync requests as we emulate
106            a real machine */
107         regs->psw.cc = 0;
108         break;
109 
110     default:
111         PTIO(ERR,"*SIGA");
112 
113     }
114 
115     release_lock (&dev->lock);
116 
117 }
118 #endif /*defined(FEATURE_QUEUED_DIRECT_IO)*/
119 
120 
121 #if !defined(_GEN_ARCH)
122 
123 #if defined(_ARCHMODE2)
124  #define  _GEN_ARCH _ARCHMODE2
125  #include "qdio.c"
126 #endif
127 
128 #if defined(_ARCHMODE3)
129  #undef   _GEN_ARCH
130  #define  _GEN_ARCH _ARCHMODE3
131  #include "qdio.c"
132 #endif
133 
134 #endif /*!defined(_GEN_ARCH)*/
135