aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_status.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/device_status.c')
-rw-r--r--drivers/s390/cio/device_status.c133
1 files changed, 65 insertions, 68 deletions
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 4a38993000f2..1b03c5423be2 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -29,9 +29,11 @@
29static void 29static void
30ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) 30ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
31{ 31{
32 if (!(irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK | 32 char dbf_text[15];
33 SCHN_STAT_CHN_CTRL_CHK | 33
34 SCHN_STAT_INTF_CTRL_CHK))) 34 if (!scsw_is_valid_cstat(&irb->scsw) ||
35 !(scsw_cstat(&irb->scsw) & (SCHN_STAT_CHN_DATA_CHK |
36 SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK)))
35 return; 37 return;
36 CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check " 38 CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check "
37 "received" 39 "received"
@@ -39,15 +41,10 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
39 ": %02X sch_stat : %02X\n", 41 ": %02X sch_stat : %02X\n",
40 cdev->private->dev_id.devno, cdev->private->schid.ssid, 42 cdev->private->dev_id.devno, cdev->private->schid.ssid,
41 cdev->private->schid.sch_no, 43 cdev->private->schid.sch_no,
42 irb->scsw.dstat, irb->scsw.cstat); 44 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw));
43 45 sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no);
44 if (irb->scsw.cc != 3) { 46 CIO_TRACE_EVENT(0, dbf_text);
45 char dbf_text[15]; 47 CIO_HEX_EVENT(0, irb, sizeof(struct irb));
46
47 sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no);
48 CIO_TRACE_EVENT(0, dbf_text);
49 CIO_HEX_EVENT(0, irb, sizeof (struct irb));
50 }
51} 48}
52 49
53/* 50/*
@@ -81,12 +78,12 @@ ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
81 * are condition that have to be met for the extended control 78 * are condition that have to be met for the extended control
82 * bit to have meaning. Sick. 79 * bit to have meaning. Sick.
83 */ 80 */
84 cdev->private->irb.scsw.ectl = 0; 81 cdev->private->irb.scsw.cmd.ectl = 0;
85 if ((irb->scsw.stctl & SCSW_STCTL_ALERT_STATUS) && 82 if ((irb->scsw.cmd.stctl & SCSW_STCTL_ALERT_STATUS) &&
86 !(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS)) 83 !(irb->scsw.cmd.stctl & SCSW_STCTL_INTER_STATUS))
87 cdev->private->irb.scsw.ectl = irb->scsw.ectl; 84 cdev->private->irb.scsw.cmd.ectl = irb->scsw.cmd.ectl;
88 /* Check if extended control word is valid. */ 85 /* Check if extended control word is valid. */
89 if (!cdev->private->irb.scsw.ectl) 86 if (!cdev->private->irb.scsw.cmd.ectl)
90 return; 87 return;
91 /* Copy concurrent sense / model dependent information. */ 88 /* Copy concurrent sense / model dependent information. */
92 memcpy (&cdev->private->irb.ecw, irb->ecw, sizeof (irb->ecw)); 89 memcpy (&cdev->private->irb.ecw, irb->ecw, sizeof (irb->ecw));
@@ -98,11 +95,12 @@ ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
98static int 95static int
99ccw_device_accumulate_esw_valid(struct irb *irb) 96ccw_device_accumulate_esw_valid(struct irb *irb)
100{ 97{
101 if (!irb->scsw.eswf && irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) 98 if (!irb->scsw.cmd.eswf &&
99 (irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND))
102 return 0; 100 return 0;
103 if (irb->scsw.stctl == 101 if (irb->scsw.cmd.stctl ==
104 (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) && 102 (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) &&
105 !(irb->scsw.actl & SCSW_ACTL_SUSPENDED)) 103 !(irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED))
106 return 0; 104 return 0;
107 return 1; 105 return 1;
108} 106}
@@ -125,7 +123,7 @@ ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)
125 cdev_irb->esw.esw1.lpum = irb->esw.esw1.lpum; 123 cdev_irb->esw.esw1.lpum = irb->esw.esw1.lpum;
126 124
127 /* Copy subchannel logout information if esw is of format 0. */ 125 /* Copy subchannel logout information if esw is of format 0. */
128 if (irb->scsw.eswf) { 126 if (irb->scsw.cmd.eswf) {
129 cdev_sublog = &cdev_irb->esw.esw0.sublog; 127 cdev_sublog = &cdev_irb->esw.esw0.sublog;
130 sublog = &irb->esw.esw0.sublog; 128 sublog = &irb->esw.esw0.sublog;
131 /* Copy extended status flags. */ 129 /* Copy extended status flags. */
@@ -134,7 +132,7 @@ ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)
134 * Copy fields that have a meaning for channel data check 132 * Copy fields that have a meaning for channel data check
135 * channel control check and interface control check. 133 * channel control check and interface control check.
136 */ 134 */
137 if (irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK | 135 if (irb->scsw.cmd.cstat & (SCHN_STAT_CHN_DATA_CHK |
138 SCHN_STAT_CHN_CTRL_CHK | 136 SCHN_STAT_CHN_CTRL_CHK |
139 SCHN_STAT_INTF_CTRL_CHK)) { 137 SCHN_STAT_INTF_CTRL_CHK)) {
140 /* Copy ancillary report bit. */ 138 /* Copy ancillary report bit. */
@@ -155,7 +153,7 @@ ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)
155 /* Copy i/o-error alert. */ 153 /* Copy i/o-error alert. */
156 cdev_sublog->ioerr = sublog->ioerr; 154 cdev_sublog->ioerr = sublog->ioerr;
157 /* Copy channel path timeout bit. */ 155 /* Copy channel path timeout bit. */
158 if (irb->scsw.cstat & SCHN_STAT_INTF_CTRL_CHK) 156 if (irb->scsw.cmd.cstat & SCHN_STAT_INTF_CTRL_CHK)
159 cdev_irb->esw.esw0.erw.cpt = irb->esw.esw0.erw.cpt; 157 cdev_irb->esw.esw0.erw.cpt = irb->esw.esw0.erw.cpt;
160 /* Copy failing storage address validity flag. */ 158 /* Copy failing storage address validity flag. */
161 cdev_irb->esw.esw0.erw.fsavf = irb->esw.esw0.erw.fsavf; 159 cdev_irb->esw.esw0.erw.fsavf = irb->esw.esw0.erw.fsavf;
@@ -200,24 +198,24 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
200 * If not, the remaining bit have no meaning and we must ignore them. 198 * If not, the remaining bit have no meaning and we must ignore them.
201 * The esw is not meaningful as well... 199 * The esw is not meaningful as well...
202 */ 200 */
203 if (!(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) 201 if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))
204 return; 202 return;
205 203
206 /* Check for channel checks and interface control checks. */ 204 /* Check for channel checks and interface control checks. */
207 ccw_device_msg_control_check(cdev, irb); 205 ccw_device_msg_control_check(cdev, irb);
208 206
209 /* Check for path not operational. */ 207 /* Check for path not operational. */
210 if (irb->scsw.pno && irb->scsw.fctl != 0 && 208 if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw))
211 (!(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS) ||
212 (irb->scsw.actl & SCSW_ACTL_SUSPENDED)))
213 ccw_device_path_notoper(cdev); 209 ccw_device_path_notoper(cdev);
214 210 /* No irb accumulation for transport mode irbs. */
211 if (scsw_is_tm(&irb->scsw)) {
212 memcpy(&cdev->private->irb, irb, sizeof(struct irb));
213 return;
214 }
215 /* 215 /*
216 * Don't accumulate unsolicited interrupts. 216 * Don't accumulate unsolicited interrupts.
217 */ 217 */
218 if ((irb->scsw.stctl == 218 if (!scsw_is_solicited(&irb->scsw))
219 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
220 (!irb->scsw.cc))
221 return; 219 return;
222 220
223 cdev_irb = &cdev->private->irb; 221 cdev_irb = &cdev->private->irb;
@@ -227,62 +225,63 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
227 * status at the subchannel has been cleared and we must not pass 225 * status at the subchannel has been cleared and we must not pass
228 * intermediate accumulated status to the device driver. 226 * intermediate accumulated status to the device driver.
229 */ 227 */
230 if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) 228 if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC)
231 memset(&cdev->private->irb, 0, sizeof(struct irb)); 229 memset(&cdev->private->irb, 0, sizeof(struct irb));
232 230
233 /* Copy bits which are valid only for the start function. */ 231 /* Copy bits which are valid only for the start function. */
234 if (irb->scsw.fctl & SCSW_FCTL_START_FUNC) { 232 if (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) {
235 /* Copy key. */ 233 /* Copy key. */
236 cdev_irb->scsw.key = irb->scsw.key; 234 cdev_irb->scsw.cmd.key = irb->scsw.cmd.key;
237 /* Copy suspend control bit. */ 235 /* Copy suspend control bit. */
238 cdev_irb->scsw.sctl = irb->scsw.sctl; 236 cdev_irb->scsw.cmd.sctl = irb->scsw.cmd.sctl;
239 /* Accumulate deferred condition code. */ 237 /* Accumulate deferred condition code. */
240 cdev_irb->scsw.cc |= irb->scsw.cc; 238 cdev_irb->scsw.cmd.cc |= irb->scsw.cmd.cc;
241 /* Copy ccw format bit. */ 239 /* Copy ccw format bit. */
242 cdev_irb->scsw.fmt = irb->scsw.fmt; 240 cdev_irb->scsw.cmd.fmt = irb->scsw.cmd.fmt;
243 /* Copy prefetch bit. */ 241 /* Copy prefetch bit. */
244 cdev_irb->scsw.pfch = irb->scsw.pfch; 242 cdev_irb->scsw.cmd.pfch = irb->scsw.cmd.pfch;
245 /* Copy initial-status-interruption-control. */ 243 /* Copy initial-status-interruption-control. */
246 cdev_irb->scsw.isic = irb->scsw.isic; 244 cdev_irb->scsw.cmd.isic = irb->scsw.cmd.isic;
247 /* Copy address limit checking control. */ 245 /* Copy address limit checking control. */
248 cdev_irb->scsw.alcc = irb->scsw.alcc; 246 cdev_irb->scsw.cmd.alcc = irb->scsw.cmd.alcc;
249 /* Copy suppress suspend bit. */ 247 /* Copy suppress suspend bit. */
250 cdev_irb->scsw.ssi = irb->scsw.ssi; 248 cdev_irb->scsw.cmd.ssi = irb->scsw.cmd.ssi;
251 } 249 }
252 250
253 /* Take care of the extended control bit and extended control word. */ 251 /* Take care of the extended control bit and extended control word. */
254 ccw_device_accumulate_ecw(cdev, irb); 252 ccw_device_accumulate_ecw(cdev, irb);
255 253
256 /* Accumulate function control. */ 254 /* Accumulate function control. */
257 cdev_irb->scsw.fctl |= irb->scsw.fctl; 255 cdev_irb->scsw.cmd.fctl |= irb->scsw.cmd.fctl;
258 /* Copy activity control. */ 256 /* Copy activity control. */
259 cdev_irb->scsw.actl= irb->scsw.actl; 257 cdev_irb->scsw.cmd.actl = irb->scsw.cmd.actl;
260 /* Accumulate status control. */ 258 /* Accumulate status control. */
261 cdev_irb->scsw.stctl |= irb->scsw.stctl; 259 cdev_irb->scsw.cmd.stctl |= irb->scsw.cmd.stctl;
262 /* 260 /*
263 * Copy ccw address if it is valid. This is a bit simplified 261 * Copy ccw address if it is valid. This is a bit simplified
264 * but should be close enough for all practical purposes. 262 * but should be close enough for all practical purposes.
265 */ 263 */
266 if ((irb->scsw.stctl & SCSW_STCTL_PRIM_STATUS) || 264 if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) ||
267 ((irb->scsw.stctl == 265 ((irb->scsw.cmd.stctl ==
268 (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND)) && 266 (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND)) &&
269 (irb->scsw.actl & SCSW_ACTL_DEVACT) && 267 (irb->scsw.cmd.actl & SCSW_ACTL_DEVACT) &&
270 (irb->scsw.actl & SCSW_ACTL_SCHACT)) || 268 (irb->scsw.cmd.actl & SCSW_ACTL_SCHACT)) ||
271 (irb->scsw.actl & SCSW_ACTL_SUSPENDED)) 269 (irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED))
272 cdev_irb->scsw.cpa = irb->scsw.cpa; 270 cdev_irb->scsw.cmd.cpa = irb->scsw.cmd.cpa;
273 /* Accumulate device status, but not the device busy flag. */ 271 /* Accumulate device status, but not the device busy flag. */
274 cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY; 272 cdev_irb->scsw.cmd.dstat &= ~DEV_STAT_BUSY;
275 /* dstat is not always valid. */ 273 /* dstat is not always valid. */
276 if (irb->scsw.stctl & 274 if (irb->scsw.cmd.stctl &
277 (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS 275 (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS
278 | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS)) 276 | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))
279 cdev_irb->scsw.dstat |= irb->scsw.dstat; 277 cdev_irb->scsw.cmd.dstat |= irb->scsw.cmd.dstat;
280 /* Accumulate subchannel status. */ 278 /* Accumulate subchannel status. */
281 cdev_irb->scsw.cstat |= irb->scsw.cstat; 279 cdev_irb->scsw.cmd.cstat |= irb->scsw.cmd.cstat;
282 /* Copy residual count if it is valid. */ 280 /* Copy residual count if it is valid. */
283 if ((irb->scsw.stctl & SCSW_STCTL_PRIM_STATUS) && 281 if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&
284 (irb->scsw.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN)) == 0) 282 (irb->scsw.cmd.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN))
285 cdev_irb->scsw.count = irb->scsw.count; 283 == 0)
284 cdev_irb->scsw.cmd.count = irb->scsw.cmd.count;
286 285
287 /* Take care of bits in the extended status word. */ 286 /* Take care of bits in the extended status word. */
288 ccw_device_accumulate_esw(cdev, irb); 287 ccw_device_accumulate_esw(cdev, irb);
@@ -299,7 +298,7 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
299 * sense facility available/supported when enabling the 298 * sense facility available/supported when enabling the
300 * concurrent sense facility. 299 * concurrent sense facility.
301 */ 300 */
302 if ((cdev_irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && 301 if ((cdev_irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
303 !(cdev_irb->esw.esw0.erw.cons)) 302 !(cdev_irb->esw.esw0.erw.cons))
304 cdev->private->flags.dosense = 1; 303 cdev->private->flags.dosense = 1;
305} 304}
@@ -317,7 +316,7 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
317 sch = to_subchannel(cdev->dev.parent); 316 sch = to_subchannel(cdev->dev.parent);
318 317
319 /* A sense is required, can we do it now ? */ 318 /* A sense is required, can we do it now ? */
320 if ((irb->scsw.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0) 319 if (scsw_actl(&irb->scsw) & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT))
321 /* 320 /*
322 * we received an Unit Check but we have no final 321 * we received an Unit Check but we have no final
323 * status yet, therefore we must delay the SENSE 322 * status yet, therefore we must delay the SENSE
@@ -355,20 +354,18 @@ ccw_device_accumulate_basic_sense(struct ccw_device *cdev, struct irb *irb)
355 * If not, the remaining bit have no meaning and we must ignore them. 354 * If not, the remaining bit have no meaning and we must ignore them.
356 * The esw is not meaningful as well... 355 * The esw is not meaningful as well...
357 */ 356 */
358 if (!(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) 357 if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))
359 return; 358 return;
360 359
361 /* Check for channel checks and interface control checks. */ 360 /* Check for channel checks and interface control checks. */
362 ccw_device_msg_control_check(cdev, irb); 361 ccw_device_msg_control_check(cdev, irb);
363 362
364 /* Check for path not operational. */ 363 /* Check for path not operational. */
365 if (irb->scsw.pno && irb->scsw.fctl != 0 && 364 if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw))
366 (!(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS) ||
367 (irb->scsw.actl & SCSW_ACTL_SUSPENDED)))
368 ccw_device_path_notoper(cdev); 365 ccw_device_path_notoper(cdev);
369 366
370 if (!(irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && 367 if (!(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
371 (irb->scsw.dstat & DEV_STAT_CHN_END)) { 368 (irb->scsw.cmd.dstat & DEV_STAT_CHN_END)) {
372 cdev->private->irb.esw.esw0.erw.cons = 1; 369 cdev->private->irb.esw.esw0.erw.cons = 1;
373 cdev->private->flags.dosense = 0; 370 cdev->private->flags.dosense = 0;
374 } 371 }
@@ -386,11 +383,11 @@ int
386ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb) 383ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb)
387{ 384{
388 ccw_device_accumulate_irb(cdev, irb); 385 ccw_device_accumulate_irb(cdev, irb);
389 if ((irb->scsw.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0) 386 if ((irb->scsw.cmd.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0)
390 return -EBUSY; 387 return -EBUSY;
391 /* Check for basic sense. */ 388 /* Check for basic sense. */
392 if (cdev->private->flags.dosense && 389 if (cdev->private->flags.dosense &&
393 !(irb->scsw.dstat & DEV_STAT_UNIT_CHECK)) { 390 !(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)) {
394 cdev->private->irb.esw.esw0.erw.cons = 1; 391 cdev->private->irb.esw.esw0.erw.cons = 1;
395 cdev->private->flags.dosense = 0; 392 cdev->private->flags.dosense = 0;
396 return 0; 393 return 0;