diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2008-10-10 21:33:06 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-10-10 21:33:47 +0200 |
commit | ecf5d9ef68b868b293b40b89615a92de7310d065 (patch) | |
tree | ec92f05f79e222075e2425129e15b0ee9131364e /drivers/s390/cio/device.c | |
parent | 46fbe4e46ddb88805245a24f684400b50ead68a7 (diff) | |
download | kernel_samsung_tuna-ecf5d9ef68b868b293b40b89615a92de7310d065.tar.gz kernel_samsung_tuna-ecf5d9ef68b868b293b40b89615a92de7310d065.tar.bz2 kernel_samsung_tuna-ecf5d9ef68b868b293b40b89615a92de7310d065.zip |
[S390] cio: introduce purge function for /proc/cio_ignore
Allow users to remove blacklisted ccw devices by using the
/proc/cio_ignore interface:
echo purge > /proc/cio_ignore
will remove all devices which are offline and blacklisted.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r-- | drivers/s390/cio/device.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 38a79ecfc74..8575d263b13 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -31,6 +31,7 @@ #include "device.h" #include "ioasm.h" #include "io_sch.h" +#include "blacklist.h" static struct timer_list recovery_timer; static DEFINE_SPINLOCK(recovery_lock); @@ -1470,6 +1471,45 @@ static void ccw_device_schedule_recovery(void) spin_unlock_irqrestore(&recovery_lock, flags); } +static int purge_fn(struct device *dev, void *data) +{ + struct ccw_device *cdev = to_ccwdev(dev); + struct ccw_device_private *priv = cdev->private; + int unreg; + + spin_lock_irq(cdev->ccwlock); + unreg = is_blacklisted(priv->dev_id.ssid, priv->dev_id.devno) && + (priv->state == DEV_STATE_OFFLINE); + spin_unlock_irq(cdev->ccwlock); + if (!unreg) + goto out; + if (!get_device(&cdev->dev)) + goto out; + CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid, + priv->dev_id.devno); + PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister); + queue_work(slow_path_wq, &cdev->private->kick_work); + +out: + /* Abort loop in case of pending signal. */ + if (signal_pending(current)) + return -EINTR; + + return 0; +} + +/** + * ccw_purge_blacklisted - purge unused, blacklisted devices + * + * Unregister all ccw devices that are offline and on the blacklist. + */ +int ccw_purge_blacklisted(void) +{ + CIO_MSG_EVENT(2, "ccw: purging blacklisted devices\n"); + bus_for_each_dev(&ccw_bus_type, NULL, NULL, purge_fn); + return 0; +} + static void device_set_disconnected(struct ccw_device *cdev) { if (!cdev) |