Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-1.0+
0002 /*
0003  * Copyright IBM Corp. 2002, 2009
0004  *
0005  * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
0006  *        Cornelia Huck (cornelia.huck@de.ibm.com)
0007  */
0008 #include <linux/export.h>
0009 #include <linux/init.h>
0010 #include <linux/errno.h>
0011 #include <linux/slab.h>
0012 #include <linux/list.h>
0013 #include <linux/device.h>
0014 #include <linux/delay.h>
0015 #include <linux/completion.h>
0016 
0017 #include <asm/ccwdev.h>
0018 #include <asm/idals.h>
0019 #include <asm/chpid.h>
0020 #include <asm/fcx.h>
0021 
0022 #include "cio.h"
0023 #include "cio_debug.h"
0024 #include "css.h"
0025 #include "chsc.h"
0026 #include "device.h"
0027 #include "chp.h"
0028 
0029 /**
0030  * ccw_device_set_options_mask() - set some options and unset the rest
0031  * @cdev: device for which the options are to be set
0032  * @flags: options to be set
0033  *
0034  * All flags specified in @flags are set, all flags not specified in @flags
0035  * are cleared.
0036  * Returns:
0037  *   %0 on success, -%EINVAL on an invalid flag combination.
0038  */
0039 int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)
0040 {
0041        /*
0042     * The flag usage is mutal exclusive ...
0043     */
0044     if ((flags & CCWDEV_EARLY_NOTIFICATION) &&
0045         (flags & CCWDEV_REPORT_ALL))
0046         return -EINVAL;
0047     cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
0048     cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
0049     cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
0050     cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
0051     cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
0052     return 0;
0053 }
0054 
0055 /**
0056  * ccw_device_set_options() - set some options
0057  * @cdev: device for which the options are to be set
0058  * @flags: options to be set
0059  *
0060  * All flags specified in @flags are set, the remainder is left untouched.
0061  * Returns:
0062  *   %0 on success, -%EINVAL if an invalid flag combination would ensue.
0063  */
0064 int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
0065 {
0066        /*
0067     * The flag usage is mutal exclusive ...
0068     */
0069     if (((flags & CCWDEV_EARLY_NOTIFICATION) &&
0070         (flags & CCWDEV_REPORT_ALL)) ||
0071         ((flags & CCWDEV_EARLY_NOTIFICATION) &&
0072          cdev->private->options.repall) ||
0073         ((flags & CCWDEV_REPORT_ALL) &&
0074          cdev->private->options.fast))
0075         return -EINVAL;
0076     cdev->private->options.fast |= (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
0077     cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
0078     cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
0079     cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
0080     cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
0081     return 0;
0082 }
0083 
0084 /**
0085  * ccw_device_clear_options() - clear some options
0086  * @cdev: device for which the options are to be cleared
0087  * @flags: options to be cleared
0088  *
0089  * All flags specified in @flags are cleared, the remainder is left untouched.
0090  */
0091 void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)
0092 {
0093     cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0;
0094     cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
0095     cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
0096     cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
0097     cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
0098 }
0099 
0100 /**
0101  * ccw_device_is_pathgroup() - determine if paths to this device are grouped
0102  * @cdev: ccw device
0103  *
0104  * Return non-zero if there is a path group, zero otherwise.
0105  */
0106 int ccw_device_is_pathgroup(struct ccw_device *cdev)
0107 {
0108     return cdev->private->flags.pgroup;
0109 }
0110 EXPORT_SYMBOL(ccw_device_is_pathgroup);
0111 
0112 /**
0113  * ccw_device_is_multipath() - determine if device is operating in multipath mode
0114  * @cdev: ccw device
0115  *
0116  * Return non-zero if device is operating in multipath mode, zero otherwise.
0117  */
0118 int ccw_device_is_multipath(struct ccw_device *cdev)
0119 {
0120     return cdev->private->flags.mpath;
0121 }
0122 EXPORT_SYMBOL(ccw_device_is_multipath);
0123 
0124 /**
0125  * ccw_device_clear() - terminate I/O request processing
0126  * @cdev: target ccw device
0127  * @intparm: interruption parameter to be returned upon conclusion of csch
0128  *
0129  * ccw_device_clear() calls csch on @cdev's subchannel.
0130  * Returns:
0131  *  %0 on success,
0132  *  -%ENODEV on device not operational,
0133  *  -%EINVAL on invalid device state.
0134  * Context:
0135  *  Interrupts disabled, ccw device lock held
0136  */
0137 int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
0138 {
0139     struct subchannel *sch;
0140     int ret;
0141 
0142     if (!cdev || !cdev->dev.parent)
0143         return -ENODEV;
0144     sch = to_subchannel(cdev->dev.parent);
0145     if (!sch->schib.pmcw.ena)
0146         return -EINVAL;
0147     if (cdev->private->state == DEV_STATE_NOT_OPER)
0148         return -ENODEV;
0149     if (cdev->private->state != DEV_STATE_ONLINE &&
0150         cdev->private->state != DEV_STATE_W4SENSE)
0151         return -EINVAL;
0152 
0153     ret = cio_clear(sch);
0154     if (ret == 0)
0155         cdev->private->intparm = intparm;
0156     return ret;
0157 }
0158 
0159 /**
0160  * ccw_device_start_timeout_key() - start a s390 channel program with timeout and key
0161  * @cdev: target ccw device
0162  * @cpa: logical start address of channel program
0163  * @intparm: user specific interruption parameter; will be presented back to
0164  *       @cdev's interrupt handler. Allows a device driver to associate
0165  *       the interrupt with a particular I/O request.
0166  * @lpm: defines the channel path to be used for a specific I/O request. A
0167  *   value of 0 will make cio use the opm.
0168  * @key: storage key to be used for the I/O
0169  * @flags: additional flags; defines the action to be performed for I/O
0170  *     processing.
0171  * @expires: timeout value in jiffies
0172  *
0173  * Start a S/390 channel program. When the interrupt arrives, the
0174  * IRQ handler is called, either immediately, delayed (dev-end missing,
0175  * or sense required) or never (no IRQ handler registered).
0176  * This function notifies the device driver if the channel program has not
0177  * completed during the time specified by @expires. If a timeout occurs, the
0178  * channel program is terminated via xsch, hsch or csch, and the device's
0179  * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
0180  * The interruption handler will echo back the @intparm specified here, unless
0181  * another interruption parameter is specified by a subsequent invocation of
0182  * ccw_device_halt() or ccw_device_clear().
0183  * Returns:
0184  *  %0, if the operation was successful;
0185  *  -%EBUSY, if the device is busy, or status pending;
0186  *  -%EACCES, if no path specified in @lpm is operational;
0187  *  -%ENODEV, if the device is not operational.
0188  * Context:
0189  *  Interrupts disabled, ccw device lock held
0190  */
0191 int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
0192                  unsigned long intparm, __u8 lpm, __u8 key,
0193                  unsigned long flags, int expires)
0194 {
0195     struct subchannel *sch;
0196     int ret;
0197 
0198     if (!cdev || !cdev->dev.parent)
0199         return -ENODEV;
0200     sch = to_subchannel(cdev->dev.parent);
0201     if (!sch->schib.pmcw.ena)
0202         return -EINVAL;
0203     if (cdev->private->state == DEV_STATE_NOT_OPER)
0204         return -ENODEV;
0205     if (cdev->private->state == DEV_STATE_VERIFY) {
0206         /* Remember to fake irb when finished. */
0207         if (!cdev->private->flags.fake_irb) {
0208             cdev->private->flags.fake_irb = FAKE_CMD_IRB;
0209             cdev->private->intparm = intparm;
0210             return 0;
0211         } else
0212             /* There's already a fake I/O around. */
0213             return -EBUSY;
0214     }
0215     if (cdev->private->state != DEV_STATE_ONLINE ||
0216         ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&
0217          !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) ||
0218         cdev->private->flags.doverify)
0219         return -EBUSY;
0220     ret = cio_set_options (sch, flags);
0221     if (ret)
0222         return ret;
0223     /* Adjust requested path mask to exclude unusable paths. */
0224     if (lpm) {
0225         lpm &= sch->lpm;
0226         if (lpm == 0)
0227             return -EACCES;
0228     }
0229     ret = cio_start_key (sch, cpa, lpm, key);
0230     switch (ret) {
0231     case 0:
0232         cdev->private->intparm = intparm;
0233         if (expires)
0234             ccw_device_set_timeout(cdev, expires);
0235         break;
0236     case -EACCES:
0237     case -ENODEV:
0238         dev_fsm_event(cdev, DEV_EVENT_VERIFY);
0239         break;
0240     }
0241     return ret;
0242 }
0243 
0244 /**
0245  * ccw_device_start_key() - start a s390 channel program with key
0246  * @cdev: target ccw device
0247  * @cpa: logical start address of channel program
0248  * @intparm: user specific interruption parameter; will be presented back to
0249  *       @cdev's interrupt handler. Allows a device driver to associate
0250  *       the interrupt with a particular I/O request.
0251  * @lpm: defines the channel path to be used for a specific I/O request. A
0252  *   value of 0 will make cio use the opm.
0253  * @key: storage key to be used for the I/O
0254  * @flags: additional flags; defines the action to be performed for I/O
0255  *     processing.
0256  *
0257  * Start a S/390 channel program. When the interrupt arrives, the
0258  * IRQ handler is called, either immediately, delayed (dev-end missing,
0259  * or sense required) or never (no IRQ handler registered).
0260  * The interruption handler will echo back the @intparm specified here, unless
0261  * another interruption parameter is specified by a subsequent invocation of
0262  * ccw_device_halt() or ccw_device_clear().
0263  * Returns:
0264  *  %0, if the operation was successful;
0265  *  -%EBUSY, if the device is busy, or status pending;
0266  *  -%EACCES, if no path specified in @lpm is operational;
0267  *  -%ENODEV, if the device is not operational.
0268  * Context:
0269  *  Interrupts disabled, ccw device lock held
0270  */
0271 int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
0272              unsigned long intparm, __u8 lpm, __u8 key,
0273              unsigned long flags)
0274 {
0275     return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, key,
0276                         flags, 0);
0277 }
0278 
0279 /**
0280  * ccw_device_start() - start a s390 channel program
0281  * @cdev: target ccw device
0282  * @cpa: logical start address of channel program
0283  * @intparm: user specific interruption parameter; will be presented back to
0284  *       @cdev's interrupt handler. Allows a device driver to associate
0285  *       the interrupt with a particular I/O request.
0286  * @lpm: defines the channel path to be used for a specific I/O request. A
0287  *   value of 0 will make cio use the opm.
0288  * @flags: additional flags; defines the action to be performed for I/O
0289  *     processing.
0290  *
0291  * Start a S/390 channel program. When the interrupt arrives, the
0292  * IRQ handler is called, either immediately, delayed (dev-end missing,
0293  * or sense required) or never (no IRQ handler registered).
0294  * The interruption handler will echo back the @intparm specified here, unless
0295  * another interruption parameter is specified by a subsequent invocation of
0296  * ccw_device_halt() or ccw_device_clear().
0297  * Returns:
0298  *  %0, if the operation was successful;
0299  *  -%EBUSY, if the device is busy, or status pending;
0300  *  -%EACCES, if no path specified in @lpm is operational;
0301  *  -%ENODEV, if the device is not operational.
0302  * Context:
0303  *  Interrupts disabled, ccw device lock held
0304  */
0305 int ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
0306              unsigned long intparm, __u8 lpm, unsigned long flags)
0307 {
0308     return ccw_device_start_key(cdev, cpa, intparm, lpm,
0309                     PAGE_DEFAULT_KEY, flags);
0310 }
0311 
0312 /**
0313  * ccw_device_start_timeout() - start a s390 channel program with timeout
0314  * @cdev: target ccw device
0315  * @cpa: logical start address of channel program
0316  * @intparm: user specific interruption parameter; will be presented back to
0317  *       @cdev's interrupt handler. Allows a device driver to associate
0318  *       the interrupt with a particular I/O request.
0319  * @lpm: defines the channel path to be used for a specific I/O request. A
0320  *   value of 0 will make cio use the opm.
0321  * @flags: additional flags; defines the action to be performed for I/O
0322  *     processing.
0323  * @expires: timeout value in jiffies
0324  *
0325  * Start a S/390 channel program. When the interrupt arrives, the
0326  * IRQ handler is called, either immediately, delayed (dev-end missing,
0327  * or sense required) or never (no IRQ handler registered).
0328  * This function notifies the device driver if the channel program has not
0329  * completed during the time specified by @expires. If a timeout occurs, the
0330  * channel program is terminated via xsch, hsch or csch, and the device's
0331  * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
0332  * The interruption handler will echo back the @intparm specified here, unless
0333  * another interruption parameter is specified by a subsequent invocation of
0334  * ccw_device_halt() or ccw_device_clear().
0335  * Returns:
0336  *  %0, if the operation was successful;
0337  *  -%EBUSY, if the device is busy, or status pending;
0338  *  -%EACCES, if no path specified in @lpm is operational;
0339  *  -%ENODEV, if the device is not operational.
0340  * Context:
0341  *  Interrupts disabled, ccw device lock held
0342  */
0343 int ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
0344                  unsigned long intparm, __u8 lpm,
0345                  unsigned long flags, int expires)
0346 {
0347     return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
0348                         PAGE_DEFAULT_KEY, flags,
0349                         expires);
0350 }
0351 
0352 
0353 /**
0354  * ccw_device_halt() - halt I/O request processing
0355  * @cdev: target ccw device
0356  * @intparm: interruption parameter to be returned upon conclusion of hsch
0357  *
0358  * ccw_device_halt() calls hsch on @cdev's subchannel.
0359  * The interruption handler will echo back the @intparm specified here, unless
0360  * another interruption parameter is specified by a subsequent invocation of
0361  * ccw_device_clear().
0362  * Returns:
0363  *  %0 on success,
0364  *  -%ENODEV on device not operational,
0365  *  -%EINVAL on invalid device state,
0366  *  -%EBUSY on device busy or interrupt pending.
0367  * Context:
0368  *  Interrupts disabled, ccw device lock held
0369  */
0370 int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
0371 {
0372     struct subchannel *sch;
0373     int ret;
0374 
0375     if (!cdev || !cdev->dev.parent)
0376         return -ENODEV;
0377     sch = to_subchannel(cdev->dev.parent);
0378     if (!sch->schib.pmcw.ena)
0379         return -EINVAL;
0380     if (cdev->private->state == DEV_STATE_NOT_OPER)
0381         return -ENODEV;
0382     if (cdev->private->state != DEV_STATE_ONLINE &&
0383         cdev->private->state != DEV_STATE_W4SENSE)
0384         return -EINVAL;
0385 
0386     ret = cio_halt(sch);
0387     if (ret == 0)
0388         cdev->private->intparm = intparm;
0389     return ret;
0390 }
0391 
0392 /**
0393  * ccw_device_resume() - resume channel program execution
0394  * @cdev: target ccw device
0395  *
0396  * ccw_device_resume() calls rsch on @cdev's subchannel.
0397  * Returns:
0398  *  %0 on success,
0399  *  -%ENODEV on device not operational,
0400  *  -%EINVAL on invalid device state,
0401  *  -%EBUSY on device busy or interrupt pending.
0402  * Context:
0403  *  Interrupts disabled, ccw device lock held
0404  */
0405 int ccw_device_resume(struct ccw_device *cdev)
0406 {
0407     struct subchannel *sch;
0408 
0409     if (!cdev || !cdev->dev.parent)
0410         return -ENODEV;
0411     sch = to_subchannel(cdev->dev.parent);
0412     if (!sch->schib.pmcw.ena)
0413         return -EINVAL;
0414     if (cdev->private->state == DEV_STATE_NOT_OPER)
0415         return -ENODEV;
0416     if (cdev->private->state != DEV_STATE_ONLINE ||
0417         !(sch->schib.scsw.cmd.actl & SCSW_ACTL_SUSPENDED))
0418         return -EINVAL;
0419     return cio_resume(sch);
0420 }
0421 
0422 /**
0423  * ccw_device_get_ciw() - Search for CIW command in extended sense data.
0424  * @cdev: ccw device to inspect
0425  * @ct: command type to look for
0426  *
0427  * During SenseID, command information words (CIWs) describing special
0428  * commands available to the device may have been stored in the extended
0429  * sense data. This function searches for CIWs of a specified command
0430  * type in the extended sense data.
0431  * Returns:
0432  *  %NULL if no extended sense data has been stored or if no CIW of the
0433  *  specified command type could be found,
0434  *  else a pointer to the CIW of the specified command type.
0435  */
0436 struct ciw *ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct)
0437 {
0438     int ciw_cnt;
0439 
0440     if (cdev->private->flags.esid == 0)
0441         return NULL;
0442     for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++)
0443         if (cdev->private->dma_area->senseid.ciw[ciw_cnt].ct == ct)
0444             return cdev->private->dma_area->senseid.ciw + ciw_cnt;
0445     return NULL;
0446 }
0447 
0448 /**
0449  * ccw_device_get_path_mask() - get currently available paths
0450  * @cdev: ccw device to be queried
0451  * Returns:
0452  *  %0 if no subchannel for the device is available,
0453  *  else the mask of currently available paths for the ccw device's subchannel.
0454  */
0455 __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
0456 {
0457     struct subchannel *sch;
0458 
0459     if (!cdev->dev.parent)
0460         return 0;
0461 
0462     sch = to_subchannel(cdev->dev.parent);
0463     return sch->lpm;
0464 }
0465 
0466 /**
0467  * ccw_device_get_chp_desc() - return newly allocated channel-path descriptor
0468  * @cdev: device to obtain the descriptor for
0469  * @chp_idx: index of the channel path
0470  *
0471  * On success return a newly allocated copy of the channel-path description
0472  * data associated with the given channel path. Return %NULL on error.
0473  */
0474 struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *cdev,
0475                                int chp_idx)
0476 {
0477     struct subchannel *sch;
0478     struct chp_id chpid;
0479 
0480     sch = to_subchannel(cdev->dev.parent);
0481     chp_id_init(&chpid);
0482     chpid.id = sch->schib.pmcw.chpid[chp_idx];
0483     return chp_get_chp_desc(chpid);
0484 }
0485 
0486 /**
0487  * ccw_device_get_util_str() - return newly allocated utility strings
0488  * @cdev: device to obtain the utility strings for
0489  * @chp_idx: index of the channel path
0490  *
0491  * On success return a newly allocated copy of the utility strings
0492  * associated with the given channel path. Return %NULL on error.
0493  */
0494 u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx)
0495 {
0496     struct subchannel *sch = to_subchannel(cdev->dev.parent);
0497     struct channel_path *chp;
0498     struct chp_id chpid;
0499     u8 *util_str;
0500 
0501     chp_id_init(&chpid);
0502     chpid.id = sch->schib.pmcw.chpid[chp_idx];
0503     chp = chpid_to_chp(chpid);
0504 
0505     util_str = kmalloc(sizeof(chp->desc_fmt3.util_str), GFP_KERNEL);
0506     if (!util_str)
0507         return NULL;
0508 
0509     mutex_lock(&chp->lock);
0510     memcpy(util_str, chp->desc_fmt3.util_str, sizeof(chp->desc_fmt3.util_str));
0511     mutex_unlock(&chp->lock);
0512 
0513     return util_str;
0514 }
0515 
0516 /**
0517  * ccw_device_get_id() - obtain a ccw device id
0518  * @cdev: device to obtain the id for
0519  * @dev_id: where to fill in the values
0520  */
0521 void ccw_device_get_id(struct ccw_device *cdev, struct ccw_dev_id *dev_id)
0522 {
0523     *dev_id = cdev->private->dev_id;
0524 }
0525 EXPORT_SYMBOL(ccw_device_get_id);
0526 
0527 /**
0528  * ccw_device_tm_start_timeout_key() - perform start function
0529  * @cdev: ccw device on which to perform the start function
0530  * @tcw: transport-command word to be started
0531  * @intparm: user defined parameter to be passed to the interrupt handler
0532  * @lpm: mask of paths to use
0533  * @key: storage key to use for storage access
0534  * @expires: time span in jiffies after which to abort request
0535  *
0536  * Start the tcw on the given ccw device. Return zero on success, non-zero
0537  * otherwise.
0538  */
0539 int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
0540                     unsigned long intparm, u8 lpm, u8 key,
0541                     int expires)
0542 {
0543     struct subchannel *sch;
0544     int rc;
0545 
0546     sch = to_subchannel(cdev->dev.parent);
0547     if (!sch->schib.pmcw.ena)
0548         return -EINVAL;
0549     if (cdev->private->state == DEV_STATE_VERIFY) {
0550         /* Remember to fake irb when finished. */
0551         if (!cdev->private->flags.fake_irb) {
0552             cdev->private->flags.fake_irb = FAKE_TM_IRB;
0553             cdev->private->intparm = intparm;
0554             return 0;
0555         } else
0556             /* There's already a fake I/O around. */
0557             return -EBUSY;
0558     }
0559     if (cdev->private->state != DEV_STATE_ONLINE)
0560         return -EIO;
0561     /* Adjust requested path mask to exclude unusable paths. */
0562     if (lpm) {
0563         lpm &= sch->lpm;
0564         if (lpm == 0)
0565             return -EACCES;
0566     }
0567     rc = cio_tm_start_key(sch, tcw, lpm, key);
0568     if (rc == 0) {
0569         cdev->private->intparm = intparm;
0570         if (expires)
0571             ccw_device_set_timeout(cdev, expires);
0572     }
0573     return rc;
0574 }
0575 EXPORT_SYMBOL(ccw_device_tm_start_timeout_key);
0576 
0577 /**
0578  * ccw_device_tm_start_key() - perform start function
0579  * @cdev: ccw device on which to perform the start function
0580  * @tcw: transport-command word to be started
0581  * @intparm: user defined parameter to be passed to the interrupt handler
0582  * @lpm: mask of paths to use
0583  * @key: storage key to use for storage access
0584  *
0585  * Start the tcw on the given ccw device. Return zero on success, non-zero
0586  * otherwise.
0587  */
0588 int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
0589                 unsigned long intparm, u8 lpm, u8 key)
0590 {
0591     return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm, key, 0);
0592 }
0593 EXPORT_SYMBOL(ccw_device_tm_start_key);
0594 
0595 /**
0596  * ccw_device_tm_start() - perform start function
0597  * @cdev: ccw device on which to perform the start function
0598  * @tcw: transport-command word to be started
0599  * @intparm: user defined parameter to be passed to the interrupt handler
0600  * @lpm: mask of paths to use
0601  *
0602  * Start the tcw on the given ccw device. Return zero on success, non-zero
0603  * otherwise.
0604  */
0605 int ccw_device_tm_start(struct ccw_device *cdev, struct tcw *tcw,
0606             unsigned long intparm, u8 lpm)
0607 {
0608     return ccw_device_tm_start_key(cdev, tcw, intparm, lpm,
0609                        PAGE_DEFAULT_KEY);
0610 }
0611 EXPORT_SYMBOL(ccw_device_tm_start);
0612 
0613 /**
0614  * ccw_device_tm_start_timeout() - perform start function
0615  * @cdev: ccw device on which to perform the start function
0616  * @tcw: transport-command word to be started
0617  * @intparm: user defined parameter to be passed to the interrupt handler
0618  * @lpm: mask of paths to use
0619  * @expires: time span in jiffies after which to abort request
0620  *
0621  * Start the tcw on the given ccw device. Return zero on success, non-zero
0622  * otherwise.
0623  */
0624 int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw,
0625                    unsigned long intparm, u8 lpm, int expires)
0626 {
0627     return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm,
0628                            PAGE_DEFAULT_KEY, expires);
0629 }
0630 EXPORT_SYMBOL(ccw_device_tm_start_timeout);
0631 
0632 /**
0633  * ccw_device_get_mdc() - accumulate max data count
0634  * @cdev: ccw device for which the max data count is accumulated
0635  * @mask: mask of paths to use
0636  *
0637  * Return the number of 64K-bytes blocks all paths at least support
0638  * for a transport command. Return value 0 indicates failure.
0639  */
0640 int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
0641 {
0642     struct subchannel *sch = to_subchannel(cdev->dev.parent);
0643     struct channel_path *chp;
0644     struct chp_id chpid;
0645     int mdc = 0, i;
0646 
0647     /* Adjust requested path mask to excluded varied off paths. */
0648     if (mask)
0649         mask &= sch->lpm;
0650     else
0651         mask = sch->lpm;
0652 
0653     chp_id_init(&chpid);
0654     for (i = 0; i < 8; i++) {
0655         if (!(mask & (0x80 >> i)))
0656             continue;
0657         chpid.id = sch->schib.pmcw.chpid[i];
0658         chp = chpid_to_chp(chpid);
0659         if (!chp)
0660             continue;
0661 
0662         mutex_lock(&chp->lock);
0663         if (!chp->desc_fmt1.f) {
0664             mutex_unlock(&chp->lock);
0665             return 0;
0666         }
0667         if (!chp->desc_fmt1.r)
0668             mdc = 1;
0669         mdc = mdc ? min_t(int, mdc, chp->desc_fmt1.mdc) :
0670                 chp->desc_fmt1.mdc;
0671         mutex_unlock(&chp->lock);
0672     }
0673 
0674     return mdc;
0675 }
0676 EXPORT_SYMBOL(ccw_device_get_mdc);
0677 
0678 /**
0679  * ccw_device_tm_intrg() - perform interrogate function
0680  * @cdev: ccw device on which to perform the interrogate function
0681  *
0682  * Perform an interrogate function on the given ccw device. Return zero on
0683  * success, non-zero otherwise.
0684  */
0685 int ccw_device_tm_intrg(struct ccw_device *cdev)
0686 {
0687     struct subchannel *sch = to_subchannel(cdev->dev.parent);
0688 
0689     if (!sch->schib.pmcw.ena)
0690         return -EINVAL;
0691     if (cdev->private->state != DEV_STATE_ONLINE)
0692         return -EIO;
0693     if (!scsw_is_tm(&sch->schib.scsw) ||
0694         !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
0695         return -EINVAL;
0696     return cio_tm_intrg(sch);
0697 }
0698 EXPORT_SYMBOL(ccw_device_tm_intrg);
0699 
0700 /**
0701  * ccw_device_get_schid() - obtain a subchannel id
0702  * @cdev: device to obtain the id for
0703  * @schid: where to fill in the values
0704  */
0705 void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid)
0706 {
0707     struct subchannel *sch = to_subchannel(cdev->dev.parent);
0708 
0709     *schid = sch->schid;
0710 }
0711 EXPORT_SYMBOL_GPL(ccw_device_get_schid);
0712 
0713 /**
0714  * ccw_device_pnso() - Perform Network-Subchannel Operation
0715  * @cdev:       device on which PNSO is performed
0716  * @pnso_area:      request and response block for the operation
0717  * @oc:         Operation Code
0718  * @resume_token:   resume token for multiblock response
0719  * @cnc:        Boolean change-notification control
0720  *
0721  * pnso_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)
0722  *
0723  * Returns 0 on success.
0724  */
0725 int ccw_device_pnso(struct ccw_device *cdev,
0726             struct chsc_pnso_area *pnso_area, u8 oc,
0727             struct chsc_pnso_resume_token resume_token, int cnc)
0728 {
0729     struct subchannel_id schid;
0730 
0731     ccw_device_get_schid(cdev, &schid);
0732     return chsc_pnso(schid, pnso_area, oc, resume_token, cnc);
0733 }
0734 EXPORT_SYMBOL_GPL(ccw_device_pnso);
0735 
0736 /**
0737  * ccw_device_get_cssid() - obtain Channel Subsystem ID
0738  * @cdev: device to obtain the CSSID for
0739  * @cssid: The resulting Channel Subsystem ID
0740  */
0741 int ccw_device_get_cssid(struct ccw_device *cdev, u8 *cssid)
0742 {
0743     struct device *sch_dev = cdev->dev.parent;
0744     struct channel_subsystem *css = to_css(sch_dev->parent);
0745 
0746     if (css->id_valid)
0747         *cssid = css->cssid;
0748     return css->id_valid ? 0 : -ENODEV;
0749 }
0750 EXPORT_SYMBOL_GPL(ccw_device_get_cssid);
0751 
0752 /**
0753  * ccw_device_get_iid() - obtain MIF-image ID
0754  * @cdev: device to obtain the MIF-image ID for
0755  * @iid: The resulting MIF-image ID
0756  */
0757 int ccw_device_get_iid(struct ccw_device *cdev, u8 *iid)
0758 {
0759     struct device *sch_dev = cdev->dev.parent;
0760     struct channel_subsystem *css = to_css(sch_dev->parent);
0761 
0762     if (css->id_valid)
0763         *iid = css->iid;
0764     return css->id_valid ? 0 : -ENODEV;
0765 }
0766 EXPORT_SYMBOL_GPL(ccw_device_get_iid);
0767 
0768 /**
0769  * ccw_device_get_chpid() - obtain Channel Path ID
0770  * @cdev: device to obtain the Channel Path ID for
0771  * @chp_idx: Index of the channel path
0772  * @chpid: The resulting Channel Path ID
0773  */
0774 int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid)
0775 {
0776     struct subchannel *sch = to_subchannel(cdev->dev.parent);
0777     int mask;
0778 
0779     if ((chp_idx < 0) || (chp_idx > 7))
0780         return -EINVAL;
0781     mask = 0x80 >> chp_idx;
0782     if (!(sch->schib.pmcw.pim & mask))
0783         return -ENODEV;
0784 
0785     *chpid = sch->schib.pmcw.chpid[chp_idx];
0786     return 0;
0787 }
0788 EXPORT_SYMBOL_GPL(ccw_device_get_chpid);
0789 
0790 /**
0791  * ccw_device_get_chid() - obtain Channel ID associated with specified CHPID
0792  * @cdev: device to obtain the Channel ID for
0793  * @chp_idx: Index of the channel path
0794  * @chid: The resulting Channel ID
0795  */
0796 int ccw_device_get_chid(struct ccw_device *cdev, int chp_idx, u16 *chid)
0797 {
0798     struct chp_id cssid_chpid;
0799     struct channel_path *chp;
0800     int rc;
0801 
0802     chp_id_init(&cssid_chpid);
0803     rc = ccw_device_get_chpid(cdev, chp_idx, &cssid_chpid.id);
0804     if (rc)
0805         return rc;
0806     chp = chpid_to_chp(cssid_chpid);
0807     if (!chp)
0808         return -ENODEV;
0809 
0810     mutex_lock(&chp->lock);
0811     if (chp->desc_fmt1.flags & 0x10)
0812         *chid = chp->desc_fmt1.chid;
0813     else
0814         rc = -ENODEV;
0815     mutex_unlock(&chp->lock);
0816 
0817     return rc;
0818 }
0819 EXPORT_SYMBOL_GPL(ccw_device_get_chid);
0820 
0821 /*
0822  * Allocate zeroed dma coherent 31 bit addressable memory using
0823  * the subchannels dma pool. Maximal size of allocation supported
0824  * is PAGE_SIZE.
0825  */
0826 void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size)
0827 {
0828     void *addr;
0829 
0830     if (!get_device(&cdev->dev))
0831         return NULL;
0832     addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size);
0833     if (IS_ERR_OR_NULL(addr))
0834         put_device(&cdev->dev);
0835     return addr;
0836 }
0837 EXPORT_SYMBOL(ccw_device_dma_zalloc);
0838 
0839 void ccw_device_dma_free(struct ccw_device *cdev, void *cpu_addr, size_t size)
0840 {
0841     if (!cpu_addr)
0842         return;
0843     cio_gp_dma_free(cdev->private->dma_pool, cpu_addr, size);
0844     put_device(&cdev->dev);
0845 }
0846 EXPORT_SYMBOL(ccw_device_dma_free);
0847 
0848 EXPORT_SYMBOL(ccw_device_set_options_mask);
0849 EXPORT_SYMBOL(ccw_device_set_options);
0850 EXPORT_SYMBOL(ccw_device_clear_options);
0851 EXPORT_SYMBOL(ccw_device_clear);
0852 EXPORT_SYMBOL(ccw_device_halt);
0853 EXPORT_SYMBOL(ccw_device_resume);
0854 EXPORT_SYMBOL(ccw_device_start_timeout);
0855 EXPORT_SYMBOL(ccw_device_start);
0856 EXPORT_SYMBOL(ccw_device_start_timeout_key);
0857 EXPORT_SYMBOL(ccw_device_start_key);
0858 EXPORT_SYMBOL(ccw_device_get_ciw);
0859 EXPORT_SYMBOL(ccw_device_get_path_mask);
0860 EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc);
0861 EXPORT_SYMBOL_GPL(ccw_device_get_util_str);