From 68c32eb2707aed0a3be1a60b0f206943a25e8f34 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 6 Sep 2021 13:59:26 +0200 Subject: [PATCH] s390: remove xpram device driver Support for expanded storage was only available until z13 and z/VM 6.3 respectively. However there haven't been any use cases a long time before for this device driver. Therefore remove it. Acked-by: Christian Borntraeger Signed-off-by: Heiko Carstens --- arch/s390/configs/defconfig | 1 - arch/s390/configs/zfcpdump_defconfig | 1 - drivers/s390/block/Kconfig | 11 - drivers/s390/block/Makefile | 1 - drivers/s390/block/xpram.c | 416 --------------------------- 5 files changed, 430 deletions(-) delete mode 100644 drivers/s390/block/xpram.c diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index e1642d2cba59..56a1cc85c5d7 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -397,7 +397,6 @@ CONFIG_BLK_DEV_DRBD=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -# CONFIG_BLK_DEV_XPRAM is not set CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_RBD=m CONFIG_BLK_DEV_NVME=m diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index d576aaab27c9..aceccf3b9a88 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -35,7 +35,6 @@ CONFIG_NET=y # CONFIG_ETHTOOL_NETLINK is not set CONFIG_DEVTMPFS=y CONFIG_BLK_DEV_RAM=y -# CONFIG_BLK_DEV_XPRAM is not set # CONFIG_DCSSBLK is not set # CONFIG_DASD is not set CONFIG_ENCLOSURE_SERVICES=y diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig index 376f1efbbb86..d0416dbd0cd8 100644 --- a/drivers/s390/block/Kconfig +++ b/drivers/s390/block/Kconfig @@ -2,17 +2,6 @@ comment "S/390 block device drivers" depends on S390 && BLOCK -config BLK_DEV_XPRAM - def_tristate m - prompt "XPRAM disk support" - depends on S390 && BLOCK - help - Select this option if you want to use your expanded storage on S/390 - or zSeries as a disk. This is useful as a _fast_ swap device if you - want to access more than 2G of memory when running in 31 bit mode. - This option is also available as a module which will be called - xpram. If unsure, say "N". - config DCSSBLK def_tristate m select FS_DAX_LIMITED diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index 60c85cff556f..a0a54d2f063f 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_DASD) += dasd_mod.o obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o -obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o obj-$(CONFIG_DCSSBLK) += dcssblk.o scm_block-objs := scm_drv.o scm_blk.o diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c deleted file mode 100644 index ce98fab4d43c..000000000000 --- a/drivers/s390/block/xpram.c +++ /dev/null @@ -1,416 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Xpram.c -- the S/390 expanded memory RAM-disk - * - * significant parts of this code are based on - * the sbull device driver presented in - * A. Rubini: Linux Device Drivers - * - * Author of XPRAM specific coding: Reinhard Buendgen - * buendgen@de.ibm.com - * Rewrite for 2.5: Martin Schwidefsky - * - * External interfaces: - * Interfaces to linux kernel - * xpram_setup: read kernel parameters - * Device specific file operations - * xpram_iotcl - * xpram_open - * - * "ad-hoc" partitioning: - * the expanded memory can be partitioned among several devices - * (with different minors). The partitioning set up can be - * set by kernel or module parameters (int devs & int sizes[]) - * - * Potential future improvements: - * generic hard disk support to replace ad-hoc partitioning - */ - -#define KMSG_COMPONENT "xpram" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt - -#include -#include -#include /* isdigit, isxdigit */ -#include -#include -#include -#include -#include /* HDIO_GETGEO */ -#include -#include -#include -#include - -#define XPRAM_NAME "xpram" -#define XPRAM_DEVS 1 /* one partition */ -#define XPRAM_MAX_DEVS 32 /* maximal number of devices (partitions) */ - -typedef struct { - unsigned int size; /* size of xpram segment in pages */ - unsigned int offset; /* start page of xpram segment */ -} xpram_device_t; - -static xpram_device_t xpram_devices[XPRAM_MAX_DEVS]; -static unsigned int xpram_sizes[XPRAM_MAX_DEVS]; -static struct gendisk *xpram_disks[XPRAM_MAX_DEVS]; -static unsigned int xpram_pages; -static int xpram_devs; - -/* - * Parameter parsing functions. - */ -static int devs = XPRAM_DEVS; -static char *sizes[XPRAM_MAX_DEVS]; - -module_param(devs, int, 0); -module_param_array(sizes, charp, NULL, 0); - -MODULE_PARM_DESC(devs, "number of devices (\"partitions\"), " \ - "the default is " __MODULE_STRING(XPRAM_DEVS) "\n"); -MODULE_PARM_DESC(sizes, "list of device (partition) sizes " \ - "the defaults are 0s \n" \ - "All devices with size 0 equally partition the " - "remaining space on the expanded strorage not " - "claimed by explicit sizes\n"); -MODULE_LICENSE("GPL"); - -/* - * Copy expanded memory page (4kB) into main memory - * Arguments - * page_addr: address of target page - * xpage_index: index of expandeded memory page - * Return value - * 0: if operation succeeds - * -EIO: if pgin failed - * -ENXIO: if xpram has vanished - */ -static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index) -{ - int cc = 2; /* return unused cc 2 if pgin traps */ - - asm volatile( - " .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */ - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc"); - if (cc == 3) - return -ENXIO; - if (cc == 2) - return -ENXIO; - if (cc == 1) - return -EIO; - return 0; -} - -/* - * Copy a 4kB page of main memory to an expanded memory page - * Arguments - * page_addr: address of source page - * xpage_index: index of expandeded memory page - * Return value - * 0: if operation succeeds - * -EIO: if pgout failed - * -ENXIO: if xpram has vanished - */ -static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index) -{ - int cc = 2; /* return unused cc 2 if pgin traps */ - - asm volatile( - " .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */ - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc"); - if (cc == 3) - return -ENXIO; - if (cc == 2) - return -ENXIO; - if (cc == 1) - return -EIO; - return 0; -} - -/* - * Check if xpram is available. - */ -static int __init xpram_present(void) -{ - unsigned long mem_page; - int rc; - - mem_page = (unsigned long) __get_free_page(GFP_KERNEL); - if (!mem_page) - return -ENOMEM; - rc = xpram_page_in(mem_page, 0); - free_page(mem_page); - return rc ? -ENXIO : 0; -} - -/* - * Return index of the last available xpram page. - */ -static unsigned long __init xpram_highest_page_index(void) -{ - unsigned int page_index, add_bit; - unsigned long mem_page; - - mem_page = (unsigned long) __get_free_page(GFP_KERNEL); - if (!mem_page) - return 0; - - page_index = 0; - add_bit = 1ULL << (sizeof(unsigned int)*8 - 1); - while (add_bit > 0) { - if (xpram_page_in(mem_page, page_index | add_bit) == 0) - page_index |= add_bit; - add_bit >>= 1; - } - - free_page (mem_page); - - return page_index; -} - -/* - * Block device make request function. - */ -static blk_qc_t xpram_submit_bio(struct bio *bio) -{ - xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data; - struct bio_vec bvec; - struct bvec_iter iter; - unsigned int index; - unsigned long page_addr; - unsigned long bytes; - - blk_queue_split(&bio); - - if ((bio->bi_iter.bi_sector & 7) != 0 || - (bio->bi_iter.bi_size & 4095) != 0) - /* Request is not page-aligned. */ - goto fail; - if ((bio->bi_iter.bi_size >> 12) > xdev->size) - /* Request size is no page-aligned. */ - goto fail; - if ((bio->bi_iter.bi_sector >> 3) > 0xffffffffU - xdev->offset) - goto fail; - index = (bio->bi_iter.bi_sector >> 3) + xdev->offset; - bio_for_each_segment(bvec, bio, iter) { - page_addr = (unsigned long) - kmap(bvec.bv_page) + bvec.bv_offset; - bytes = bvec.bv_len; - if ((page_addr & 4095) != 0 || (bytes & 4095) != 0) - /* More paranoia. */ - goto fail; - while (bytes > 0) { - if (bio_data_dir(bio) == READ) { - if (xpram_page_in(page_addr, index) != 0) - goto fail; - } else { - if (xpram_page_out(page_addr, index) != 0) - goto fail; - } - page_addr += 4096; - bytes -= 4096; - index++; - } - } - bio_endio(bio); - return BLK_QC_T_NONE; -fail: - bio_io_error(bio); - return BLK_QC_T_NONE; -} - -static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - unsigned long size; - - /* - * get geometry: we have to fake one... trim the size to a - * multiple of 64 (32k): tell we have 16 sectors, 4 heads, - * whatever cylinders. Tell also that data starts at sector. 4. - */ - size = (xpram_pages * 8) & ~0x3f; - geo->cylinders = size >> 6; - geo->heads = 4; - geo->sectors = 16; - geo->start = 4; - return 0; -} - -static const struct block_device_operations xpram_devops = -{ - .owner = THIS_MODULE, - .submit_bio = xpram_submit_bio, - .getgeo = xpram_getgeo, -}; - -/* - * Setup xpram_sizes array. - */ -static int __init xpram_setup_sizes(unsigned long pages) -{ - unsigned long mem_needed; - unsigned long mem_auto; - unsigned long long size; - char *sizes_end; - int mem_auto_no; - int i; - - /* Check number of devices. */ - if (devs <= 0 || devs > XPRAM_MAX_DEVS) { - pr_err("%d is not a valid number of XPRAM devices\n",devs); - return -EINVAL; - } - xpram_devs = devs; - - /* - * Copy sizes array to xpram_sizes and align partition - * sizes to page boundary. - */ - mem_needed = 0; - mem_auto_no = 0; - for (i = 0; i < xpram_devs; i++) { - if (sizes[i]) { - size = simple_strtoull(sizes[i], &sizes_end, 0); - switch (*sizes_end) { - case 'g': - case 'G': - size <<= 20; - break; - case 'm': - case 'M': - size <<= 10; - } - xpram_sizes[i] = (size + 3) & -4UL; - } - if (xpram_sizes[i]) - mem_needed += xpram_sizes[i]; - else - mem_auto_no++; - } - - pr_info(" number of devices (partitions): %d \n", xpram_devs); - for (i = 0; i < xpram_devs; i++) { - if (xpram_sizes[i]) - pr_info(" size of partition %d: %u kB\n", - i, xpram_sizes[i]); - else - pr_info(" size of partition %d to be set " - "automatically\n",i); - } - pr_info(" memory needed (for sized partitions): %lu kB\n", - mem_needed); - pr_info(" partitions to be sized automatically: %d\n", - mem_auto_no); - - if (mem_needed > pages * 4) { - pr_err("Not enough expanded memory available\n"); - return -EINVAL; - } - - /* - * partitioning: - * xpram_sizes[i] != 0; partition i has size xpram_sizes[i] kB - * else: ; all partitions with zero xpram_sizes[i] - * partition equally the remaining space - */ - if (mem_auto_no) { - mem_auto = ((pages - mem_needed / 4) / mem_auto_no) * 4; - pr_info(" automatically determined " - "partition size: %lu kB\n", mem_auto); - for (i = 0; i < xpram_devs; i++) - if (xpram_sizes[i] == 0) - xpram_sizes[i] = mem_auto; - } - return 0; -} - -static int __init xpram_setup_blkdev(void) -{ - unsigned long offset; - int i, rc = -ENOMEM; - - for (i = 0; i < xpram_devs; i++) { - xpram_disks[i] = blk_alloc_disk(NUMA_NO_NODE); - if (!xpram_disks[i]) - goto out; - blk_queue_flag_set(QUEUE_FLAG_NONROT, xpram_disks[i]->queue); - blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, - xpram_disks[i]->queue); - blk_queue_logical_block_size(xpram_disks[i]->queue, 4096); - } - - /* - * Register xpram major. - */ - rc = register_blkdev(XPRAM_MAJOR, XPRAM_NAME); - if (rc < 0) - goto out; - - /* - * Setup device structures. - */ - offset = 0; - for (i = 0; i < xpram_devs; i++) { - struct gendisk *disk = xpram_disks[i]; - - xpram_devices[i].size = xpram_sizes[i] / 4; - xpram_devices[i].offset = offset; - offset += xpram_devices[i].size; - disk->major = XPRAM_MAJOR; - disk->first_minor = i; - disk->minors = 1; - disk->fops = &xpram_devops; - disk->private_data = &xpram_devices[i]; - sprintf(disk->disk_name, "slram%d", i); - set_capacity(disk, xpram_sizes[i] << 1); - add_disk(disk); - } - - return 0; -out: - while (i--) - blk_cleanup_disk(xpram_disks[i]); - return rc; -} - -/* - * Finally, the init/exit functions. - */ -static void __exit xpram_exit(void) -{ - int i; - for (i = 0; i < xpram_devs; i++) { - del_gendisk(xpram_disks[i]); - blk_cleanup_disk(xpram_disks[i]); - } - unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); -} - -static int __init xpram_init(void) -{ - int rc; - - /* Find out size of expanded memory. */ - if (xpram_present() != 0) { - pr_err("No expanded memory available\n"); - return -ENODEV; - } - xpram_pages = xpram_highest_page_index() + 1; - pr_info(" %u pages expanded memory found (%lu KB).\n", - xpram_pages, (unsigned long) xpram_pages*4); - rc = xpram_setup_sizes(xpram_pages); - if (rc) - return rc; - return xpram_setup_blkdev(); -} - -module_init(xpram_init); -module_exit(xpram_exit); -- 2.20.1