/*
 * 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 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(NUMA_NO_NODE);
	if (!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));
	blk_queue_logical_block_size(dev->disk->queue, bsize);
	err = add_disk(dev->disk);
	if (err)
		goto out_cleanup_disk;

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

	return 0;

out_cleanup_disk:
	blk_cleanup_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);
		blk_cleanup_disk(dev->disk);
		kfree(dev);
	}
	unregister_blkdev(major_num, "nfhd");
}

module_init(nfhd_init);
module_exit(nfhd_exit);

MODULE_LICENSE("GPL");
