diff options
Diffstat (limited to 'drivers/s390/cio/device_pgid.c')
-rw-r--r-- | drivers/s390/cio/device_pgid.c | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 0adac8a67331..052832d03d38 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "cio_debug.h" | 22 | #include "cio_debug.h" |
23 | #include "css.h" | 23 | #include "css.h" |
24 | #include "device.h" | 24 | #include "device.h" |
25 | #include "ioasm.h" | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Start Sense Path Group ID helper function. Used in ccw_device_recog | 28 | * Start Sense Path Group ID helper function. Used in ccw_device_recog |
@@ -56,10 +57,10 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) | |||
56 | if (ret != -EACCES) | 57 | if (ret != -EACCES) |
57 | return ret; | 58 | return ret; |
58 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " | 59 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " |
59 | "%04x, lpm %02X, became 'not " | 60 | "0.%x.%04x, lpm %02X, became 'not " |
60 | "operational'\n", | 61 | "operational'\n", |
61 | cdev->private->devno, sch->irq, | 62 | cdev->private->devno, sch->schid.ssid, |
62 | cdev->private->imask); | 63 | sch->schid.sch_no, cdev->private->imask); |
63 | 64 | ||
64 | } | 65 | } |
65 | cdev->private->imask >>= 1; | 66 | cdev->private->imask >>= 1; |
@@ -105,10 +106,10 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
105 | return -EOPNOTSUPP; | 106 | return -EOPNOTSUPP; |
106 | } | 107 | } |
107 | if (irb->esw.esw0.erw.cons) { | 108 | if (irb->esw.esw0.erw.cons) { |
108 | CIO_MSG_EVENT(2, "SNID - device %04x, unit check, " | 109 | CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, " |
109 | "lpum %02X, cnt %02d, sns : " | 110 | "lpum %02X, cnt %02d, sns : " |
110 | "%02X%02X%02X%02X %02X%02X%02X%02X ...\n", | 111 | "%02X%02X%02X%02X %02X%02X%02X%02X ...\n", |
111 | cdev->private->devno, | 112 | cdev->private->ssid, cdev->private->devno, |
112 | irb->esw.esw0.sublog.lpum, | 113 | irb->esw.esw0.sublog.lpum, |
113 | irb->esw.esw0.erw.scnt, | 114 | irb->esw.esw0.erw.scnt, |
114 | irb->ecw[0], irb->ecw[1], | 115 | irb->ecw[0], irb->ecw[1], |
@@ -118,15 +119,17 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
118 | return -EAGAIN; | 119 | return -EAGAIN; |
119 | } | 120 | } |
120 | if (irb->scsw.cc == 3) { | 121 | if (irb->scsw.cc == 3) { |
121 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " | 122 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," |
122 | "%04x, lpm %02X, became 'not operational'\n", | 123 | " lpm %02X, became 'not operational'\n", |
123 | cdev->private->devno, sch->irq, sch->orb.lpm); | 124 | cdev->private->devno, sch->schid.ssid, |
125 | sch->schid.sch_no, sch->orb.lpm); | ||
124 | return -EACCES; | 126 | return -EACCES; |
125 | } | 127 | } |
126 | if (cdev->private->pgid.inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { | 128 | if (cdev->private->pgid.inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { |
127 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel %04x " | 129 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x " |
128 | "is reserved by someone else\n", | 130 | "is reserved by someone else\n", |
129 | cdev->private->devno, sch->irq); | 131 | cdev->private->devno, sch->schid.ssid, |
132 | sch->schid.sch_no); | ||
130 | return -EUSERS; | 133 | return -EUSERS; |
131 | } | 134 | } |
132 | return 0; | 135 | return 0; |
@@ -162,7 +165,7 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
162 | /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */ | 165 | /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */ |
163 | case 0: /* Sense Path Group ID successful. */ | 166 | case 0: /* Sense Path Group ID successful. */ |
164 | if (cdev->private->pgid.inf.ps.state1 == SNID_STATE1_RESET) | 167 | if (cdev->private->pgid.inf.ps.state1 == SNID_STATE1_RESET) |
165 | memcpy(&cdev->private->pgid, &global_pgid, | 168 | memcpy(&cdev->private->pgid, &css[0]->global_pgid, |
166 | sizeof(struct pgid)); | 169 | sizeof(struct pgid)); |
167 | ccw_device_sense_pgid_done(cdev, 0); | 170 | ccw_device_sense_pgid_done(cdev, 0); |
168 | break; | 171 | break; |
@@ -235,8 +238,9 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) | |||
235 | sch->lpm &= ~cdev->private->imask; | 238 | sch->lpm &= ~cdev->private->imask; |
236 | sch->vpm &= ~cdev->private->imask; | 239 | sch->vpm &= ~cdev->private->imask; |
237 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " | 240 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " |
238 | "%04x, lpm %02X, became 'not operational'\n", | 241 | "0.%x.%04x, lpm %02X, became 'not operational'\n", |
239 | cdev->private->devno, sch->irq, cdev->private->imask); | 242 | cdev->private->devno, sch->schid.ssid, |
243 | sch->schid.sch_no, cdev->private->imask); | ||
240 | return ret; | 244 | return ret; |
241 | } | 245 | } |
242 | 246 | ||
@@ -258,8 +262,10 @@ __ccw_device_check_pgid(struct ccw_device *cdev) | |||
258 | if (irb->ecw[0] & SNS0_CMD_REJECT) | 262 | if (irb->ecw[0] & SNS0_CMD_REJECT) |
259 | return -EOPNOTSUPP; | 263 | return -EOPNOTSUPP; |
260 | /* Hmm, whatever happened, try again. */ | 264 | /* Hmm, whatever happened, try again. */ |
261 | CIO_MSG_EVENT(2, "SPID - device %04x, unit check, cnt %02d, " | 265 | CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, " |
266 | "cnt %02d, " | ||
262 | "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n", | 267 | "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n", |
268 | cdev->private->ssid, | ||
263 | cdev->private->devno, irb->esw.esw0.erw.scnt, | 269 | cdev->private->devno, irb->esw.esw0.erw.scnt, |
264 | irb->ecw[0], irb->ecw[1], | 270 | irb->ecw[0], irb->ecw[1], |
265 | irb->ecw[2], irb->ecw[3], | 271 | irb->ecw[2], irb->ecw[3], |
@@ -268,10 +274,10 @@ __ccw_device_check_pgid(struct ccw_device *cdev) | |||
268 | return -EAGAIN; | 274 | return -EAGAIN; |
269 | } | 275 | } |
270 | if (irb->scsw.cc == 3) { | 276 | if (irb->scsw.cc == 3) { |
271 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " | 277 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," |
272 | "%04x, lpm %02X, became 'not operational'\n", | 278 | " lpm %02X, became 'not operational'\n", |
273 | cdev->private->devno, sch->irq, | 279 | cdev->private->devno, sch->schid.ssid, |
274 | cdev->private->imask); | 280 | sch->schid.sch_no, cdev->private->imask); |
275 | return -EACCES; | 281 | return -EACCES; |
276 | } | 282 | } |
277 | return 0; | 283 | return 0; |
@@ -364,8 +370,22 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
364 | void | 370 | void |
365 | ccw_device_verify_start(struct ccw_device *cdev) | 371 | ccw_device_verify_start(struct ccw_device *cdev) |
366 | { | 372 | { |
373 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | ||
374 | |||
367 | cdev->private->flags.pgid_single = 0; | 375 | cdev->private->flags.pgid_single = 0; |
368 | cdev->private->iretry = 5; | 376 | cdev->private->iretry = 5; |
377 | /* | ||
378 | * Update sch->lpm with current values to catch paths becoming | ||
379 | * available again. | ||
380 | */ | ||
381 | if (stsch(sch->schid, &sch->schib)) { | ||
382 | ccw_device_verify_done(cdev, -ENODEV); | ||
383 | return; | ||
384 | } | ||
385 | sch->lpm = sch->schib.pmcw.pim & | ||
386 | sch->schib.pmcw.pam & | ||
387 | sch->schib.pmcw.pom & | ||
388 | sch->opm; | ||
369 | __ccw_device_verify_start(cdev); | 389 | __ccw_device_verify_start(cdev); |
370 | } | 390 | } |
371 | 391 | ||