diff options
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r-- | drivers/s390/cio/chsc.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index a01f3bba4a7b..c28444af0919 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -238,8 +238,6 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
238 | /* Check for single path devices. */ | 238 | /* Check for single path devices. */ |
239 | if (sch->schib.pmcw.pim == 0x80) | 239 | if (sch->schib.pmcw.pim == 0x80) |
240 | goto out_unreg; | 240 | goto out_unreg; |
241 | if (sch->vpm == mask) | ||
242 | goto out_unreg; | ||
243 | 241 | ||
244 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && | 242 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && |
245 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && | 243 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && |
@@ -258,6 +256,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
258 | /* trigger path verification. */ | 256 | /* trigger path verification. */ |
259 | if (sch->driver && sch->driver->verify) | 257 | if (sch->driver && sch->driver->verify) |
260 | sch->driver->verify(&sch->dev); | 258 | sch->driver->verify(&sch->dev); |
259 | else if (sch->vpm == mask) | ||
260 | goto out_unreg; | ||
261 | out_unlock: | 261 | out_unlock: |
262 | spin_unlock_irq(&sch->lock); | 262 | spin_unlock_irq(&sch->lock); |
263 | return 0; | 263 | return 0; |
@@ -1391,10 +1391,8 @@ new_channel_path(int chpid) | |||
1391 | /* fill in status, etc. */ | 1391 | /* fill in status, etc. */ |
1392 | chp->id = chpid; | 1392 | chp->id = chpid; |
1393 | chp->state = 1; | 1393 | chp->state = 1; |
1394 | chp->dev = (struct device) { | 1394 | chp->dev.parent = &css[0]->device; |
1395 | .parent = &css[0]->device, | 1395 | chp->dev.release = chp_release; |
1396 | .release = chp_release, | ||
1397 | }; | ||
1398 | snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid); | 1396 | snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid); |
1399 | 1397 | ||
1400 | /* Obtain channel path description and fill it in. */ | 1398 | /* Obtain channel path description and fill it in. */ |
@@ -1464,6 +1462,40 @@ chsc_get_chp_desc(struct subchannel *sch, int chp_no) | |||
1464 | return desc; | 1462 | return desc; |
1465 | } | 1463 | } |
1466 | 1464 | ||
1465 | static int reset_channel_path(struct channel_path *chp) | ||
1466 | { | ||
1467 | int cc; | ||
1468 | |||
1469 | cc = rchp(chp->id); | ||
1470 | switch (cc) { | ||
1471 | case 0: | ||
1472 | return 0; | ||
1473 | case 2: | ||
1474 | return -EBUSY; | ||
1475 | default: | ||
1476 | return -ENODEV; | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | static void reset_channel_paths_css(struct channel_subsystem *css) | ||
1481 | { | ||
1482 | int i; | ||
1483 | |||
1484 | for (i = 0; i <= __MAX_CHPID; i++) { | ||
1485 | if (css->chps[i]) | ||
1486 | reset_channel_path(css->chps[i]); | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1490 | void cio_reset_channel_paths(void) | ||
1491 | { | ||
1492 | int i; | ||
1493 | |||
1494 | for (i = 0; i <= __MAX_CSSID; i++) { | ||
1495 | if (css[i] && css[i]->valid) | ||
1496 | reset_channel_paths_css(css[i]); | ||
1497 | } | ||
1498 | } | ||
1467 | 1499 | ||
1468 | static int __init | 1500 | static int __init |
1469 | chsc_alloc_sei_area(void) | 1501 | chsc_alloc_sei_area(void) |