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