|
@@ -2,7 +2,7 @@
|
|
* Linux driver for System z and s390 unit record devices
|
|
* Linux driver for System z and s390 unit record devices
|
|
* (z/VM virtual punch, reader, printer)
|
|
* (z/VM virtual punch, reader, printer)
|
|
*
|
|
*
|
|
- * Copyright IBM Corp. 2001, 2007
|
|
|
|
|
|
+ * Copyright IBM Corp. 2001, 2009
|
|
* Authors: Malcolm Beattie <beattiem@uk.ibm.com>
|
|
* Authors: Malcolm Beattie <beattiem@uk.ibm.com>
|
|
* Michael Holzheu <holzheu@de.ibm.com>
|
|
* Michael Holzheu <holzheu@de.ibm.com>
|
|
* Frank Munzert <munzert@de.ibm.com>
|
|
* Frank Munzert <munzert@de.ibm.com>
|
|
@@ -60,6 +60,7 @@ static int ur_probe(struct ccw_device *cdev);
|
|
static void ur_remove(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_online(struct ccw_device *cdev);
|
|
static int ur_set_offline(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 = {
|
|
static struct ccw_driver ur_driver = {
|
|
.name = "vmur",
|
|
.name = "vmur",
|
|
@@ -69,6 +70,7 @@ static struct ccw_driver ur_driver = {
|
|
.remove = ur_remove,
|
|
.remove = ur_remove,
|
|
.set_online = ur_set_online,
|
|
.set_online = ur_set_online,
|
|
.set_offline = ur_set_offline,
|
|
.set_offline = ur_set_offline,
|
|
|
|
+ .freeze = ur_pm_suspend,
|
|
};
|
|
};
|
|
|
|
|
|
static DEFINE_MUTEX(vmur_mutex);
|
|
static DEFINE_MUTEX(vmur_mutex);
|
|
@@ -157,6 +159,28 @@ static void urdev_put(struct urdev *urd)
|
|
urdev_free(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.
|
|
* Low-level functions to do I/O to a ur device.
|
|
* alloc_chan_prog
|
|
* alloc_chan_prog
|