From: Frank Munzert Date: Tue, 16 Jun 2009 08:30:37 +0000 (+0200) Subject: [S390] pm: vmur driver power management callbacks X-Git-Tag: firefly_0821_release~13902^2~15 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b241f7bcc603babd3de903fa855d418ee7c4751d;p=firefly-linux-kernel-4.4.55.git [S390] pm: vmur driver power management callbacks Signed-off-by: Frank Munzert Signed-off-by: Martin Schwidefsky --- diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 5dcef81fc9d9..92458219a9e9 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -2,7 +2,7 @@ * Linux driver for System z and s390 unit record devices * (z/VM virtual punch, reader, printer) * - * Copyright IBM Corp. 2001, 2007 + * Copyright IBM Corp. 2001, 2009 * Authors: Malcolm Beattie * Michael Holzheu * Frank Munzert @@ -60,6 +60,7 @@ static int ur_probe(struct ccw_device *cdev); static void ur_remove(struct ccw_device *cdev); static int ur_set_online(struct ccw_device *cdev); static int ur_set_offline(struct ccw_device *cdev); +static int ur_pm_suspend(struct ccw_device *cdev); static struct ccw_driver ur_driver = { .name = "vmur", @@ -69,6 +70,7 @@ static struct ccw_driver ur_driver = { .remove = ur_remove, .set_online = ur_set_online, .set_offline = ur_set_offline, + .freeze = ur_pm_suspend, }; static DEFINE_MUTEX(vmur_mutex); @@ -157,6 +159,28 @@ static void urdev_put(struct urdev *urd) urdev_free(urd); } +/* + * State and contents of ur devices can be changed by class D users issuing + * CP commands such as PURGE or TRANSFER, while the Linux guest is suspended. + * Also the Linux guest might be logged off, which causes all active spool + * files to be closed. + * So we cannot guarantee that spool files are still the same when the Linux + * guest is resumed. In order to avoid unpredictable results at resume time + * we simply refuse to suspend if a ur device node is open. + */ +static int ur_pm_suspend(struct ccw_device *cdev) +{ + struct urdev *urd = cdev->dev.driver_data; + + TRACE("ur_pm_suspend: cdev=%p\n", cdev); + if (urd->open_flag) { + pr_err("Unit record device %s is busy, %s refusing to " + "suspend.\n", dev_name(&cdev->dev), ur_banner); + return -EBUSY; + } + return 0; +} + /* * Low-level functions to do I/O to a ur device. * alloc_chan_prog