diff options
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r-- | drivers/s390/cio/device.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 6d229f3523a0..51bd3687d163 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "ioasm.h" | 36 | #include "ioasm.h" |
37 | #include "io_sch.h" | 37 | #include "io_sch.h" |
38 | #include "blacklist.h" | 38 | #include "blacklist.h" |
39 | #include "chsc.h" | ||
39 | 40 | ||
40 | static struct timer_list recovery_timer; | 41 | static struct timer_list recovery_timer; |
41 | static DEFINE_SPINLOCK(recovery_lock); | 42 | static DEFINE_SPINLOCK(recovery_lock); |
@@ -486,9 +487,11 @@ static int online_store_handle_offline(struct ccw_device *cdev) | |||
486 | spin_lock_irq(cdev->ccwlock); | 487 | spin_lock_irq(cdev->ccwlock); |
487 | ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL); | 488 | ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL); |
488 | spin_unlock_irq(cdev->ccwlock); | 489 | spin_unlock_irq(cdev->ccwlock); |
489 | } else if (cdev->online && cdev->drv && cdev->drv->set_offline) | 490 | return 0; |
491 | } | ||
492 | if (cdev->drv && cdev->drv->set_offline) | ||
490 | return ccw_device_set_offline(cdev); | 493 | return ccw_device_set_offline(cdev); |
491 | return 0; | 494 | return -EINVAL; |
492 | } | 495 | } |
493 | 496 | ||
494 | static int online_store_recog_and_online(struct ccw_device *cdev) | 497 | static int online_store_recog_and_online(struct ccw_device *cdev) |
@@ -505,8 +508,8 @@ static int online_store_recog_and_online(struct ccw_device *cdev) | |||
505 | return -EAGAIN; | 508 | return -EAGAIN; |
506 | } | 509 | } |
507 | if (cdev->drv && cdev->drv->set_online) | 510 | if (cdev->drv && cdev->drv->set_online) |
508 | ccw_device_set_online(cdev); | 511 | return ccw_device_set_online(cdev); |
509 | return 0; | 512 | return -EINVAL; |
510 | } | 513 | } |
511 | 514 | ||
512 | static int online_store_handle_online(struct ccw_device *cdev, int force) | 515 | static int online_store_handle_online(struct ccw_device *cdev, int force) |
@@ -598,6 +601,25 @@ available_show (struct device *dev, struct device_attribute *attr, char *buf) | |||
598 | } | 601 | } |
599 | } | 602 | } |
600 | 603 | ||
604 | static ssize_t | ||
605 | initiate_logging(struct device *dev, struct device_attribute *attr, | ||
606 | const char *buf, size_t count) | ||
607 | { | ||
608 | struct subchannel *sch = to_subchannel(dev); | ||
609 | int rc; | ||
610 | |||
611 | rc = chsc_siosl(sch->schid); | ||
612 | if (rc < 0) { | ||
613 | pr_warning("Logging for subchannel 0.%x.%04x failed with " | ||
614 | "errno=%d\n", | ||
615 | sch->schid.ssid, sch->schid.sch_no, rc); | ||
616 | return rc; | ||
617 | } | ||
618 | pr_notice("Logging for subchannel 0.%x.%04x was triggered\n", | ||
619 | sch->schid.ssid, sch->schid.sch_no); | ||
620 | return count; | ||
621 | } | ||
622 | |||
601 | static DEVICE_ATTR(chpids, 0444, chpids_show, NULL); | 623 | static DEVICE_ATTR(chpids, 0444, chpids_show, NULL); |
602 | static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL); | 624 | static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL); |
603 | static DEVICE_ATTR(devtype, 0444, devtype_show, NULL); | 625 | static DEVICE_ATTR(devtype, 0444, devtype_show, NULL); |
@@ -605,10 +627,12 @@ static DEVICE_ATTR(cutype, 0444, cutype_show, NULL); | |||
605 | static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); | 627 | static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); |
606 | static DEVICE_ATTR(online, 0644, online_show, online_store); | 628 | static DEVICE_ATTR(online, 0644, online_show, online_store); |
607 | static DEVICE_ATTR(availability, 0444, available_show, NULL); | 629 | static DEVICE_ATTR(availability, 0444, available_show, NULL); |
630 | static DEVICE_ATTR(logging, 0200, NULL, initiate_logging); | ||
608 | 631 | ||
609 | static struct attribute *io_subchannel_attrs[] = { | 632 | static struct attribute *io_subchannel_attrs[] = { |
610 | &dev_attr_chpids.attr, | 633 | &dev_attr_chpids.attr, |
611 | &dev_attr_pimpampom.attr, | 634 | &dev_attr_pimpampom.attr, |
635 | &dev_attr_logging.attr, | ||
612 | NULL, | 636 | NULL, |
613 | }; | 637 | }; |
614 | 638 | ||
@@ -2036,6 +2060,21 @@ void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo) | |||
2036 | } | 2060 | } |
2037 | } | 2061 | } |
2038 | 2062 | ||
2063 | /** | ||
2064 | * ccw_device_siosl() - initiate logging | ||
2065 | * @cdev: ccw device | ||
2066 | * | ||
2067 | * This function is used to invoke model-dependent logging within the channel | ||
2068 | * subsystem. | ||
2069 | */ | ||
2070 | int ccw_device_siosl(struct ccw_device *cdev) | ||
2071 | { | ||
2072 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | ||
2073 | |||
2074 | return chsc_siosl(sch->schid); | ||
2075 | } | ||
2076 | EXPORT_SYMBOL_GPL(ccw_device_siosl); | ||
2077 | |||
2039 | MODULE_LICENSE("GPL"); | 2078 | MODULE_LICENSE("GPL"); |
2040 | EXPORT_SYMBOL(ccw_device_set_online); | 2079 | EXPORT_SYMBOL(ccw_device_set_online); |
2041 | EXPORT_SYMBOL(ccw_device_set_offline); | 2080 | EXPORT_SYMBOL(ccw_device_set_offline); |