/*
 * ARAnyM block device driver
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/slab.h>

#include <asm/natfeat.h>

static long nfhd_id;

enum {
	/* emulation entry points */
	NFHD_READ_WRITE = 10,
	NFHD_GET_CAPACITY = 14,

	/* skip ACSI devices */
	NFHD_DEV_OFFSET = 8,
};

static inline s32 nfhd_read_write(u32 major, u32 minor, u32 rwflag, u32 recno,
				  u32 count, u32 buf)
{
	return nf_call(nfhd_id + NFHD_READ_WRITE, major, minor, rwflag, recno,
		       count, buf);
}

static inline s32 nfhd_get_capacity(u32 major, u32 minor, u32 *blocks,
				    u32 *blocksize)
{
	return nf_call(nfhd_id + NFHD_GET_CAPACITY, major, minor,
		       virt_to_phys(blocks), virt_to_phys(blocksize));
}

static LIST_HEAD(nfhd_list);

static int major_num;
module_param(major_num, int, 0);

struct nfhd_device {
	struct list_head list;
	int id;
	u32 blocks, bsize;
	int bshift;
	struct gendisk *disk;
};

static void nfhd_submit_bio(struct bio *bio)
{
	struct nfhd_device *dev = bio->bi_bdev->bd_disk->private_data;
	struct bio_vec bvec;
	struct bvec_iter iter;
	int dir, len, shift;
	sector_t sec = bio->bi_iter.bi_sector;

	dir = bio_data_dir(bio);
	shift = dev->bshift;
	bio_for_each_segment(bvec, bio, iter) {
		len = bvec.bv_len;
		len >>= 9;
		nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
				page_to_phys(bvec.bv_page) + bvec.bv_offset);
		sec += len;
	}
	bio_endio(bio);
}

static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
	struct nfhd_device *dev = bdev->bd_disk->private_data;

	geo->cylinders = dev->blocks >> (6 - dev->bshift);
	geo->heads = 4;
	geo->sectors = 16;

	return 0;
}

static const struct block_device_operations nfhd_ops = {
	.owner	= THIS_MODULE,
	.submit_bio = nfhd_submit_bio,
	.getgeo	= nfhd_getgeo,
};

static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
{
	struct queue_limits lim = {
		.logical_block_size	= bsize,
	};
	struct nfhd_device *dev;
	int dev_id = id - NFHD_DEV_OFFSET;
	int err = -ENOMEM;

	pr_info("nfhd%u: found device with %u blocks (%u bytes)\n", dev_id,
		blocks, bsize);

	if (bsize < 512 || (bsize & (bsize - 1))) {
		pr_warn("nfhd%u: invalid block size\n", dev_id);
		return -EINVAL;
	}

	dev = kmalloc(sizeof(struct nfhd_device), GFP_KERNEL);
	if (!dev)
		goto out;

	dev->id = id;
	dev->blocks = blocks;
	dev->bsize = bsize;
	dev->bshift = ffs(bsize) - 10;

	dev->disk = blk_alloc_disk(&lim, NUMA_NO_NODE);
	if (IS_ERR(dev->disk)) {
		err = PTR_ERR(dev->disk);
		goto free_dev;
	}

	dev->disk->major = major_num;
	dev->disk->first_minor = dev_id * 16;
	dev->disk->minors = 16;
	dev->disk->fops = &nfhd_ops;
	dev->disk->private_data = dev;
	sprintf(dev->disk->disk_name, "nfhd%u", dev_id);
	set_capacity(dev->disk, (sector_t)blocks * (bsize / 512));
	err = add_disk(dev->disk);
	if (err)
		goto out_cleanup_disk;

	list_add_tail(&dev->list, &nfhd_list);

	return 0;

out_cleanup_disk:
	put_disk(dev->disk);
free_dev:
	kfree(dev);
out:
	return err;
}

static int __init nfhd_init(void)
{
	u32 blocks, bsize;
	int ret;
	int i;

	nfhd_id = nf_get_id("XHDI");
	if (!nfhd_id)
		return -ENODEV;

	ret = register_blkdev(major_num, "nfhd");
	if (ret < 0) {
		pr_warn("nfhd: unable to get major number\n");
		return ret;
	}

	if (!major_num)
		major_num = ret;

	for (i = NFHD_DEV_OFFSET; i < 24; i++) {
		if (nfhd_get_capacity(i, 0, &blocks, &bsize))
			continue;
		nfhd_init_one(i, blocks, bsize);
	}

	return 0;
}

static void __exit nfhd_exit(void)
{
	struct nfhd_device *dev, *next;

	list_for_each_entry_safe(dev, next, &nfhd_list, list) {
		list_del(&dev->list);
		del_gendisk(dev->disk);
		put_disk(dev->disk);
		kfree(dev);
	}
	unregister_blkdev(major_num, "nfhd");
}

module_init(nfhd_init);
module_exit(nfhd_exit);

MODULE_LICENSE("GPL");
