return 0;
}
+enum iucv_pm_states {
+ IUCV_PM_INITIAL = 0,
+ IUCV_PM_FREEZING = 1,
+ IUCV_PM_THAWING = 2,
+ IUCV_PM_RESTORING = 3,
+};
+static enum iucv_pm_states iucv_pm_state;
+
static int iucv_pm_prepare(struct device *);
static void iucv_pm_complete(struct device *);
static int iucv_pm_freeze(struct device *);
static int iucv_pm_thaw(struct device *);
static int iucv_pm_restore(struct device *);
-static struct dev_pm_ops iucv_pm_ops = {
+static const struct dev_pm_ops iucv_pm_ops = {
.prepare = iucv_pm_prepare,
.complete = iucv_pm_complete,
.freeze = iucv_pm_freeze,
" srl %0,28\n"
: "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
if (ccode == 0)
- iucv_max_pathid = reg0;
+ iucv_max_pathid = reg1;
kfree(param);
return ccode ? -EPERM : 0;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
spin_lock_bh(&iucv_table_lock);
iucv_cleanup_queue();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
preempt_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
if (msg->flags & IUCV_IPRMDATA)
return iucv_message_receive_iprmdata(path, msg, flags,
buffer, size, residual);
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
union iucv_param *parm;
int rc;
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
int rc;
local_bh_disable();
- if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+ if (cpus_empty(iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
*/
static void iucv_work_fn(struct work_struct *work)
{
- typedef void iucv_irq_fn(struct iucv_irq_data *);
LIST_HEAD(work_queue);
struct iucv_irq_list *p, *n;
static int iucv_pm_freeze(struct device *dev)
{
int cpu;
+ struct iucv_irq_list *p, *n;
int rc = 0;
#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "iucv_pm_freeze\n");
#endif
- for_each_cpu_mask_nr(cpu, iucv_irq_cpumask)
- smp_call_function_single(cpu, iucv_block_cpu_almost, NULL, 1);
+ if (iucv_pm_state != IUCV_PM_FREEZING) {
+ for_each_cpu_mask_nr(cpu, iucv_irq_cpumask)
+ smp_call_function_single(cpu, iucv_block_cpu_almost,
+ NULL, 1);
+ cancel_work_sync(&iucv_work);
+ list_for_each_entry_safe(p, n, &iucv_work_queue, list) {
+ list_del_init(&p->list);
+ iucv_sever_pathid(p->data.ippathid,
+ iucv_error_no_listener);
+ kfree(p);
+ }
+ }
+ iucv_pm_state = IUCV_PM_FREEZING;
if (dev->driver && dev->driver->pm && dev->driver->pm->freeze)
rc = dev->driver->pm->freeze(dev);
if (iucv_path_table_empty())
#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "iucv_pm_thaw\n");
#endif
+ iucv_pm_state = IUCV_PM_THAWING;
if (!iucv_path_table) {
rc = iucv_enable();
if (rc)
#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "iucv_pm_restore %p\n", iucv_path_table);
#endif
+ if ((iucv_pm_state != IUCV_PM_RESTORING) && iucv_path_table)
+ pr_warning("Suspending Linux did not completely close all IUCV "
+ "connections\n");
+ iucv_pm_state = IUCV_PM_RESTORING;
if (cpus_empty(iucv_irq_cpumask)) {
rc = iucv_query_maxconn();
rc = iucv_enable();