/*
 * osd_uld.c - OSD Upper Layer Driver
 *
 * A Linux driver module that registers as a SCSI ULD and probes
 * for OSD type SCSI devices.
 * It's main function is to export osd devices to in-kernel users like
 * osdfs and pNFS-objects-LD. It also provides one ioctl for running
 * in Kernel tests.
 *
 * Copyright (C) 2008 Panasas Inc.  All rights reserved.
 *
 * Authors:
 *   Boaz Harrosh <ooo@electrozaur.com>
 *   Benny Halevy <bhalevy@panasas.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the Panasas company nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/namei.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/major.h>
#include <linux/file.h>
#include <linux/slab.h>

#include <scsi/scsi.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_ioctl.h>

#include <scsi/osd_initiator.h>
#include <scsi/osd_sec.h>

#include "osd_debug.h"

#ifndef TYPE_OSD
#  define TYPE_OSD 0x11
#endif

#ifndef SCSI_OSD_MAJOR
#  define SCSI_OSD_MAJOR 260
#endif
#define SCSI_OSD_MAX_MINOR MINORMASK

static const char osd_name[] = "osd";
static const char *osd_version_string = "open-osd 0.2.1";

MODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>");
MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(SCSI_OSD_MAJOR);
MODULE_ALIAS_SCSI_DEVICE(TYPE_OSD);

struct osd_uld_device {
	int minor;
	struct device class_dev;
	struct cdev cdev;
	struct osd_dev od;
	struct osd_dev_info odi;
	struct gendisk *disk;
};

struct osd_dev_handle {
	struct osd_dev od;
	struct file *file;
	struct osd_uld_device *oud;
} ;

static DEFINE_IDA(osd_minor_ida);

/*
 * scsi sysfs attribute operations
 */
static ssize_t osdname_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct osd_uld_device *ould = container_of(dev, struct osd_uld_device,
						   class_dev);
	return sprintf(buf, "%s\n", ould->odi.osdname);
}
static DEVICE_ATTR_RO(osdname);

static ssize_t systemid_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct osd_uld_device *ould = container_of(dev, struct osd_uld_device,
						   class_dev);

	memcpy(buf, ould->odi.systemid, ould->odi.systemid_len);
	return ould->odi.systemid_len;
}
static DEVICE_ATTR_RO(systemid);

static struct attribute *osd_uld_attrs[] = {
	&dev_attr_osdname.attr,
	&dev_attr_systemid.attr,
	NULL,
};
ATTRIBUTE_GROUPS(osd_uld);

static struct class osd_uld_class = {
	.owner		= THIS_MODULE,
	.name		= "scsi_osd",
	.dev_groups	= osd_uld_groups,
};

/*
 * Char Device operations
 */

static int osd_uld_open(struct inode *inode, struct file *file)
{
	struct osd_uld_device *oud = container_of(inode->i_cdev,
					struct osd_uld_device, cdev);

	get_device(&oud->class_dev);
	/* cache osd_uld_device on file handle */
	file->private_data = oud;
	OSD_DEBUG("osd_uld_open %p\n", oud);
	return 0;
}

static int osd_uld_release(struct inode *inode, struct file *file)
{
	struct osd_uld_device *oud = file->private_data;

	OSD_DEBUG("osd_uld_release %p\n", file->private_data);
	file->private_data = NULL;
	put_device(&oud->class_dev);
	return 0;
}

/* FIXME: Only one vector for now */
unsigned g_test_ioctl;
do_test_fn *g_do_test;

int osduld_register_test(unsigned ioctl, do_test_fn *do_test)
{
	if (g_test_ioctl)
		return -EINVAL;

	g_test_ioctl = ioctl;
	g_do_test = do_test;
	return 0;
}
EXPORT_SYMBOL(osduld_register_test);

void osduld_unregister_test(unsigned ioctl)
{
	if (ioctl == g_test_ioctl) {
		g_test_ioctl = 0;
		g_do_test = NULL;
	}
}
EXPORT_SYMBOL(osduld_unregister_test);

static do_test_fn *_find_ioctl(unsigned cmd)
{
	if (g_test_ioctl == cmd)
		return g_do_test;
	else
		return NULL;
}

static long osd_uld_ioctl(struct file *file, unsigned int cmd,
	unsigned long arg)
{
	struct osd_uld_device *oud = file->private_data;
	int ret;
	do_test_fn *do_test;

	do_test = _find_ioctl(cmd);
	if (do_test)
		ret = do_test(&oud->od, cmd, arg);
	else {
		OSD_ERR("Unknown ioctl %d: osd_uld_device=%p\n", cmd, oud);
		ret = -ENOIOCTLCMD;
	}
	return ret;
}

static const struct file_operations osd_fops = {
	.owner          = THIS_MODULE,
	.open           = osd_uld_open,
	.release        = osd_uld_release,
	.unlocked_ioctl = osd_uld_ioctl,
	.llseek		= noop_llseek,
};

struct osd_dev *osduld_path_lookup(const char *name)
{
	struct osd_uld_device *oud;
	struct osd_dev_handle *odh;
	struct file *file;
	int error;

	if (!name || !*name) {
		OSD_ERR("Mount with !path || !*path\n");
		return ERR_PTR(-EINVAL);
	}

	odh = kzalloc(sizeof(*odh), GFP_KERNEL);
	if (unlikely(!odh))
		return ERR_PTR(-ENOMEM);

	file = filp_open(name, O_RDWR, 0);
	if (IS_ERR(file)) {
		error = PTR_ERR(file);
		goto free_od;
	}

	if (file->f_op != &osd_fops){
		error = -EINVAL;
		goto close_file;
	}

	oud = file->private_data;

	odh->od = oud->od;
	odh->file = file;
	odh->oud = oud;

	return &odh->od;

close_file:
	fput(file);
free_od:
	kfree(odh);
	return ERR_PTR(error);
}
EXPORT_SYMBOL(osduld_path_lookup);

static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len,
				     const u8 *a2, unsigned a2_len)
{
	if (!a2_len) /* User string is Empty means don't care */
		return true;

	if (a1_len != a2_len)
		return false;

	return 0 == memcmp(a1, a2, a1_len);
}

static int _match_odi(struct device *dev, const void *find_data)
{
	struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
						  class_dev);
	const struct osd_dev_info *odi = find_data;

	if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
			      odi->systemid, odi->systemid_len) &&
	    _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
			      odi->osdname, odi->osdname_len)) {
		OSD_DEBUG("found device sysid_len=%d osdname=%d\n",
			  odi->systemid_len, odi->osdname_len);
		return 1;
	} else {
		return 0;
	}
}

/* osduld_info_lookup - Loop through all devices, return the requested osd_dev.
 *
 * if @odi->systemid_len and/or @odi->osdname_len are zero, they act as a don't
 * care. .e.g if they're both zero /dev/osd0 is returned.
 */
struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi)
{
	struct device *dev = class_find_device(&osd_uld_class, NULL, odi, _match_odi);
	if (likely(dev)) {
		struct osd_dev_handle *odh = kzalloc(sizeof(*odh), GFP_KERNEL);
		struct osd_uld_device *oud = container_of(dev,
			struct osd_uld_device, class_dev);

		if (unlikely(!odh)) {
			put_device(dev);
			return ERR_PTR(-ENOMEM);
		}

		odh->od = oud->od;
		odh->oud = oud;

		return &odh->od;
	}

	return ERR_PTR(-ENODEV);
}
EXPORT_SYMBOL(osduld_info_lookup);

void osduld_put_device(struct osd_dev *od)
{
	if (od && !IS_ERR(od)) {
		struct osd_dev_handle *odh =
				container_of(od, struct osd_dev_handle, od);
		struct osd_uld_device *oud = odh->oud;

		BUG_ON(od->scsi_device != oud->od.scsi_device);

		/* If scsi has released the device (logout), and exofs has last
		 * reference on oud it will be freed by above osd_uld_release
		 * within fput below. But this will oops in cdev_release which
		 * is called after the fops->release. A get_/put_ pair makes
		 * sure we have a cdev for the duration of fput
		 */
		if (odh->file) {
			get_device(&oud->class_dev);
			fput(odh->file);
		}
		put_device(&oud->class_dev);
		kfree(odh);
	}
}
EXPORT_SYMBOL(osduld_put_device);

const struct osd_dev_info *osduld_device_info(struct osd_dev *od)
{
	struct osd_dev_handle *odh =
				container_of(od, struct osd_dev_handle, od);
	return &odh->oud->odi;
}
EXPORT_SYMBOL(osduld_device_info);

bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi)
{
	struct osd_dev_handle *odh =
				container_of(od, struct osd_dev_handle, od);
	struct osd_uld_device *oud = odh->oud;

	return (oud->odi.systemid_len == odi->systemid_len) &&
		_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
				 odi->systemid, odi->systemid_len) &&
		(oud->odi.osdname_len == odi->osdname_len) &&
		_the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
				  odi->osdname, odi->osdname_len);
}
EXPORT_SYMBOL(osduld_device_same);

/*
 * Scsi Device operations
 */

static int __detect_osd(struct osd_uld_device *oud)
{
	struct scsi_device *scsi_device = oud->od.scsi_device;
	struct scsi_sense_hdr sense_hdr;
	char caps[OSD_CAP_LEN];
	int error;

	/* sending a test_unit_ready as first command seems to be needed
	 * by some targets
	 */
	OSD_DEBUG("start scsi_test_unit_ready %p %p %p\n",
			oud, scsi_device, scsi_device->request_queue);
	error = scsi_test_unit_ready(scsi_device, 10*HZ, 5, &sense_hdr);
	if (error)
		OSD_ERR("warning: scsi_test_unit_ready failed\n");

	osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
	if (osd_auto_detect_ver(&oud->od, caps, &oud->odi))
		return -ENODEV;

	return 0;
}

static void __remove(struct device *dev)
{
	struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
						  class_dev);
	struct scsi_device *scsi_device = oud->od.scsi_device;

	kfree(oud->odi.osdname);

	osd_dev_fini(&oud->od);
	scsi_device_put(scsi_device);

	OSD_INFO("osd_remove %s\n",
		 oud->disk ? oud->disk->disk_name : NULL);

	if (oud->disk)
		put_disk(oud->disk);

	kfree(oud);
}

static int osd_probe(struct device *dev)
{
	struct scsi_device *scsi_device = to_scsi_device(dev);
	struct gendisk *disk;
	struct osd_uld_device *oud;
	int minor;
	int error;

	if (scsi_device->type != TYPE_OSD)
		return -ENODEV;

	minor = ida_alloc_max(&osd_minor_ida, SCSI_OSD_MAX_MINOR, GFP_KERNEL);
	if (minor == -ENOSPC)
		return -EBUSY;
	if (minor < 0)
		return -ENODEV;

	error = -ENOMEM;
	oud = kzalloc(sizeof(*oud), GFP_KERNEL);
	if (NULL == oud)
		goto err_retract_minor;

	/* class device member */
	device_initialize(&oud->class_dev);
	dev_set_drvdata(dev, oud);
	oud->minor = minor;
	oud->class_dev.devt = MKDEV(SCSI_OSD_MAJOR, oud->minor);
	oud->class_dev.class = &osd_uld_class;
	oud->class_dev.parent = dev;
	oud->class_dev.release = __remove;

	/* hold one more reference to the scsi_device that will get released
	 * in __release, in case a logout is happening while fs is mounted
	 */
	if (scsi_device_get(scsi_device))
		goto err_retract_minor;
	osd_dev_init(&oud->od, scsi_device);

	/* allocate a disk and set it up */
	/* FIXME: do we need this since sg has already done that */
	disk = alloc_disk(1);
	if (!disk) {
		OSD_ERR("alloc_disk failed\n");
		goto err_free_osd;
	}
	disk->major = SCSI_OSD_MAJOR;
	disk->first_minor = oud->minor;
	sprintf(disk->disk_name, "osd%d", oud->minor);
	oud->disk = disk;

	/* Detect the OSD Version */
	error = __detect_osd(oud);
	if (error) {
		OSD_ERR("osd detection failed, non-compatible OSD device\n");
		goto err_free_osd;
	}

	/* init the char-device for communication with user-mode */
	cdev_init(&oud->cdev, &osd_fops);
	oud->cdev.owner = THIS_MODULE;

	error = dev_set_name(&oud->class_dev, "%s", disk->disk_name);
	if (error) {
		OSD_ERR("dev_set_name failed => %d\n", error);
		goto err_free_osd;
	}

	error = cdev_device_add(&oud->cdev, &oud->class_dev);
	if (error) {
		OSD_ERR("device_register failed => %d\n", error);
		goto err_free_osd;
	}

	OSD_INFO("osd_probe %s\n", disk->disk_name);
	return 0;

err_free_osd:
	put_device(&oud->class_dev);
err_retract_minor:
	ida_free(&osd_minor_ida, minor);
	return error;
}

static int osd_remove(struct device *dev)
{
	struct scsi_device *scsi_device = to_scsi_device(dev);
	struct osd_uld_device *oud = dev_get_drvdata(dev);

	if (oud->od.scsi_device != scsi_device) {
		OSD_ERR("Half cooked osd-device %p, || %p!=%p",
			dev, oud->od.scsi_device, scsi_device);
	}

	cdev_device_del(&oud->cdev, &oud->class_dev);
	ida_free(&osd_minor_ida, oud->minor);
	put_device(&oud->class_dev);

	return 0;
}

/*
 * Global driver and scsi registration
 */

static struct scsi_driver osd_driver = {
	.gendrv = {
		.name		= osd_name,
		.owner		= THIS_MODULE,
		.probe		= osd_probe,
		.remove		= osd_remove,
	}
};

static int __init osd_uld_init(void)
{
	int err;

	err = class_register(&osd_uld_class);
	if (err) {
		OSD_ERR("Unable to register sysfs class => %d\n", err);
		return err;
	}

	err = register_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0),
				     SCSI_OSD_MAX_MINOR, osd_name);
	if (err) {
		OSD_ERR("Unable to register major %d for osd ULD => %d\n",
			SCSI_OSD_MAJOR, err);
		goto err_out;
	}

	err = scsi_register_driver(&osd_driver.gendrv);
	if (err) {
		OSD_ERR("scsi_register_driver failed => %d\n", err);
		goto err_out_chrdev;
	}

	OSD_INFO("LOADED %s\n", osd_version_string);
	return 0;

err_out_chrdev:
	unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
err_out:
	class_unregister(&osd_uld_class);
	return err;
}

static void __exit osd_uld_exit(void)
{
	scsi_unregister_driver(&osd_driver.gendrv);
	unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
	class_unregister(&osd_uld_class);
	OSD_INFO("UNLOADED %s\n", osd_version_string);
}

module_init(osd_uld_init);
module_exit(osd_uld_exit);
