aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r--drivers/s390/cio/device.c47
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
40static struct timer_list recovery_timer; 41static struct timer_list recovery_timer;
41static DEFINE_SPINLOCK(recovery_lock); 42static 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
494static int online_store_recog_and_online(struct ccw_device *cdev) 497static 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
512static int online_store_handle_online(struct ccw_device *cdev, int force) 515static 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
604static ssize_t
605initiate_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
601static DEVICE_ATTR(chpids, 0444, chpids_show, NULL); 623static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
602static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL); 624static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
603static DEVICE_ATTR(devtype, 0444, devtype_show, NULL); 625static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
@@ -605,10 +627,12 @@ static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
605static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); 627static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
606static DEVICE_ATTR(online, 0644, online_show, online_store); 628static DEVICE_ATTR(online, 0644, online_show, online_store);
607static DEVICE_ATTR(availability, 0444, available_show, NULL); 629static DEVICE_ATTR(availability, 0444, available_show, NULL);
630static DEVICE_ATTR(logging, 0200, NULL, initiate_logging);
608 631
609static struct attribute *io_subchannel_attrs[] = { 632static 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 */
2070int 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}
2076EXPORT_SYMBOL_GPL(ccw_device_siosl);
2077
2039MODULE_LICENSE("GPL"); 2078MODULE_LICENSE("GPL");
2040EXPORT_SYMBOL(ccw_device_set_online); 2079EXPORT_SYMBOL(ccw_device_set_online);
2041EXPORT_SYMBOL(ccw_device_set_offline); 2080EXPORT_SYMBOL(ccw_device_set_offline);