/*
 * zfcp device driver
 *
 * Userspace interface for accessing the
 * Access Control Lists / Control File Data Channel;
 * handling of response code and states for ports and LUNs.
 *
 * Copyright IBM Corporation 2008, 2010
 */

#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/slab.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <asm/compat.h>
#include <asm/ccwdev.h>
#include "zfcp_def.h"
#include "zfcp_ext.h"
#include "zfcp_fsf.h"

#define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL		0x00010001
#define ZFCP_CFDC_CMND_DOWNLOAD_FORCE		0x00010101
#define ZFCP_CFDC_CMND_FULL_ACCESS		0x00000201
#define ZFCP_CFDC_CMND_RESTRICTED_ACCESS	0x00000401
#define ZFCP_CFDC_CMND_UPLOAD			0x00010002

#define ZFCP_CFDC_DOWNLOAD			0x00000001
#define ZFCP_CFDC_UPLOAD			0x00000002
#define ZFCP_CFDC_WITH_CONTROL_FILE		0x00010000

#define ZFCP_CFDC_IOC_MAGIC                     0xDD
#define ZFCP_CFDC_IOC \
	_IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_data)

/**
 * struct zfcp_cfdc_data - data for ioctl cfdc interface
 * @signature: request signature
 * @devno: FCP adapter device number
 * @command: command code
 * @fsf_status: returns status of FSF command to userspace
 * @fsf_status_qual: returned to userspace
 * @payloads: access conflicts list
 * @control_file: access control table
 */
struct zfcp_cfdc_data {
	u32 signature;
	u32 devno;
	u32 command;
	u32 fsf_status;
	u8  fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
	u8  payloads[256];
	u8  control_file[0];
};

static int zfcp_cfdc_copy_from_user(struct scatterlist *sg,
				    void __user *user_buffer)
{
	unsigned int length;
	unsigned int size = ZFCP_CFDC_MAX_SIZE;

	while (size) {
		length = min((unsigned int)size, sg->length);
		if (copy_from_user(sg_virt(sg++), user_buffer, length))
			return -EFAULT;
		user_buffer += length;
		size -= length;
	}
	return 0;
}

static int zfcp_cfdc_copy_to_user(void __user  *user_buffer,
				  struct scatterlist *sg)
{
	unsigned int length;
	unsigned int size = ZFCP_CFDC_MAX_SIZE;

	while (size) {
		length = min((unsigned int) size, sg->length);
		if (copy_to_user(user_buffer, sg_virt(sg++), length))
			return -EFAULT;
		user_buffer += length;
		size -= length;
	}
	return 0;
}

static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
{
	char busid[9];
	struct ccw_device *cdev;
	struct zfcp_adapter *adapter;

	snprintf(busid, sizeof(busid), "0.0.%04x", devno);
	cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
	if (!cdev)
		return NULL;

	adapter = zfcp_ccw_adapter_by_cdev(cdev);

	put_device(&cdev->dev);
	return adapter;
}

static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
{
	switch (command) {
	case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL:
		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
		fsf_cfdc->option = FSF_CFDC_OPTION_NORMAL_MODE;
		break;
	case ZFCP_CFDC_CMND_DOWNLOAD_FORCE:
		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
		fsf_cfdc->option = FSF_CFDC_OPTION_FORCE;
		break;
	case ZFCP_CFDC_CMND_FULL_ACCESS:
		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
		fsf_cfdc->option = FSF_CFDC_OPTION_FULL_ACCESS;
		break;
	case ZFCP_CFDC_CMND_RESTRICTED_ACCESS:
		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
		fsf_cfdc->option = FSF_CFDC_OPTION_RESTRICTED_ACCESS;
		break;
	case ZFCP_CFDC_CMND_UPLOAD:
		fsf_cfdc->command = FSF_QTCB_UPLOAD_CONTROL_FILE;
		fsf_cfdc->option = 0;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int zfcp_cfdc_sg_setup(int command, struct scatterlist *sg,
			      u8 __user *control_file)
{
	int retval;
	retval = zfcp_sg_setup_table(sg, ZFCP_CFDC_PAGES);
	if (retval)
		return retval;

	sg[ZFCP_CFDC_PAGES - 1].length = ZFCP_CFDC_MAX_SIZE % PAGE_SIZE;

	if (command & ZFCP_CFDC_WITH_CONTROL_FILE &&
	    command & ZFCP_CFDC_DOWNLOAD) {
		retval = zfcp_cfdc_copy_from_user(sg, control_file);
		if (retval) {
			zfcp_sg_free_table(sg, ZFCP_CFDC_PAGES);
			return -EFAULT;
		}
	}

	return 0;
}

static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data,
				   struct zfcp_fsf_req *req)
{
	data->fsf_status = req->qtcb->header.fsf_status;
	memcpy(&data->fsf_status_qual, &req->qtcb->header.fsf_status_qual,
	       sizeof(union fsf_status_qual));
	memcpy(&data->payloads, &req->qtcb->bottom.support.els,
	       sizeof(req->qtcb->bottom.support.els));
}

static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
				unsigned long arg)
{
	struct zfcp_cfdc_data *data;
	struct zfcp_cfdc_data __user *data_user;
	struct zfcp_adapter *adapter;
	struct zfcp_fsf_req *req;
	struct zfcp_fsf_cfdc *fsf_cfdc;
	int retval;

	if (command != ZFCP_CFDC_IOC)
		return -ENOTTY;

	if (is_compat_task())
		data_user = compat_ptr(arg);
	else
		data_user = (void __user *)arg;

	if (!data_user)
		return -EINVAL;

	fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL);
	if (!fsf_cfdc)
		return -ENOMEM;

	data = memdup_user(data_user, sizeof(*data_user));
	if (IS_ERR(data)) {
		retval = PTR_ERR(data);
		goto no_mem_sense;
	}

	if (data->signature != 0xCFDCACDF) {
		retval = -EINVAL;
		goto free_buffer;
	}

	retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command);

	adapter = zfcp_cfdc_get_adapter(data->devno);
	if (!adapter) {
		retval = -ENXIO;
		goto free_buffer;
	}

	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
				    data_user->control_file);
	if (retval)
		goto adapter_put;
	req = zfcp_fsf_control_file(adapter, fsf_cfdc);
	if (IS_ERR(req)) {
		retval = PTR_ERR(req);
		goto free_sg;
	}

	if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		retval = -ENXIO;
		goto free_fsf;
	}

	zfcp_cfdc_req_to_sense(data, req);
	retval = copy_to_user(data_user, data, sizeof(*data_user));
	if (retval) {
		retval = -EFAULT;
		goto free_fsf;
	}

	if (data->command & ZFCP_CFDC_UPLOAD)
		retval = zfcp_cfdc_copy_to_user(&data_user->control_file,
						fsf_cfdc->sg);

 free_fsf:
	zfcp_fsf_req_free(req);
 free_sg:
	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
 adapter_put:
	zfcp_ccw_adapter_put(adapter);
 free_buffer:
	kfree(data);
 no_mem_sense:
	kfree(fsf_cfdc);
	return retval;
}

static const struct file_operations zfcp_cfdc_fops = {
	.open = nonseekable_open,
	.unlocked_ioctl = zfcp_cfdc_dev_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = zfcp_cfdc_dev_ioctl,
#endif
	.llseek = no_llseek,
};

struct miscdevice zfcp_cfdc_misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "zfcp_cfdc",
	.fops = &zfcp_cfdc_fops,
};

/**
 * zfcp_cfdc_adapter_access_changed - Process change in adapter ACT
 * @adapter: Adapter where the Access Control Table (ACT) changed
 *
 * After a change in the adapter ACT, check if access to any
 * previously denied resources is now possible.
 */
void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
{
	unsigned long flags;
	struct zfcp_port *port;
	struct scsi_device *sdev;
	struct zfcp_scsi_dev *zfcp_sdev;
	int status;

	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
		return;

	read_lock_irqsave(&adapter->port_list_lock, flags);
	list_for_each_entry(port, &adapter->port_list, list) {
		status = atomic_read(&port->status);
		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
		    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
			zfcp_erp_port_reopen(port,
					     ZFCP_STATUS_COMMON_ERP_FAILED,
					     "cfaac_1", NULL);
	}
	read_unlock_irqrestore(&adapter->port_list_lock, flags);

	shost_for_each_device(sdev, port->adapter->scsi_host) {
		zfcp_sdev = sdev_to_zfcp(sdev);
		status = atomic_read(&zfcp_sdev->status);
		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
		    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
			zfcp_erp_lun_reopen(sdev,
					    ZFCP_STATUS_COMMON_ERP_FAILED,
					    "cfaac_2", NULL);
	}
}

static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table)
{
	u16 subtable = table >> 16;
	u16 rule = table & 0xffff;
	const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" };

	if (subtable && subtable < ARRAY_SIZE(act_type))
		dev_warn(&adapter->ccw_device->dev,
			 "Access denied according to ACT rule type %s, "
			 "rule %d\n", act_type[subtable], rule);
}

/**
 * zfcp_cfdc_port_denied - Process "access denied" for port
 * @port: The port where the acces has been denied
 * @qual: The FSF status qualifier for the access denied FSF status
 */
void zfcp_cfdc_port_denied(struct zfcp_port *port,
			   union fsf_status_qual *qual)
{
	dev_warn(&port->adapter->ccw_device->dev,
		 "Access denied to port 0x%016Lx\n",
		 (unsigned long long)port->wwpn);

	zfcp_act_eval_err(port->adapter, qual->halfword[0]);
	zfcp_act_eval_err(port->adapter, qual->halfword[1]);
	zfcp_erp_set_port_status(port,
				 ZFCP_STATUS_COMMON_ERP_FAILED |
				 ZFCP_STATUS_COMMON_ACCESS_DENIED);
}

/**
 * zfcp_cfdc_lun_denied - Process "access denied" for LUN
 * @sdev: The SCSI device / LUN where the access has been denied
 * @qual: The FSF status qualifier for the access denied FSF status
 */
void zfcp_cfdc_lun_denied(struct scsi_device *sdev,
			  union fsf_status_qual *qual)
{
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);

	dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
		 "Access denied to LUN 0x%016Lx on port 0x%016Lx\n",
		 zfcp_scsi_dev_lun(sdev),
		 (unsigned long long)zfcp_sdev->port->wwpn);
	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]);
	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]);
	zfcp_erp_set_lun_status(sdev,
				ZFCP_STATUS_COMMON_ERP_FAILED |
				ZFCP_STATUS_COMMON_ACCESS_DENIED);

	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
}

/**
 * zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status
 * @sdev: The LUN / SCSI device where sharing violation occurred
 * @qual: The FSF status qualifier from the LUN sharing violation
 */
void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev,
			      union fsf_status_qual *qual)
{
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);

	if (qual->word[0])
		dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
			 "LUN 0x%Lx on port 0x%Lx is already in "
			 "use by CSS%d, MIF Image ID %x\n",
			 zfcp_scsi_dev_lun(sdev),
			 (unsigned long long)zfcp_sdev->port->wwpn,
			 qual->fsf_queue_designator.cssid,
			 qual->fsf_queue_designator.hla);
	else
		zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]);

	zfcp_erp_set_lun_status(sdev,
				ZFCP_STATUS_COMMON_ERP_FAILED |
				ZFCP_STATUS_COMMON_ACCESS_DENIED);
	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
}

/**
 * zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun"
 * @sdev: The SCSI device / LUN where to evaluate the status
 * @bottom: The qtcb bottom with the status from the "open lun"
 *
 * Returns: 0 if LUN is usable, -EACCES if the access control table
 *          reports an unsupported configuration.
 */
int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
			    struct fsf_qtcb_bottom_support *bottom)
{
	int shared, rw;
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;

	if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) ||
	    !(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) ||
	    zfcp_ccw_priv_sch(adapter))
		return 0;

	shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE);
	rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);

	if (shared)
		atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);

	if (!rw) {
		atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
		dev_info(&adapter->ccw_device->dev, "SCSI device at LUN "
			 "0x%016Lx on port 0x%016Lx opened read-only\n",
			 zfcp_scsi_dev_lun(sdev),
			 (unsigned long long)zfcp_sdev->port->wwpn);
	}

	if (!shared && !rw) {
		dev_err(&adapter->ccw_device->dev, "Exclusive read-only access "
			"not supported (LUN 0x%016Lx, port 0x%016Lx)\n",
			zfcp_scsi_dev_lun(sdev),
			(unsigned long long)zfcp_sdev->port->wwpn);
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
		zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL);
		return -EACCES;
	}

	if (shared && rw) {
		dev_err(&adapter->ccw_device->dev,
			"Shared read-write access not supported "
			"(LUN 0x%016Lx, port 0x%016Lx)\n",
			zfcp_scsi_dev_lun(sdev),
			(unsigned long long)zfcp_sdev->port->wwpn);
		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
		zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL);
		return -EACCES;
	}

	return 0;
}
