Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-1.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright IBM Corp. 2002, 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *	      Cornelia Huck (cornelia.huck@de.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/ccwdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/idals.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/chpid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/fcx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "cio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "cio_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "css.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "chsc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "device.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "chp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * ccw_device_set_options_mask() - set some options and unset the rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * @cdev: device for which the options are to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * @flags: options to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * All flags specified in @flags are set, all flags not specified in @flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * are cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *   %0 on success, -%EINVAL on an invalid flag combination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)        /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	* The flag usage is mutal exclusive ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	if ((flags & CCWDEV_EARLY_NOTIFICATION) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	    (flags & CCWDEV_REPORT_ALL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * ccw_device_set_options() - set some options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @cdev: device for which the options are to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * @flags: options to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * All flags specified in @flags are set, the remainder is left untouched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *   %0 on success, -%EINVAL if an invalid flag combination would ensue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)        /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	* The flag usage is mutal exclusive ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (((flags & CCWDEV_EARLY_NOTIFICATION) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	    (flags & CCWDEV_REPORT_ALL)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	    ((flags & CCWDEV_EARLY_NOTIFICATION) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	     cdev->private->options.repall) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	    ((flags & CCWDEV_REPORT_ALL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	     cdev->private->options.fast))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	cdev->private->options.fast |= (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * ccw_device_clear_options() - clear some options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * @cdev: device for which the options are to be cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * @flags: options to be cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * All flags specified in @flags are cleared, the remainder is left untouched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * ccw_device_is_pathgroup() - determine if paths to this device are grouped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * @cdev: ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * Return non-zero if there is a path group, zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int ccw_device_is_pathgroup(struct ccw_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	return cdev->private->flags.pgroup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) EXPORT_SYMBOL(ccw_device_is_pathgroup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * ccw_device_is_multipath() - determine if device is operating in multipath mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * @cdev: ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * Return non-zero if device is operating in multipath mode, zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int ccw_device_is_multipath(struct ccw_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return cdev->private->flags.mpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) EXPORT_SYMBOL(ccw_device_is_multipath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * ccw_device_clear() - terminate I/O request processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * @intparm: interruption parameter to be returned upon conclusion of csch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * ccw_device_clear() calls csch on @cdev's subchannel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *  %0 on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  *  -%ENODEV on device not operational,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *  -%EINVAL on invalid device state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (!cdev || !cdev->dev.parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!sch->schib.pmcw.ena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (cdev->private->state == DEV_STATE_NOT_OPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (cdev->private->state != DEV_STATE_ONLINE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	    cdev->private->state != DEV_STATE_W4SENSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	ret = cio_clear(sch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		cdev->private->intparm = intparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * ccw_device_start_timeout_key() - start a s390 channel program with timeout and key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * @cpa: logical start address of channel program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * @intparm: user specific interruption parameter; will be presented back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  *	     @cdev's interrupt handler. Allows a device driver to associate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  *	     the interrupt with a particular I/O request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * @lpm: defines the channel path to be used for a specific I/O request. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  *	 value of 0 will make cio use the opm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * @key: storage key to be used for the I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * @flags: additional flags; defines the action to be performed for I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *	   processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * @expires: timeout value in jiffies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * Start a S/390 channel program. When the interrupt arrives, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * IRQ handler is called, either immediately, delayed (dev-end missing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * or sense required) or never (no IRQ handler registered).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * This function notifies the device driver if the channel program has not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * completed during the time specified by @expires. If a timeout occurs, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * channel program is terminated via xsch, hsch or csch, and the device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * The interruption handler will echo back the @intparm specified here, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * another interruption parameter is specified by a subsequent invocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * ccw_device_halt() or ccw_device_clear().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *  %0, if the operation was successful;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  *  -%EBUSY, if the device is busy, or status pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  *  -%EACCES, if no path specified in @lpm is operational;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  *  -%ENODEV, if the device is not operational.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				 unsigned long intparm, __u8 lpm, __u8 key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 				 unsigned long flags, int expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (!cdev || !cdev->dev.parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (!sch->schib.pmcw.ena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	if (cdev->private->state == DEV_STATE_NOT_OPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (cdev->private->state == DEV_STATE_VERIFY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		/* Remember to fake irb when finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		if (!cdev->private->flags.fake_irb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			cdev->private->flags.fake_irb = FAKE_CMD_IRB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			cdev->private->intparm = intparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			/* There's already a fake I/O around. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (cdev->private->state != DEV_STATE_ONLINE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	    ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	     !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	    cdev->private->flags.doverify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ret = cio_set_options (sch, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* Adjust requested path mask to exclude unusable paths. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (lpm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		lpm &= sch->lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		if (lpm == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	ret = cio_start_key (sch, cpa, lpm, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		cdev->private->intparm = intparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		if (expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			ccw_device_set_timeout(cdev, expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	case -EACCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  * ccw_device_start_key() - start a s390 channel program with key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * @cpa: logical start address of channel program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * @intparm: user specific interruption parameter; will be presented back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *	     @cdev's interrupt handler. Allows a device driver to associate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *	     the interrupt with a particular I/O request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * @lpm: defines the channel path to be used for a specific I/O request. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  *	 value of 0 will make cio use the opm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * @key: storage key to be used for the I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * @flags: additional flags; defines the action to be performed for I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  *	   processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * Start a S/390 channel program. When the interrupt arrives, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  * IRQ handler is called, either immediately, delayed (dev-end missing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  * or sense required) or never (no IRQ handler registered).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  * The interruption handler will echo back the @intparm specified here, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * another interruption parameter is specified by a subsequent invocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  * ccw_device_halt() or ccw_device_clear().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  *  %0, if the operation was successful;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  *  -%EBUSY, if the device is busy, or status pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  *  -%EACCES, if no path specified in @lpm is operational;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  *  -%ENODEV, if the device is not operational.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			 unsigned long intparm, __u8 lpm, __u8 key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			 unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 					    flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * ccw_device_start() - start a s390 channel program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * @cpa: logical start address of channel program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * @intparm: user specific interruption parameter; will be presented back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  *	     @cdev's interrupt handler. Allows a device driver to associate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  *	     the interrupt with a particular I/O request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * @lpm: defines the channel path to be used for a specific I/O request. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  *	 value of 0 will make cio use the opm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  * @flags: additional flags; defines the action to be performed for I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  *	   processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  * Start a S/390 channel program. When the interrupt arrives, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  * IRQ handler is called, either immediately, delayed (dev-end missing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * or sense required) or never (no IRQ handler registered).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  * The interruption handler will echo back the @intparm specified here, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * another interruption parameter is specified by a subsequent invocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * ccw_device_halt() or ccw_device_clear().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *  %0, if the operation was successful;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  *  -%EBUSY, if the device is busy, or status pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  *  -%EACCES, if no path specified in @lpm is operational;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  *  -%ENODEV, if the device is not operational.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		     unsigned long intparm, __u8 lpm, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return ccw_device_start_key(cdev, cpa, intparm, lpm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				    PAGE_DEFAULT_KEY, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  * ccw_device_start_timeout() - start a s390 channel program with timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  * @cpa: logical start address of channel program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)  * @intparm: user specific interruption parameter; will be presented back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)  *	     @cdev's interrupt handler. Allows a device driver to associate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  *	     the interrupt with a particular I/O request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  * @lpm: defines the channel path to be used for a specific I/O request. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)  *	 value of 0 will make cio use the opm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)  * @flags: additional flags; defines the action to be performed for I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  *	   processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * @expires: timeout value in jiffies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  * Start a S/390 channel program. When the interrupt arrives, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)  * IRQ handler is called, either immediately, delayed (dev-end missing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * or sense required) or never (no IRQ handler registered).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * This function notifies the device driver if the channel program has not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  * completed during the time specified by @expires. If a timeout occurs, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  * channel program is terminated via xsch, hsch or csch, and the device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)  * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)  * The interruption handler will echo back the @intparm specified here, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  * another interruption parameter is specified by a subsequent invocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * ccw_device_halt() or ccw_device_clear().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  *  %0, if the operation was successful;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  *  -%EBUSY, if the device is busy, or status pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  *  -%EACCES, if no path specified in @lpm is operational;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  *  -%ENODEV, if the device is not operational.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			     unsigned long intparm, __u8 lpm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			     unsigned long flags, int expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 					    PAGE_DEFAULT_KEY, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 					    expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  * ccw_device_halt() - halt I/O request processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @intparm: interruption parameter to be returned upon conclusion of hsch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * ccw_device_halt() calls hsch on @cdev's subchannel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * The interruption handler will echo back the @intparm specified here, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  * another interruption parameter is specified by a subsequent invocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  * ccw_device_clear().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)  *  %0 on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  *  -%ENODEV on device not operational,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)  *  -%EINVAL on invalid device state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  *  -%EBUSY on device busy or interrupt pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (!cdev || !cdev->dev.parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	if (!sch->schib.pmcw.ena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (cdev->private->state == DEV_STATE_NOT_OPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (cdev->private->state != DEV_STATE_ONLINE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	    cdev->private->state != DEV_STATE_W4SENSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	ret = cio_halt(sch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		cdev->private->intparm = intparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * ccw_device_resume() - resume channel program execution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * @cdev: target ccw device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * ccw_device_resume() calls rsch on @cdev's subchannel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  *  %0 on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  *  -%ENODEV on device not operational,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  *  -%EINVAL on invalid device state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  *  -%EBUSY on device busy or interrupt pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  *  Interrupts disabled, ccw device lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int ccw_device_resume(struct ccw_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (!cdev || !cdev->dev.parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	if (!sch->schib.pmcw.ena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (cdev->private->state == DEV_STATE_NOT_OPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (cdev->private->state != DEV_STATE_ONLINE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	    !(sch->schib.scsw.cmd.actl & SCSW_ACTL_SUSPENDED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	return cio_resume(sch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  * ccw_device_get_ciw() - Search for CIW command in extended sense data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * @cdev: ccw device to inspect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  * @ct: command type to look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  * During SenseID, command information words (CIWs) describing special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  * commands available to the device may have been stored in the extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  * sense data. This function searches for CIWs of a specified command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)  * type in the extended sense data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  *  %NULL if no extended sense data has been stored or if no CIW of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  *  specified command type could be found,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  *  else a pointer to the CIW of the specified command type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct ciw *ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	int ciw_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	if (cdev->private->flags.esid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		if (cdev->private->dma_area->senseid.ciw[ciw_cnt].ct == ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			return cdev->private->dma_area->senseid.ciw + ciw_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)  * ccw_device_get_path_mask() - get currently available paths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)  * @cdev: ccw device to be queried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)  *  %0 if no subchannel for the device is available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  *  else the mask of currently available paths for the ccw device's subchannel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (!cdev->dev.parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	return sch->lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)  * ccw_device_get_chp_desc() - return newly allocated channel-path descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)  * @cdev: device to obtain the descriptor for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)  * @chp_idx: index of the channel path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)  * On success return a newly allocated copy of the channel-path description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  * data associated with the given channel path. Return %NULL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 						       int chp_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct chp_id chpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	chp_id_init(&chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	chpid.id = sch->schib.pmcw.chpid[chp_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	return chp_get_chp_desc(chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)  * ccw_device_get_util_str() - return newly allocated utility strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)  * @cdev: device to obtain the utility strings for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)  * @chp_idx: index of the channel path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)  * On success return a newly allocated copy of the utility strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)  * associated with the given channel path. Return %NULL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	struct channel_path *chp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	struct chp_id chpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	u8 *util_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	chp_id_init(&chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	chpid.id = sch->schib.pmcw.chpid[chp_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	chp = chpid_to_chp(chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	util_str = kmalloc(sizeof(chp->desc_fmt3.util_str), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (!util_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	mutex_lock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	memcpy(util_str, chp->desc_fmt3.util_str, sizeof(chp->desc_fmt3.util_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	mutex_unlock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	return util_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  * ccw_device_get_id() - obtain a ccw device id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)  * @cdev: device to obtain the id for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)  * @dev_id: where to fill in the values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) void ccw_device_get_id(struct ccw_device *cdev, struct ccw_dev_id *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	*dev_id = cdev->private->dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) EXPORT_SYMBOL(ccw_device_get_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)  * ccw_device_tm_start_timeout_key() - perform start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)  * @cdev: ccw device on which to perform the start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)  * @tcw: transport-command word to be started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)  * @intparm: user defined parameter to be passed to the interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)  * @lpm: mask of paths to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  * @key: storage key to use for storage access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  * @expires: time span in jiffies after which to abort request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)  * Start the tcw on the given ccw device. Return zero on success, non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)  * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 				    unsigned long intparm, u8 lpm, u8 key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 				    int expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	if (!sch->schib.pmcw.ena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (cdev->private->state == DEV_STATE_VERIFY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		/* Remember to fake irb when finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		if (!cdev->private->flags.fake_irb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			cdev->private->flags.fake_irb = FAKE_TM_IRB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			cdev->private->intparm = intparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 			/* There's already a fake I/O around. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	if (cdev->private->state != DEV_STATE_ONLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	/* Adjust requested path mask to exclude unusable paths. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	if (lpm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		lpm &= sch->lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		if (lpm == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	rc = cio_tm_start_key(sch, tcw, lpm, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		cdev->private->intparm = intparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		if (expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			ccw_device_set_timeout(cdev, expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) EXPORT_SYMBOL(ccw_device_tm_start_timeout_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  * ccw_device_tm_start_key() - perform start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  * @cdev: ccw device on which to perform the start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  * @tcw: transport-command word to be started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)  * @intparm: user defined parameter to be passed to the interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)  * @lpm: mask of paths to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)  * @key: storage key to use for storage access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)  * Start the tcw on the given ccw device. Return zero on success, non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)  * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 			    unsigned long intparm, u8 lpm, u8 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm, key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) EXPORT_SYMBOL(ccw_device_tm_start_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  * ccw_device_tm_start() - perform start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)  * @cdev: ccw device on which to perform the start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)  * @tcw: transport-command word to be started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)  * @intparm: user defined parameter to be passed to the interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)  * @lpm: mask of paths to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)  * Start the tcw on the given ccw device. Return zero on success, non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)  * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) int ccw_device_tm_start(struct ccw_device *cdev, struct tcw *tcw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			unsigned long intparm, u8 lpm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	return ccw_device_tm_start_key(cdev, tcw, intparm, lpm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 				       PAGE_DEFAULT_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) EXPORT_SYMBOL(ccw_device_tm_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  * ccw_device_tm_start_timeout() - perform start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)  * @cdev: ccw device on which to perform the start function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)  * @tcw: transport-command word to be started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  * @intparm: user defined parameter to be passed to the interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * @lpm: mask of paths to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  * @expires: time span in jiffies after which to abort request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)  * Start the tcw on the given ccw device. Return zero on success, non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)  * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 			       unsigned long intparm, u8 lpm, int expires)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 					       PAGE_DEFAULT_KEY, expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) EXPORT_SYMBOL(ccw_device_tm_start_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)  * ccw_device_get_mdc() - accumulate max data count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)  * @cdev: ccw device for which the max data count is accumulated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)  * @mask: mask of paths to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)  * Return the number of 64K-bytes blocks all paths at least support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)  * for a transport command. Return value 0 indicates failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	struct channel_path *chp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	struct chp_id chpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	int mdc = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	/* Adjust requested path mask to excluded varied off paths. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	if (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		mask &= sch->lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		mask = sch->lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	chp_id_init(&chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		if (!(mask & (0x80 >> i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		chpid.id = sch->schib.pmcw.chpid[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		chp = chpid_to_chp(chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		if (!chp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		mutex_lock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		if (!chp->desc_fmt1.f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			mutex_unlock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		if (!chp->desc_fmt1.r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			mdc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		mdc = mdc ? min_t(int, mdc, chp->desc_fmt1.mdc) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			    chp->desc_fmt1.mdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		mutex_unlock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	return mdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) EXPORT_SYMBOL(ccw_device_get_mdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)  * ccw_device_tm_intrg() - perform interrogate function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)  * @cdev: ccw device on which to perform the interrogate function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)  * Perform an interrogate function on the given ccw device. Return zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)  * success, non-zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int ccw_device_tm_intrg(struct ccw_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	if (!sch->schib.pmcw.ena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	if (cdev->private->state != DEV_STATE_ONLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (!scsw_is_tm(&sch->schib.scsw) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	    !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	return cio_tm_intrg(sch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) EXPORT_SYMBOL(ccw_device_tm_intrg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)  * ccw_device_get_schid() - obtain a subchannel id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)  * @cdev: device to obtain the id for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)  * @schid: where to fill in the values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	*schid = sch->schid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) EXPORT_SYMBOL_GPL(ccw_device_get_schid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)  * ccw_device_pnso() - Perform Network-Subchannel Operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)  * @cdev:		device on which PNSO is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)  * @pnso_area:		request and response block for the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)  * @oc:			Operation Code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)  * @resume_token:	resume token for multiblock response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)  * @cnc:		Boolean change-notification control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)  * pnso_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int ccw_device_pnso(struct ccw_device *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		    struct chsc_pnso_area *pnso_area, u8 oc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		    struct chsc_pnso_resume_token resume_token, int cnc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	struct subchannel_id schid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	ccw_device_get_schid(cdev, &schid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	return chsc_pnso(schid, pnso_area, oc, resume_token, cnc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) EXPORT_SYMBOL_GPL(ccw_device_pnso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)  * ccw_device_get_cssid() - obtain Channel Subsystem ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)  * @cdev: device to obtain the CSSID for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)  * @cssid: The resulting Channel Subsystem ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int ccw_device_get_cssid(struct ccw_device *cdev, u8 *cssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	struct device *sch_dev = cdev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	struct channel_subsystem *css = to_css(sch_dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	if (css->id_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		*cssid = css->cssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	return css->id_valid ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) EXPORT_SYMBOL_GPL(ccw_device_get_cssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)  * ccw_device_get_iid() - obtain MIF-image ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)  * @cdev: device to obtain the MIF-image ID for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)  * @iid: The resulting MIF-image ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int ccw_device_get_iid(struct ccw_device *cdev, u8 *iid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	struct device *sch_dev = cdev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	struct channel_subsystem *css = to_css(sch_dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	if (css->id_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		*iid = css->iid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	return css->id_valid ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) EXPORT_SYMBOL_GPL(ccw_device_get_iid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)  * ccw_device_get_chpid() - obtain Channel Path ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)  * @cdev: device to obtain the Channel Path ID for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)  * @chp_idx: Index of the channel path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)  * @chpid: The resulting Channel Path ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	if ((chp_idx < 0) || (chp_idx > 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	mask = 0x80 >> chp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	if (!(sch->schib.pmcw.pim & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	*chpid = sch->schib.pmcw.chpid[chp_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) EXPORT_SYMBOL_GPL(ccw_device_get_chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)  * ccw_device_get_chid() - obtain Channel ID associated with specified CHPID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)  * @cdev: device to obtain the Channel ID for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)  * @chp_idx: Index of the channel path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)  * @chid: The resulting Channel ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int ccw_device_get_chid(struct ccw_device *cdev, int chp_idx, u16 *chid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	struct chp_id cssid_chpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	struct channel_path *chp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	chp_id_init(&cssid_chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	rc = ccw_device_get_chpid(cdev, chp_idx, &cssid_chpid.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	chp = chpid_to_chp(cssid_chpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	if (!chp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	mutex_lock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	if (chp->desc_fmt1.flags & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		*chid = chp->desc_fmt1.chid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	mutex_unlock(&chp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) EXPORT_SYMBOL_GPL(ccw_device_get_chid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)  * Allocate zeroed dma coherent 31 bit addressable memory using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)  * the subchannels dma pool. Maximal size of allocation supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)  * is PAGE_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	if (!get_device(&cdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	if (IS_ERR_OR_NULL(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		put_device(&cdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) EXPORT_SYMBOL(ccw_device_dma_zalloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) void ccw_device_dma_free(struct ccw_device *cdev, void *cpu_addr, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	if (!cpu_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	cio_gp_dma_free(cdev->private->dma_pool, cpu_addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	put_device(&cdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) EXPORT_SYMBOL(ccw_device_dma_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) EXPORT_SYMBOL(ccw_device_set_options_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) EXPORT_SYMBOL(ccw_device_set_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) EXPORT_SYMBOL(ccw_device_clear_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) EXPORT_SYMBOL(ccw_device_clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) EXPORT_SYMBOL(ccw_device_halt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) EXPORT_SYMBOL(ccw_device_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) EXPORT_SYMBOL(ccw_device_start_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) EXPORT_SYMBOL(ccw_device_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) EXPORT_SYMBOL(ccw_device_start_timeout_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) EXPORT_SYMBOL(ccw_device_start_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) EXPORT_SYMBOL(ccw_device_get_ciw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) EXPORT_SYMBOL(ccw_device_get_path_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) EXPORT_SYMBOL_GPL(ccw_device_get_util_str);