4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
5 * Copyright (c) 2019 IBM Corp.
7 * Author(s): Jason J. Herne <jjherne@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or (at
10 * your option) any later version. See the COPYING file in the top-level
16 #include "s390-arch.h"
20 static char chsc_page
[PAGE_SIZE
] __attribute__((__aligned__(PAGE_SIZE
)));
22 static int __do_cio(SubChannelId schid
, uint32_t ccw_addr
, int fmt
, Irb
*irb
);
24 int enable_mss_facility(void)
27 ChscAreaSda
*sda_area
= (ChscAreaSda
*) chsc_page
;
29 memset(sda_area
, 0, PAGE_SIZE
);
30 sda_area
->request
.length
= 0x0400;
31 sda_area
->request
.code
= 0x0031;
32 sda_area
->operation_code
= 0x2;
35 if ((ret
== 0) && (sda_area
->response
.code
== 0x0001)) {
41 void enable_subchannel(SubChannelId schid
)
45 stsch_err(schid
, &schib
);
50 uint16_t cu_type(SubChannelId schid
)
55 sense_id_ccw
.cmd_code
= CCW_CMD_SENSE_ID
;
56 sense_id_ccw
.cda
= ptr2u32(&sense_data
);
57 sense_id_ccw
.count
= sizeof(sense_data
);
58 sense_id_ccw
.flags
|= CCW_FLAG_SLI
;
60 if (do_cio(schid
, CU_TYPE_UNKNOWN
, ptr2u32(&sense_id_ccw
), CCW_FMT1
)) {
61 panic("Failed to run SenseID CCw\n");
64 return sense_data
.cu_type
;
67 int basic_sense(SubChannelId schid
, uint16_t cutype
, void *sense_data
,
73 senseCcw
.cmd_code
= CCW_CMD_BASIC_SENSE
;
74 senseCcw
.cda
= ptr2u32(sense_data
);
75 senseCcw
.count
= data_size
;
77 return __do_cio(schid
, ptr2u32(&senseCcw
), CCW_FMT1
, &irb
);
80 static bool irb_error(Irb
*irb
)
82 if (irb
->scsw
.cstat
) {
85 return irb
->scsw
.dstat
!= (SCSW_DSTAT_DEVEND
| SCSW_DSTAT_CHEND
);
88 static void print_eckd_dasd_sense_data(SenseDataEckdDasd
*sd
)
92 if (sd
->config_info
& 0x8000) {
93 sclp_print("Eckd Dasd Sense Data (fmt 24-bytes):\n");
95 sclp_print("Eckd Dasd Sense Data (fmt 32-bytes):\n");
98 strcat(msgline
, " Sense Condition Flags :");
99 if (sd
->common_status
& SNS_STAT0_CMD_REJECT
) {
100 strcat(msgline
, " [Cmd-Reject]");
102 if (sd
->common_status
& SNS_STAT0_INTERVENTION_REQ
) {
103 strcat(msgline
, " [Intervention-Required]");
105 if (sd
->common_status
& SNS_STAT0_BUS_OUT_CHECK
) {
106 strcat(msgline
, " [Bus-Out-Parity-Check]");
108 if (sd
->common_status
& SNS_STAT0_EQUIPMENT_CHECK
) {
109 strcat(msgline
, " [Equipment-Check]");
111 if (sd
->common_status
& SNS_STAT0_DATA_CHECK
) {
112 strcat(msgline
, " [Data-Check]");
114 if (sd
->common_status
& SNS_STAT0_OVERRUN
) {
115 strcat(msgline
, " [Overrun]");
117 if (sd
->common_status
& SNS_STAT0_INCOMPL_DOMAIN
) {
118 strcat(msgline
, " [Incomplete-Domain]");
121 if (sd
->status
[0] & SNS_STAT1_PERM_ERR
) {
122 strcat(msgline
, " [Permanent-Error]");
124 if (sd
->status
[0] & SNS_STAT1_INV_TRACK_FORMAT
) {
125 strcat(msgline
, " [Invalid-Track-Fmt]");
127 if (sd
->status
[0] & SNS_STAT1_EOC
) {
128 strcat(msgline
, " [End-of-Cyl]");
130 if (sd
->status
[0] & SNS_STAT1_MESSAGE_TO_OPER
) {
131 strcat(msgline
, " [Operator-Msg]");
133 if (sd
->status
[0] & SNS_STAT1_NO_REC_FOUND
) {
134 strcat(msgline
, " [No-Record-Found]");
136 if (sd
->status
[0] & SNS_STAT1_FILE_PROTECTED
) {
137 strcat(msgline
, " [File-Protected]");
139 if (sd
->status
[0] & SNS_STAT1_WRITE_INHIBITED
) {
140 strcat(msgline
, " [Write-Inhibited]");
142 if (sd
->status
[0] & SNS_STAT1_IMPRECISE_END
) {
143 strcat(msgline
, " [Imprecise-Ending]");
146 if (sd
->status
[1] & SNS_STAT2_REQ_INH_WRITE
) {
147 strcat(msgline
, " [Req-Inhibit-Write]");
149 if (sd
->status
[1] & SNS_STAT2_CORRECTABLE
) {
150 strcat(msgline
, " [Correctable-Data-Check]");
152 if (sd
->status
[1] & SNS_STAT2_FIRST_LOG_ERR
) {
153 strcat(msgline
, " [First-Error-Log]");
155 if (sd
->status
[1] & SNS_STAT2_ENV_DATA_PRESENT
) {
156 strcat(msgline
, " [Env-Data-Present]");
158 if (sd
->status
[1] & SNS_STAT2_IMPRECISE_END
) {
159 strcat(msgline
, " [Imprecise-End]");
161 strcat(msgline
, "\n");
164 print_int(" Residual Count =", sd
->res_count
);
165 print_int(" Phys Drive ID =", sd
->phys_drive_id
);
166 print_int(" low cyl address =", sd
->low_cyl_addr
);
167 print_int(" head addr & hi cyl =", sd
->head_high_cyl_addr
);
168 print_int(" format/message =", sd
->fmt_msg
);
169 print_int(" fmt-dependent[0-7] =", sd
->fmt_dependent_info
[0]);
170 print_int(" fmt-dependent[8-15]=", sd
->fmt_dependent_info
[1]);
171 print_int(" prog action code =", sd
->program_action_code
);
172 print_int(" Configuration info =", sd
->config_info
);
173 print_int(" mcode / hi-cyl =", sd
->mcode_hicyl
);
174 print_int(" cyl & head addr [0]=", sd
->cyl_head_addr
[0]);
175 print_int(" cyl & head addr [1]=", sd
->cyl_head_addr
[1]);
176 print_int(" cyl & head addr [2]=", sd
->cyl_head_addr
[2]);
179 static void print_irb_err(Irb
*irb
)
181 uint64_t this_ccw
= *(uint64_t *)u32toptr(irb
->scsw
.cpa
);
182 uint64_t prev_ccw
= *(uint64_t *)u32toptr(irb
->scsw
.cpa
- 8);
185 sclp_print("Interrupt Response Block Data:\n");
187 strcat(msgline
, " Function Ctrl :");
188 if (irb
->scsw
.ctrl
& SCSW_FCTL_START_FUNC
) {
189 strcat(msgline
, " [Start]");
191 if (irb
->scsw
.ctrl
& SCSW_FCTL_HALT_FUNC
) {
192 strcat(msgline
, " [Halt]");
194 if (irb
->scsw
.ctrl
& SCSW_FCTL_CLEAR_FUNC
) {
195 strcat(msgline
, " [Clear]");
197 strcat(msgline
, "\n");
201 strcat(msgline
, " Activity Ctrl :");
202 if (irb
->scsw
.ctrl
& SCSW_ACTL_RESUME_PEND
) {
203 strcat(msgline
, " [Resume-Pending]");
205 if (irb
->scsw
.ctrl
& SCSW_ACTL_START_PEND
) {
206 strcat(msgline
, " [Start-Pending]");
208 if (irb
->scsw
.ctrl
& SCSW_ACTL_HALT_PEND
) {
209 strcat(msgline
, " [Halt-Pending]");
211 if (irb
->scsw
.ctrl
& SCSW_ACTL_CLEAR_PEND
) {
212 strcat(msgline
, " [Clear-Pending]");
214 if (irb
->scsw
.ctrl
& SCSW_ACTL_CH_ACTIVE
) {
215 strcat(msgline
, " [Channel-Active]");
217 if (irb
->scsw
.ctrl
& SCSW_ACTL_DEV_ACTIVE
) {
218 strcat(msgline
, " [Device-Active]");
220 if (irb
->scsw
.ctrl
& SCSW_ACTL_SUSPENDED
) {
221 strcat(msgline
, " [Suspended]");
223 strcat(msgline
, "\n");
227 strcat(msgline
, " Status Ctrl :");
228 if (irb
->scsw
.ctrl
& SCSW_SCTL_ALERT
) {
229 strcat(msgline
, " [Alert]");
231 if (irb
->scsw
.ctrl
& SCSW_SCTL_INTERMED
) {
232 strcat(msgline
, " [Intermediate]");
234 if (irb
->scsw
.ctrl
& SCSW_SCTL_PRIMARY
) {
235 strcat(msgline
, " [Primary]");
237 if (irb
->scsw
.ctrl
& SCSW_SCTL_SECONDARY
) {
238 strcat(msgline
, " [Secondary]");
240 if (irb
->scsw
.ctrl
& SCSW_SCTL_STATUS_PEND
) {
241 strcat(msgline
, " [Status-Pending]");
244 strcat(msgline
, "\n");
248 strcat(msgline
, " Device Status :");
249 if (irb
->scsw
.dstat
& SCSW_DSTAT_ATTN
) {
250 strcat(msgline
, " [Attention]");
252 if (irb
->scsw
.dstat
& SCSW_DSTAT_STATMOD
) {
253 strcat(msgline
, " [Status-Modifier]");
255 if (irb
->scsw
.dstat
& SCSW_DSTAT_CUEND
) {
256 strcat(msgline
, " [Ctrl-Unit-End]");
258 if (irb
->scsw
.dstat
& SCSW_DSTAT_BUSY
) {
259 strcat(msgline
, " [Busy]");
261 if (irb
->scsw
.dstat
& SCSW_DSTAT_CHEND
) {
262 strcat(msgline
, " [Channel-End]");
264 if (irb
->scsw
.dstat
& SCSW_DSTAT_DEVEND
) {
265 strcat(msgline
, " [Device-End]");
267 if (irb
->scsw
.dstat
& SCSW_DSTAT_UCHK
) {
268 strcat(msgline
, " [Unit-Check]");
270 if (irb
->scsw
.dstat
& SCSW_DSTAT_UEXCP
) {
271 strcat(msgline
, " [Unit-Exception]");
273 strcat(msgline
, "\n");
277 strcat(msgline
, " Channel Status :");
278 if (irb
->scsw
.cstat
& SCSW_CSTAT_PCINT
) {
279 strcat(msgline
, " [Program-Ctrl-Interruption]");
281 if (irb
->scsw
.cstat
& SCSW_CSTAT_BADLEN
) {
282 strcat(msgline
, " [Incorrect-Length]");
284 if (irb
->scsw
.cstat
& SCSW_CSTAT_PROGCHK
) {
285 strcat(msgline
, " [Program-Check]");
287 if (irb
->scsw
.cstat
& SCSW_CSTAT_PROTCHK
) {
288 strcat(msgline
, " [Protection-Check]");
290 if (irb
->scsw
.cstat
& SCSW_CSTAT_CHDCHK
) {
291 strcat(msgline
, " [Channel-Data-Check]");
293 if (irb
->scsw
.cstat
& SCSW_CSTAT_CHCCHK
) {
294 strcat(msgline
, " [Channel-Ctrl-Check]");
296 if (irb
->scsw
.cstat
& SCSW_CSTAT_ICCHK
) {
297 strcat(msgline
, " [Interface-Ctrl-Check]");
299 if (irb
->scsw
.cstat
& SCSW_CSTAT_CHAINCHK
) {
300 strcat(msgline
, " [Chaining-Check]");
302 strcat(msgline
, "\n");
305 print_int(" cpa=", irb
->scsw
.cpa
);
306 print_int(" prev_ccw=", prev_ccw
);
307 print_int(" this_ccw=", this_ccw
);
311 * Handles executing ssch, tsch and returns the irb obtained from tsch.
312 * Returns 0 on success, -1 if unexpected status pending and we need to retry,
313 * otherwise returns condition code from ssch/tsch for error cases.
315 static int __do_cio(SubChannelId schid
, uint32_t ccw_addr
, int fmt
, Irb
*irb
)
320 IPL_assert(fmt
== 0 || fmt
== 1, "Invalid ccw format");
322 /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
324 IPL_assert(ccw_addr
<= 0xFFFFFF - 8, "Invalid ccw address");
328 orb
.pfch
= 1; /* QEMU's cio implementation requires prefetch */
329 orb
.c64
= 1; /* QEMU's cio implementation requires 64-bit idaws */
330 orb
.lpm
= 0xFF; /* All paths allowed */
333 rc
= ssch(schid
, &orb
);
334 if (rc
== 1 || rc
== 2) {
335 /* Subchannel status pending or busy. Eat status and ask for retry. */
340 print_int("ssch failed with cc=", rc
);
347 rc
= tsch(schid
, irb
);
349 print_int("tsch failed with cc=", rc
);
356 * Executes a channel program at a given subchannel. The request to run the
357 * channel program is sent to the subchannel, we then wait for the interrupt
358 * signaling completion of the I/O operation(s) performed by the channel
359 * program. Lastly we verify that the i/o operation completed without error and
360 * that the interrupt we received was for the subchannel used to run the
363 * Note: This function assumes it is running in an environment where no other
364 * cpus are generating or receiving I/O interrupts. So either run it in a
365 * single-cpu environment or make sure all other cpus are not doing I/O and
366 * have I/O interrupts masked off. We also assume that only one device is
367 * active (generating i/o interrupts).
369 * Returns non-zero on error.
371 int do_cio(SubChannelId schid
, uint16_t cutype
, uint32_t ccw_addr
, int fmt
)
374 SenseDataEckdDasd sd
;
378 rc
= __do_cio(schid
, ccw_addr
, fmt
, &irb
);
385 /* ssch/tsch error. Message already reported by __do_cio */
389 if (!irb_error(&irb
)) {
394 * Unexpected unit check, or interface-control-check. Use sense to
395 * clear (unit check only) then retry.
397 if ((unit_check(&irb
) || iface_ctrl_check(&irb
)) && retries
<= 2) {
398 if (unit_check(&irb
)) {
399 basic_sense(schid
, cutype
, &sd
, sizeof(sd
));
405 sclp_print("cio device error\n");
406 print_int(" ssid ", schid
.ssid
);
407 print_int(" cssid ", schid
.cssid
);
408 print_int(" sch_no", schid
.sch_no
);
409 print_int(" ctrl-unit type", cutype
);
412 if (cutype
== CU_TYPE_DASD_3990
|| cutype
== CU_TYPE_DASD_2107
||
413 cutype
== CU_TYPE_UNKNOWN
) {
414 if (!basic_sense(schid
, cutype
, &sd
, sizeof(sd
))) {
415 print_eckd_dasd_sense_data(&sd
);