diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2008-07-14 03:58:51 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-07-14 04:02:08 -0400 |
commit | 83262d6349e60b9d10798d489719d80029c00798 (patch) | |
tree | f12bb266672c0e1df62b4194ea3618fda30f6b9a /drivers/s390/cio/cio.c | |
parent | 23d805b647db6c2063a13089497615efa9deacdd (diff) |
[S390] cio: provide functions for fcx enabled I/O
Provide functions for assembling and starting fcx enabled I/O request
blocks.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/cio.c')
-rw-r--r-- | drivers/s390/cio/cio.c | 81 |
1 files changed, 70 insertions, 11 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 40b2884126da..c24dfcd858da 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/chpid.h> | 25 | #include <asm/chpid.h> |
26 | #include <asm/airq.h> | 26 | #include <asm/airq.h> |
27 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
28 | #include <asm/fcx.h> | ||
28 | #include "cio.h" | 29 | #include "cio.h" |
29 | #include "css.h" | 30 | #include "css.h" |
30 | #include "chsc.h" | 31 | #include "chsc.h" |
@@ -167,30 +168,30 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ | |||
167 | { | 168 | { |
168 | char dbf_txt[15]; | 169 | char dbf_txt[15]; |
169 | int ccode; | 170 | int ccode; |
170 | struct orb *orb; | 171 | union orb *orb; |
171 | 172 | ||
172 | CIO_TRACE_EVENT(4, "stIO"); | 173 | CIO_TRACE_EVENT(4, "stIO"); |
173 | CIO_TRACE_EVENT(4, sch->dev.bus_id); | 174 | CIO_TRACE_EVENT(4, sch->dev.bus_id); |
174 | 175 | ||
175 | orb = &to_io_private(sch)->orb; | 176 | orb = &to_io_private(sch)->orb; |
176 | /* sch is always under 2G. */ | 177 | /* sch is always under 2G. */ |
177 | orb->intparm = (u32)(addr_t)sch; | 178 | orb->cmd.intparm = (u32)(addr_t)sch; |
178 | orb->fmt = 1; | 179 | orb->cmd.fmt = 1; |
179 | 180 | ||
180 | orb->pfch = sch->options.prefetch == 0; | 181 | orb->cmd.pfch = sch->options.prefetch == 0; |
181 | orb->spnd = sch->options.suspend; | 182 | orb->cmd.spnd = sch->options.suspend; |
182 | orb->ssic = sch->options.suspend && sch->options.inter; | 183 | orb->cmd.ssic = sch->options.suspend && sch->options.inter; |
183 | orb->lpm = (lpm != 0) ? lpm : sch->lpm; | 184 | orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm; |
184 | #ifdef CONFIG_64BIT | 185 | #ifdef CONFIG_64BIT |
185 | /* | 186 | /* |
186 | * for 64 bit we always support 64 bit IDAWs with 4k page size only | 187 | * for 64 bit we always support 64 bit IDAWs with 4k page size only |
187 | */ | 188 | */ |
188 | orb->c64 = 1; | 189 | orb->cmd.c64 = 1; |
189 | orb->i2k = 0; | 190 | orb->cmd.i2k = 0; |
190 | #endif | 191 | #endif |
191 | orb->key = key >> 4; | 192 | orb->cmd.key = key >> 4; |
192 | /* issue "Start Subchannel" */ | 193 | /* issue "Start Subchannel" */ |
193 | orb->cpa = (__u32) __pa(cpa); | 194 | orb->cmd.cpa = (__u32) __pa(cpa); |
194 | ccode = ssch(sch->schid, orb); | 195 | ccode = ssch(sch->schid, orb); |
195 | 196 | ||
196 | /* process condition code */ | 197 | /* process condition code */ |
@@ -1067,3 +1068,61 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) | |||
1067 | iplinfo->is_qdio = schib.pmcw.qf; | 1068 | iplinfo->is_qdio = schib.pmcw.qf; |
1068 | return 0; | 1069 | return 0; |
1069 | } | 1070 | } |
1071 | |||
1072 | /** | ||
1073 | * cio_tm_start_key - perform start function | ||
1074 | * @sch: subchannel on which to perform the start function | ||
1075 | * @tcw: transport-command word to be started | ||
1076 | * @lpm: mask of paths to use | ||
1077 | * @key: storage key to use for storage access | ||
1078 | * | ||
1079 | * Start the tcw on the given subchannel. Return zero on success, non-zero | ||
1080 | * otherwise. | ||
1081 | */ | ||
1082 | int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key) | ||
1083 | { | ||
1084 | int cc; | ||
1085 | union orb *orb = &to_io_private(sch)->orb; | ||
1086 | |||
1087 | memset(orb, 0, sizeof(union orb)); | ||
1088 | orb->tm.intparm = (u32) (addr_t) sch; | ||
1089 | orb->tm.key = key >> 4; | ||
1090 | orb->tm.b = 1; | ||
1091 | orb->tm.lpm = lpm ? lpm : sch->lpm; | ||
1092 | orb->tm.tcw = (u32) (addr_t) tcw; | ||
1093 | cc = ssch(sch->schid, orb); | ||
1094 | switch (cc) { | ||
1095 | case 0: | ||
1096 | return 0; | ||
1097 | case 1: | ||
1098 | case 2: | ||
1099 | return -EBUSY; | ||
1100 | default: | ||
1101 | return cio_start_handle_notoper(sch, lpm); | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | /** | ||
1106 | * cio_tm_intrg - perform interrogate function | ||
1107 | * @sch - subchannel on which to perform the interrogate function | ||
1108 | * | ||
1109 | * If the specified subchannel is running in transport-mode, perform the | ||
1110 | * interrogate function. Return zero on success, non-zero otherwie. | ||
1111 | */ | ||
1112 | int cio_tm_intrg(struct subchannel *sch) | ||
1113 | { | ||
1114 | int cc; | ||
1115 | |||
1116 | if (!to_io_private(sch)->orb.tm.b) | ||
1117 | return -EINVAL; | ||
1118 | cc = xsch(sch->schid); | ||
1119 | switch (cc) { | ||
1120 | case 0: | ||
1121 | case 2: | ||
1122 | return 0; | ||
1123 | case 1: | ||
1124 | return -EBUSY; | ||
1125 | default: | ||
1126 | return -ENODEV; | ||
1127 | } | ||
1128 | } | ||