Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151118
b: refs/heads/master
c: 672e405
h: refs/heads/master
v: v3
  • Loading branch information
Ursula Braun authored and Martin Schwidefsky committed Jun 16, 2009
1 parent 2488aff commit 719876c
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6c005961c15ff85fe1047c197d50b843567c89f8
refs/heads/master: 672e405b603af0bed99a4c173cdfce9bbf81c963
179 changes: 179 additions & 0 deletions trunk/net/iucv/iucv.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
* Rewritten for af_iucv:
* Martin Schwidefsky <schwidefsky@de.ibm.com>
* PM functions:
* Ursula Braun (ursula.braun@de.ibm.com)
*
* Documentation used:
* The original source
Expand Down Expand Up @@ -77,9 +79,24 @@ static int iucv_bus_match(struct device *dev, struct device_driver *drv)
return 0;
}

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 = {
.prepare = iucv_pm_prepare,
.complete = iucv_pm_complete,
.freeze = iucv_pm_freeze,
.thaw = iucv_pm_thaw,
.restore = iucv_pm_restore,
};

struct bus_type iucv_bus = {
.name = "iucv",
.match = iucv_bus_match,
.pm = &iucv_pm_ops,
};
EXPORT_SYMBOL(iucv_bus);

Expand Down Expand Up @@ -149,6 +166,7 @@ enum iucv_command_codes {
IUCV_RESUME = 14,
IUCV_SEVER = 15,
IUCV_SETMASK = 16,
IUCV_SETCONTROLMASK = 17,
};

/*
Expand Down Expand Up @@ -366,6 +384,18 @@ static void iucv_allow_cpu(void *data)
parm->set_mask.ipmask = 0xf8;
iucv_call_b2f0(IUCV_SETMASK, parm);

/*
* Enable all iucv control interrupts.
* ipmask contains bits for the different interrupts
* 0x80 - Flag to allow pending connections interrupts
* 0x40 - Flag to allow connection complete interrupts
* 0x20 - Flag to allow connection severed interrupts
* 0x10 - Flag to allow connection quiesced interrupts
* 0x08 - Flag to allow connection resumed interrupts
*/
memset(parm, 0, sizeof(union iucv_param));
parm->set_mask.ipmask = 0xf8;
iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);
/* Set indication that iucv interrupts are allowed for this cpu. */
cpu_set(cpu, iucv_irq_cpumask);
}
Expand All @@ -390,6 +420,31 @@ static void iucv_block_cpu(void *data)
cpu_clear(cpu, iucv_irq_cpumask);
}

/**
* iucv_block_cpu_almost
* @data: unused
*
* Allow connection-severed interrupts only on this cpu.
*/
static void iucv_block_cpu_almost(void *data)
{
int cpu = smp_processor_id();
union iucv_param *parm;

/* Allow iucv control interrupts only */
parm = iucv_param_irq[cpu];
memset(parm, 0, sizeof(union iucv_param));
parm->set_mask.ipmask = 0x08;
iucv_call_b2f0(IUCV_SETMASK, parm);
/* Allow iucv-severed interrupt only */
memset(parm, 0, sizeof(union iucv_param));
parm->set_mask.ipmask = 0x20;
iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);

/* Clear indication that iucv interrupts are allowed for this cpu. */
cpu_clear(cpu, iucv_irq_cpumask);
}

/**
* iucv_declare_cpu
* @data: unused
Expand Down Expand Up @@ -1766,6 +1821,130 @@ static void iucv_external_interrupt(u16 code)
spin_unlock(&iucv_queue_lock);
}

static int iucv_pm_prepare(struct device *dev)
{
int rc = 0;

#ifdef CONFIG_PM_DEBUG
printk(KERN_INFO "iucv_pm_prepare\n");
#endif
if (dev->driver && dev->driver->pm && dev->driver->pm->prepare)
rc = dev->driver->pm->prepare(dev);
return rc;
}

static void iucv_pm_complete(struct device *dev)
{
#ifdef CONFIG_PM_DEBUG
printk(KERN_INFO "iucv_pm_complete\n");
#endif
if (dev->driver && dev->driver->pm && dev->driver->pm->complete)
dev->driver->pm->complete(dev);
}

/**
* iucv_path_table_empty() - determine if iucv path table is empty
*
* Returns 0 if there are still iucv pathes defined
* 1 if there are no iucv pathes defined
*/
int iucv_path_table_empty(void)
{
int i;

for (i = 0; i < iucv_max_pathid; i++) {
if (iucv_path_table[i])
return 0;
}
return 1;
}

/**
* iucv_pm_freeze() - Freeze PM callback
* @dev: iucv-based device
*
* disable iucv interrupts
* invoke callback function of the iucv-based driver
* shut down iucv, if no iucv-pathes are established anymore
*/
static int iucv_pm_freeze(struct device *dev)
{
int cpu;
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 (dev->driver && dev->driver->pm && dev->driver->pm->freeze)
rc = dev->driver->pm->freeze(dev);
if (iucv_path_table_empty())
iucv_disable();
return rc;
}

/**
* iucv_pm_thaw() - Thaw PM callback
* @dev: iucv-based device
*
* make iucv ready for use again: allocate path table, declare interrupt buffers
* and enable iucv interrupts
* invoke callback function of the iucv-based driver
*/
static int iucv_pm_thaw(struct device *dev)
{
int rc = 0;

#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "iucv_pm_thaw\n");
#endif
if (!iucv_path_table) {
rc = iucv_enable();
if (rc)
goto out;
}
if (cpus_empty(iucv_irq_cpumask)) {
if (iucv_nonsmp_handler)
/* enable interrupts on one cpu */
iucv_allow_cpu(NULL);
else
/* enable interrupts on all cpus */
iucv_setmask_mp();
}
if (dev->driver && dev->driver->pm && dev->driver->pm->thaw)
rc = dev->driver->pm->thaw(dev);
out:
return rc;
}

/**
* iucv_pm_restore() - Restore PM callback
* @dev: iucv-based device
*
* make iucv ready for use again: allocate path table, declare interrupt buffers
* and enable iucv interrupts
* invoke callback function of the iucv-based driver
*/
static int iucv_pm_restore(struct device *dev)
{
int rc = 0;

#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "iucv_pm_restore %p\n", iucv_path_table);
#endif
if (cpus_empty(iucv_irq_cpumask)) {
rc = iucv_query_maxconn();
rc = iucv_enable();
if (rc)
goto out;
}
if (dev->driver && dev->driver->pm && dev->driver->pm->restore)
rc = dev->driver->pm->restore(dev);
out:
return rc;
}

/**
* iucv_init
*
Expand Down

0 comments on commit 719876c

Please sign in to comment.