124c98674SFarhan Ali // SPDX-License-Identifier: GPL-2.0 224c98674SFarhan Ali /* 324c98674SFarhan Ali * Channel path related status regions for vfio_ccw 424c98674SFarhan Ali * 524c98674SFarhan Ali * Copyright IBM Corp. 2020 624c98674SFarhan Ali * 724c98674SFarhan Ali * Author(s): Farhan Ali <alifm@linux.ibm.com> 824c98674SFarhan Ali * Eric Farman <farman@linux.ibm.com> 924c98674SFarhan Ali */ 1024c98674SFarhan Ali 1124c98674SFarhan Ali #include <linux/vfio.h> 1224c98674SFarhan Ali #include "vfio_ccw_private.h" 1324c98674SFarhan Ali 1424c98674SFarhan Ali static ssize_t vfio_ccw_schib_region_read(struct vfio_ccw_private *private, 1524c98674SFarhan Ali char __user *buf, size_t count, 1624c98674SFarhan Ali loff_t *ppos) 1724c98674SFarhan Ali { 1824c98674SFarhan Ali unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS; 1924c98674SFarhan Ali loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK; 2024c98674SFarhan Ali struct ccw_schib_region *region; 2124c98674SFarhan Ali int ret; 2224c98674SFarhan Ali 2324c98674SFarhan Ali if (pos + count > sizeof(*region)) 2424c98674SFarhan Ali return -EINVAL; 2524c98674SFarhan Ali 2624c98674SFarhan Ali mutex_lock(&private->io_mutex); 2724c98674SFarhan Ali region = private->region[i].data; 2824c98674SFarhan Ali 2924c98674SFarhan Ali if (cio_update_schib(private->sch)) { 3024c98674SFarhan Ali ret = -ENODEV; 3124c98674SFarhan Ali goto out; 3224c98674SFarhan Ali } 3324c98674SFarhan Ali 3424c98674SFarhan Ali memcpy(region, &private->sch->schib, sizeof(*region)); 3524c98674SFarhan Ali 3624c98674SFarhan Ali if (copy_to_user(buf, (void *)region + pos, count)) { 3724c98674SFarhan Ali ret = -EFAULT; 3824c98674SFarhan Ali goto out; 3924c98674SFarhan Ali } 4024c98674SFarhan Ali 4124c98674SFarhan Ali ret = count; 4224c98674SFarhan Ali 4324c98674SFarhan Ali out: 4424c98674SFarhan Ali mutex_unlock(&private->io_mutex); 4524c98674SFarhan Ali return ret; 4624c98674SFarhan Ali } 4724c98674SFarhan Ali 4824c98674SFarhan Ali static ssize_t vfio_ccw_schib_region_write(struct vfio_ccw_private *private, 4924c98674SFarhan Ali const char __user *buf, size_t count, 5024c98674SFarhan Ali loff_t *ppos) 5124c98674SFarhan Ali { 5224c98674SFarhan Ali return -EINVAL; 5324c98674SFarhan Ali } 5424c98674SFarhan Ali 5524c98674SFarhan Ali 5624c98674SFarhan Ali static void vfio_ccw_schib_region_release(struct vfio_ccw_private *private, 5724c98674SFarhan Ali struct vfio_ccw_region *region) 5824c98674SFarhan Ali { 5924c98674SFarhan Ali 6024c98674SFarhan Ali } 6124c98674SFarhan Ali 6224c98674SFarhan Ali const struct vfio_ccw_regops vfio_ccw_schib_region_ops = { 6324c98674SFarhan Ali .read = vfio_ccw_schib_region_read, 6424c98674SFarhan Ali .write = vfio_ccw_schib_region_write, 6524c98674SFarhan Ali .release = vfio_ccw_schib_region_release, 6624c98674SFarhan Ali }; 6724c98674SFarhan Ali 6824c98674SFarhan Ali int vfio_ccw_register_schib_dev_regions(struct vfio_ccw_private *private) 6924c98674SFarhan Ali { 7024c98674SFarhan Ali return vfio_ccw_register_dev_region(private, 7124c98674SFarhan Ali VFIO_REGION_SUBTYPE_CCW_SCHIB, 7224c98674SFarhan Ali &vfio_ccw_schib_region_ops, 7324c98674SFarhan Ali sizeof(struct ccw_schib_region), 7424c98674SFarhan Ali VFIO_REGION_INFO_FLAG_READ, 7524c98674SFarhan Ali private->schib_region); 7624c98674SFarhan Ali } 77