Skip to content

Commit

Permalink
[S390] cio: Fixup interface for setting options on ccw devices.
Browse files Browse the repository at this point in the history
The current ccw_device_set_options() sets a specified mask of options
and clears those not specified, but there is no way to find out which
options have already been set.

In order to fix this up, introduce the following interface changes:

ccw_device_set_options() now only sets the specified bits, but does
not clear those that are not specified.

ccw_device_clear_options() clears the specified bits.

ccw_device_set_options_mask() provides the old semantics (setting only
the specified bits and clearing the others).

Device drivers now work as expected. qdio has been adapted.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Cornelia Huck authored and Martin Schwidefsky committed Feb 12, 2007
1 parent 0ec6766 commit 4dd3cc5
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
32 changes: 30 additions & 2 deletions drivers/s390/cio/device_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
#include "chsc.h"
#include "device.h"

int
ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)
{
/*
* The flag usage is mutal exclusive ...
Expand All @@ -39,6 +38,33 @@ ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
return 0;
}

int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
{
/*
* The flag usage is mutal exclusive ...
*/
if (((flags & CCWDEV_EARLY_NOTIFICATION) &&
(flags & CCWDEV_REPORT_ALL)) ||
((flags & CCWDEV_EARLY_NOTIFICATION) &&
cdev->private->options.repall) ||
((flags & CCWDEV_REPORT_ALL) &&
cdev->private->options.fast))
return -EINVAL;
cdev->private->options.fast |= (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
return 0;
}

void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)
{
cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0;
cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
}

int
ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
{
Expand Down Expand Up @@ -601,7 +627,9 @@ _ccw_device_get_device_number(struct ccw_device *cdev)


MODULE_LICENSE("GPL");
EXPORT_SYMBOL(ccw_device_set_options_mask);
EXPORT_SYMBOL(ccw_device_set_options);
EXPORT_SYMBOL(ccw_device_clear_options);
EXPORT_SYMBOL(ccw_device_clear);
EXPORT_SYMBOL(ccw_device_halt);
EXPORT_SYMBOL(ccw_device_resume);
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/cio/qdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3194,7 +3194,7 @@ qdio_establish(struct qdio_initialize *init_data)

spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags);

ccw_device_set_options(cdev, 0);
ccw_device_set_options_mask(cdev, 0);
result=ccw_device_start_timeout(cdev,&irq_ptr->ccw,
QDIO_DOING_ESTABLISH,0, 0,
QDIO_ESTABLISH_TIMEOUT);
Expand Down
2 changes: 2 additions & 0 deletions include/asm-s390/ccwdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ extern void ccw_driver_unregister (struct ccw_driver *driver);

struct ccw1;

extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long);
extern int ccw_device_set_options(struct ccw_device *, unsigned long);
extern void ccw_device_clear_options(struct ccw_device *, unsigned long);

/* Allow for i/o completion notification after primary interrupt status. */
#define CCWDEV_EARLY_NOTIFICATION 0x0001
Expand Down

0 comments on commit 4dd3cc5

Please sign in to comment.