1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright IBM Corp. 2002 |
4 | * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) |
5 | * Martin Schwidefsky (schwidefsky@de.ibm.com) |
6 | * |
7 | * Status accumulation and basic sense functions. |
8 | */ |
9 | |
10 | #include <linux/module.h> |
11 | #include <linux/init.h> |
12 | #include <linux/io.h> |
13 | |
14 | #include <asm/ccwdev.h> |
15 | #include <asm/cio.h> |
16 | |
17 | #include "cio.h" |
18 | #include "cio_debug.h" |
19 | #include "css.h" |
20 | #include "device.h" |
21 | #include "ioasm.h" |
22 | #include "io_sch.h" |
23 | |
24 | /* |
25 | * Check for any kind of channel or interface control check but don't |
26 | * issue the message for the console device |
27 | */ |
28 | static void |
29 | ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) |
30 | { |
31 | struct subchannel *sch = to_subchannel(cdev->dev.parent); |
32 | char dbf_text[15]; |
33 | |
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))) |
37 | return; |
38 | CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check " |
39 | "received" |
40 | " ... device %04x on subchannel 0.%x.%04x, dev_stat " |
41 | ": %02X sch_stat : %02X\n" , |
42 | cdev->private->dev_id.devno, sch->schid.ssid, |
43 | sch->schid.sch_no, |
44 | scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw)); |
45 | sprintf(buf: dbf_text, fmt: "chk%x" , sch->schid.sch_no); |
46 | CIO_TRACE_EVENT(0, dbf_text); |
47 | CIO_HEX_EVENT(0, irb, sizeof(struct irb)); |
48 | } |
49 | |
50 | /* |
51 | * Some paths became not operational (pno bit in scsw is set). |
52 | */ |
53 | static void |
54 | ccw_device_path_notoper(struct ccw_device *cdev) |
55 | { |
56 | struct subchannel *sch; |
57 | |
58 | sch = to_subchannel(cdev->dev.parent); |
59 | if (cio_update_schib(sch)) |
60 | goto doverify; |
61 | |
62 | CIO_MSG_EVENT(0, "%s(0.%x.%04x) - path(s) %02x are " |
63 | "not operational \n" , __func__, |
64 | sch->schid.ssid, sch->schid.sch_no, |
65 | sch->schib.pmcw.pnom); |
66 | |
67 | sch->lpm &= ~sch->schib.pmcw.pnom; |
68 | doverify: |
69 | cdev->private->flags.doverify = 1; |
70 | } |
71 | |
72 | /* |
73 | * Copy valid bits from the extended control word to device irb. |
74 | */ |
75 | static void |
76 | ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb) |
77 | { |
78 | /* |
79 | * Copy extended control bit if it is valid... yes there |
80 | * are condition that have to be met for the extended control |
81 | * bit to have meaning. Sick. |
82 | */ |
83 | cdev->private->dma_area->irb.scsw.cmd.ectl = 0; |
84 | if ((irb->scsw.cmd.stctl & SCSW_STCTL_ALERT_STATUS) && |
85 | !(irb->scsw.cmd.stctl & SCSW_STCTL_INTER_STATUS)) |
86 | cdev->private->dma_area->irb.scsw.cmd.ectl = irb->scsw.cmd.ectl; |
87 | /* Check if extended control word is valid. */ |
88 | if (!cdev->private->dma_area->irb.scsw.cmd.ectl) |
89 | return; |
90 | /* Copy concurrent sense / model dependent information. */ |
91 | memcpy(&cdev->private->dma_area->irb.ecw, irb->ecw, sizeof(irb->ecw)); |
92 | } |
93 | |
94 | /* |
95 | * Check if extended status word is valid. |
96 | */ |
97 | static int |
98 | ccw_device_accumulate_esw_valid(struct irb *irb) |
99 | { |
100 | if (!irb->scsw.cmd.eswf && |
101 | (irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND)) |
102 | return 0; |
103 | if (irb->scsw.cmd.stctl == |
104 | (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) && |
105 | !(irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED)) |
106 | return 0; |
107 | return 1; |
108 | } |
109 | |
110 | /* |
111 | * Copy valid bits from the extended status word to device irb. |
112 | */ |
113 | static void |
114 | ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb) |
115 | { |
116 | struct irb *cdev_irb; |
117 | struct sublog *cdev_sublog, *sublog; |
118 | |
119 | if (!ccw_device_accumulate_esw_valid(irb)) |
120 | return; |
121 | |
122 | cdev_irb = &cdev->private->dma_area->irb; |
123 | |
124 | /* Copy last path used mask. */ |
125 | cdev_irb->esw.esw1.lpum = irb->esw.esw1.lpum; |
126 | |
127 | /* Copy subchannel logout information if esw is of format 0. */ |
128 | if (irb->scsw.cmd.eswf) { |
129 | cdev_sublog = &cdev_irb->esw.esw0.sublog; |
130 | sublog = &irb->esw.esw0.sublog; |
131 | /* Copy extended status flags. */ |
132 | cdev_sublog->esf = sublog->esf; |
133 | /* |
134 | * Copy fields that have a meaning for channel data check |
135 | * channel control check and interface control check. |
136 | */ |
137 | if (irb->scsw.cmd.cstat & (SCHN_STAT_CHN_DATA_CHK | |
138 | SCHN_STAT_CHN_CTRL_CHK | |
139 | SCHN_STAT_INTF_CTRL_CHK)) { |
140 | /* Copy ancillary report bit. */ |
141 | cdev_sublog->arep = sublog->arep; |
142 | /* Copy field-validity-flags. */ |
143 | cdev_sublog->fvf = sublog->fvf; |
144 | /* Copy storage access code. */ |
145 | cdev_sublog->sacc = sublog->sacc; |
146 | /* Copy termination code. */ |
147 | cdev_sublog->termc = sublog->termc; |
148 | /* Copy sequence code. */ |
149 | cdev_sublog->seqc = sublog->seqc; |
150 | } |
151 | /* Copy device status check. */ |
152 | cdev_sublog->devsc = sublog->devsc; |
153 | /* Copy secondary error. */ |
154 | cdev_sublog->serr = sublog->serr; |
155 | /* Copy i/o-error alert. */ |
156 | cdev_sublog->ioerr = sublog->ioerr; |
157 | /* Copy channel path timeout bit. */ |
158 | if (irb->scsw.cmd.cstat & SCHN_STAT_INTF_CTRL_CHK) |
159 | cdev_irb->esw.esw0.erw.cpt = irb->esw.esw0.erw.cpt; |
160 | /* Copy failing storage address validity flag. */ |
161 | cdev_irb->esw.esw0.erw.fsavf = irb->esw.esw0.erw.fsavf; |
162 | if (cdev_irb->esw.esw0.erw.fsavf) { |
163 | /* ... and copy the failing storage address. */ |
164 | memcpy(cdev_irb->esw.esw0.faddr, irb->esw.esw0.faddr, |
165 | sizeof (irb->esw.esw0.faddr)); |
166 | /* ... and copy the failing storage address format. */ |
167 | cdev_irb->esw.esw0.erw.fsaf = irb->esw.esw0.erw.fsaf; |
168 | } |
169 | /* Copy secondary ccw address validity bit. */ |
170 | cdev_irb->esw.esw0.erw.scavf = irb->esw.esw0.erw.scavf; |
171 | if (irb->esw.esw0.erw.scavf) |
172 | /* ... and copy the secondary ccw address. */ |
173 | cdev_irb->esw.esw0.saddr = irb->esw.esw0.saddr; |
174 | |
175 | } |
176 | /* FIXME: DCTI for format 2? */ |
177 | |
178 | /* Copy authorization bit. */ |
179 | cdev_irb->esw.esw0.erw.auth = irb->esw.esw0.erw.auth; |
180 | /* Copy path verification required flag. */ |
181 | cdev_irb->esw.esw0.erw.pvrf = irb->esw.esw0.erw.pvrf; |
182 | if (irb->esw.esw0.erw.pvrf) |
183 | cdev->private->flags.doverify = 1; |
184 | /* Copy concurrent sense bit. */ |
185 | cdev_irb->esw.esw0.erw.cons = irb->esw.esw0.erw.cons; |
186 | if (irb->esw.esw0.erw.cons) |
187 | cdev_irb->esw.esw0.erw.scnt = irb->esw.esw0.erw.scnt; |
188 | } |
189 | |
190 | /* |
191 | * Accumulate status from irb to devstat. |
192 | */ |
193 | void |
194 | ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) |
195 | { |
196 | struct irb *cdev_irb; |
197 | |
198 | /* |
199 | * Check if the status pending bit is set in stctl. |
200 | * If not, the remaining bit have no meaning and we must ignore them. |
201 | * The esw is not meaningful as well... |
202 | */ |
203 | if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) |
204 | return; |
205 | |
206 | /* Check for channel checks and interface control checks. */ |
207 | ccw_device_msg_control_check(cdev, irb); |
208 | |
209 | /* Check for path not operational. */ |
210 | if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw)) |
211 | ccw_device_path_notoper(cdev); |
212 | /* No irb accumulation for transport mode irbs. */ |
213 | if (scsw_is_tm(&irb->scsw)) { |
214 | memcpy(&cdev->private->dma_area->irb, irb, sizeof(struct irb)); |
215 | return; |
216 | } |
217 | /* |
218 | * Don't accumulate unsolicited interrupts. |
219 | */ |
220 | if (!scsw_is_solicited(&irb->scsw)) |
221 | return; |
222 | |
223 | cdev_irb = &cdev->private->dma_area->irb; |
224 | |
225 | /* |
226 | * If the clear function had been performed, all formerly pending |
227 | * status at the subchannel has been cleared and we must not pass |
228 | * intermediate accumulated status to the device driver. |
229 | */ |
230 | if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) |
231 | memset(&cdev->private->dma_area->irb, 0, sizeof(struct irb)); |
232 | |
233 | /* Copy bits which are valid only for the start function. */ |
234 | if (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) { |
235 | /* Copy key. */ |
236 | cdev_irb->scsw.cmd.key = irb->scsw.cmd.key; |
237 | /* Copy suspend control bit. */ |
238 | cdev_irb->scsw.cmd.sctl = irb->scsw.cmd.sctl; |
239 | /* Accumulate deferred condition code. */ |
240 | cdev_irb->scsw.cmd.cc |= irb->scsw.cmd.cc; |
241 | /* Copy ccw format bit. */ |
242 | cdev_irb->scsw.cmd.fmt = irb->scsw.cmd.fmt; |
243 | /* Copy prefetch bit. */ |
244 | cdev_irb->scsw.cmd.pfch = irb->scsw.cmd.pfch; |
245 | /* Copy initial-status-interruption-control. */ |
246 | cdev_irb->scsw.cmd.isic = irb->scsw.cmd.isic; |
247 | /* Copy address limit checking control. */ |
248 | cdev_irb->scsw.cmd.alcc = irb->scsw.cmd.alcc; |
249 | /* Copy suppress suspend bit. */ |
250 | cdev_irb->scsw.cmd.ssi = irb->scsw.cmd.ssi; |
251 | } |
252 | |
253 | /* Take care of the extended control bit and extended control word. */ |
254 | ccw_device_accumulate_ecw(cdev, irb); |
255 | |
256 | /* Accumulate function control. */ |
257 | cdev_irb->scsw.cmd.fctl |= irb->scsw.cmd.fctl; |
258 | /* Copy activity control. */ |
259 | cdev_irb->scsw.cmd.actl = irb->scsw.cmd.actl; |
260 | /* Accumulate status control. */ |
261 | cdev_irb->scsw.cmd.stctl |= irb->scsw.cmd.stctl; |
262 | /* |
263 | * Copy ccw address if it is valid. This is a bit simplified |
264 | * but should be close enough for all practical purposes. |
265 | */ |
266 | if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) || |
267 | ((irb->scsw.cmd.stctl == |
268 | (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND)) && |
269 | (irb->scsw.cmd.actl & SCSW_ACTL_DEVACT) && |
270 | (irb->scsw.cmd.actl & SCSW_ACTL_SCHACT)) || |
271 | (irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED)) |
272 | cdev_irb->scsw.cmd.cpa = irb->scsw.cmd.cpa; |
273 | /* Accumulate device status, but not the device busy flag. */ |
274 | cdev_irb->scsw.cmd.dstat &= ~DEV_STAT_BUSY; |
275 | /* dstat is not always valid. */ |
276 | if (irb->scsw.cmd.stctl & |
277 | (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS |
278 | | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS)) |
279 | cdev_irb->scsw.cmd.dstat |= irb->scsw.cmd.dstat; |
280 | /* Accumulate subchannel status. */ |
281 | cdev_irb->scsw.cmd.cstat |= irb->scsw.cmd.cstat; |
282 | /* Copy residual count if it is valid. */ |
283 | if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) && |
284 | (irb->scsw.cmd.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN)) |
285 | == 0) |
286 | cdev_irb->scsw.cmd.count = irb->scsw.cmd.count; |
287 | |
288 | /* Take care of bits in the extended status word. */ |
289 | ccw_device_accumulate_esw(cdev, irb); |
290 | |
291 | /* |
292 | * Check whether we must issue a SENSE CCW ourselves if there is no |
293 | * concurrent sense facility installed for the subchannel. |
294 | * No sense is required if no delayed sense is pending |
295 | * and we did not get a unit check without sense information. |
296 | * |
297 | * Note: We should check for ioinfo[irq]->flags.consns but VM |
298 | * violates the ESA/390 architecture and doesn't present an |
299 | * operand exception for virtual devices without concurrent |
300 | * sense facility available/supported when enabling the |
301 | * concurrent sense facility. |
302 | */ |
303 | if ((cdev_irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && |
304 | !(cdev_irb->esw.esw0.erw.cons)) |
305 | cdev->private->flags.dosense = 1; |
306 | } |
307 | |
308 | /* |
309 | * Do a basic sense. |
310 | */ |
311 | int |
312 | ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) |
313 | { |
314 | struct subchannel *sch; |
315 | struct ccw1 *sense_ccw; |
316 | int rc; |
317 | |
318 | sch = to_subchannel(cdev->dev.parent); |
319 | |
320 | /* A sense is required, can we do it now ? */ |
321 | if (scsw_actl(&irb->scsw) & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) |
322 | /* |
323 | * we received an Unit Check but we have no final |
324 | * status yet, therefore we must delay the SENSE |
325 | * processing. We must not report this intermediate |
326 | * status to the device interrupt handler. |
327 | */ |
328 | return -EBUSY; |
329 | |
330 | /* |
331 | * We have ending status but no sense information. Do a basic sense. |
332 | */ |
333 | sense_ccw = &to_io_private(sch)->dma_area->sense_ccw; |
334 | sense_ccw->cmd_code = CCW_CMD_BASIC_SENSE; |
335 | sense_ccw->cda = virt_to_phys(address: cdev->private->dma_area->irb.ecw); |
336 | sense_ccw->count = SENSE_MAX_COUNT; |
337 | sense_ccw->flags = CCW_FLAG_SLI; |
338 | |
339 | rc = cio_start(sch, sense_ccw, 0xff); |
340 | if (rc == -ENODEV || rc == -EACCES) |
341 | dev_fsm_event(cdev, dev_event: DEV_EVENT_VERIFY); |
342 | return rc; |
343 | } |
344 | |
345 | /* |
346 | * Add information from basic sense to devstat. |
347 | */ |
348 | void |
349 | ccw_device_accumulate_basic_sense(struct ccw_device *cdev, struct irb *irb) |
350 | { |
351 | /* |
352 | * Check if the status pending bit is set in stctl. |
353 | * If not, the remaining bit have no meaning and we must ignore them. |
354 | * The esw is not meaningful as well... |
355 | */ |
356 | if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) |
357 | return; |
358 | |
359 | /* Check for channel checks and interface control checks. */ |
360 | ccw_device_msg_control_check(cdev, irb); |
361 | |
362 | /* Check for path not operational. */ |
363 | if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw)) |
364 | ccw_device_path_notoper(cdev); |
365 | |
366 | if (!(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && |
367 | (irb->scsw.cmd.dstat & DEV_STAT_CHN_END)) { |
368 | cdev->private->dma_area->irb.esw.esw0.erw.cons = 1; |
369 | cdev->private->flags.dosense = 0; |
370 | } |
371 | /* Check if path verification is required. */ |
372 | if (ccw_device_accumulate_esw_valid(irb) && |
373 | irb->esw.esw0.erw.pvrf) |
374 | cdev->private->flags.doverify = 1; |
375 | } |
376 | |
377 | /* |
378 | * This function accumulates the status into the private devstat and |
379 | * starts a basic sense if one is needed. |
380 | */ |
381 | int |
382 | ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb) |
383 | { |
384 | ccw_device_accumulate_irb(cdev, irb); |
385 | if ((irb->scsw.cmd.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0) |
386 | return -EBUSY; |
387 | /* Check for basic sense. */ |
388 | if (cdev->private->flags.dosense && |
389 | !(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)) { |
390 | cdev->private->dma_area->irb.esw.esw0.erw.cons = 1; |
391 | cdev->private->flags.dosense = 0; |
392 | return 0; |
393 | } |
394 | if (cdev->private->flags.dosense) { |
395 | ccw_device_do_sense(cdev, irb); |
396 | return -EBUSY; |
397 | } |
398 | return 0; |
399 | } |
400 | |
401 | |