#include <linux/libata.h>
#include <linux/cdrom.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
#include <linux/pm_qos.h>
#include <scsi/scsi_device.h>

#include "libata.h"

static int zpodd_poweroff_delay = 30; /* 30 seconds for power off delay */
module_param(zpodd_poweroff_delay, int, 0644);
MODULE_PARM_DESC(zpodd_poweroff_delay, "Poweroff delay for ZPODD in seconds");

enum odd_mech_type {
	ODD_MECH_TYPE_SLOT,
	ODD_MECH_TYPE_DRAWER,
	ODD_MECH_TYPE_UNSUPPORTED,
};

struct zpodd {
	enum odd_mech_type	mech_type; /* init during probe, RO afterwards */
	struct ata_device	*dev;

	/* The following fields are synchronized by PM core. */
	bool			from_notify; /* resumed as a result of
					      * acpi wake notification */
	bool			zp_ready; /* ZP ready state */
	unsigned long		last_ready; /* last ZP ready timestamp */
	bool			zp_sampled; /* ZP ready state sampled */
	bool			powered_off; /* ODD is powered off
					      *	during suspend */
};

static int eject_tray(struct ata_device *dev)
{
	struct ata_taskfile tf;
	const char cdb[] = {  GPCMD_START_STOP_UNIT,
		0, 0, 0,
		0x02,     /* LoEj */
		0, 0, 0, 0, 0, 0, 0,
	};

	ata_tf_init(dev, &tf);
	tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
	tf.command = ATA_CMD_PACKET;
	tf.protocol = ATAPI_PROT_NODATA;

	return ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0);
}

/* Per the spec, only slot type and drawer type ODD can be supported */
static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev)
{
	char buf[16];
	unsigned int ret;
	struct rm_feature_desc *desc = (void *)(buf + 8);
	struct ata_taskfile tf;
	char cdb[] = {  GPCMD_GET_CONFIGURATION,
			2,      /* only 1 feature descriptor requested */
			0, 3,   /* 3, removable medium feature */
			0, 0, 0,/* reserved */
			0, sizeof(buf),
			0, 0, 0,
	};

	ata_tf_init(dev, &tf);
	tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
	tf.command = ATA_CMD_PACKET;
	tf.protocol = ATAPI_PROT_PIO;
	tf.lbam = sizeof(buf);

	ret = ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
				buf, sizeof(buf), 0);
	if (ret)
		return ODD_MECH_TYPE_UNSUPPORTED;

	if (be16_to_cpu(desc->feature_code) != 3)
		return ODD_MECH_TYPE_UNSUPPORTED;

	if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1)
		return ODD_MECH_TYPE_SLOT;
	else if (desc->mech_type == 1 && desc->load == 0 && desc->eject == 1)
		return ODD_MECH_TYPE_DRAWER;
	else
		return ODD_MECH_TYPE_UNSUPPORTED;
}

/* Test if ODD is zero power ready by sense code */
static bool zpready(struct ata_device *dev)
{
	u8 sense_key, *sense_buf;
	unsigned int ret, asc, ascq, add_len;
	struct zpodd *zpodd = dev->zpodd;

	ret = atapi_eh_tur(dev, &sense_key);

	if (!ret || sense_key != NOT_READY)
		return false;

	sense_buf = dev->link->ap->sector_buf;
	ret = atapi_eh_request_sense(dev, sense_buf, sense_key);
	if (ret)
		return false;

	/* sense valid */
	if ((sense_buf[0] & 0x7f) != 0x70)
		return false;

	add_len = sense_buf[7];
	/* has asc and ascq */
	if (add_len < 6)
		return false;

	asc = sense_buf[12];
	ascq = sense_buf[13];

	if (zpodd->mech_type == ODD_MECH_TYPE_SLOT)
		/* no media inside */
		return asc == 0x3a;
	else
		/* no media inside and door closed */
		return asc == 0x3a && ascq == 0x01;
}

/*
 * Update the zpodd->zp_ready field. This field will only be set
 * if the ODD has stayed in ZP ready state for zpodd_poweroff_delay
 * time, and will be used to decide if power off is allowed. If it
 * is set, it will be cleared during resume from powered off state.
 */
void zpodd_on_suspend(struct ata_device *dev)
{
	struct zpodd *zpodd = dev->zpodd;
	unsigned long expires;

	if (!zpready(dev)) {
		zpodd->zp_sampled = false;
		zpodd->zp_ready = false;
		return;
	}

	if (!zpodd->zp_sampled) {
		zpodd->zp_sampled = true;
		zpodd->last_ready = jiffies;
		return;
	}

	expires = zpodd->last_ready +
		  msecs_to_jiffies(zpodd_poweroff_delay * 1000);
	if (time_before(jiffies, expires))
		return;

	zpodd->zp_ready = true;
}

bool zpodd_zpready(struct ata_device *dev)
{
	struct zpodd *zpodd = dev->zpodd;
	return zpodd->zp_ready;
}

/*
 * Enable runtime wake capability through ACPI and set the powered_off flag,
 * this flag will be used during resume to decide what operations are needed
 * to take.
 *
 * Also, media poll needs to be silenced, so that it doesn't bring the ODD
 * back to full power state every few seconds.
 */
void zpodd_enable_run_wake(struct ata_device *dev)
{
	struct zpodd *zpodd = dev->zpodd;

	sdev_disable_disk_events(dev->sdev);

	zpodd->powered_off = true;
	device_set_run_wake(&dev->tdev, true);
	acpi_pm_device_run_wake(&dev->tdev, true);
}

/* Disable runtime wake capability if it is enabled */
void zpodd_disable_run_wake(struct ata_device *dev)
{
	struct zpodd *zpodd = dev->zpodd;

	if (zpodd->powered_off) {
		acpi_pm_device_run_wake(&dev->tdev, false);
		device_set_run_wake(&dev->tdev, false);
	}
}

/*
 * Post power on processing after the ODD has been recovered. If the
 * ODD wasn't powered off during suspend, it doesn't do anything.
 *
 * For drawer type ODD, if it is powered on due to user pressed the
 * eject button, the tray needs to be ejected. This can only be done
 * after the ODD has been recovered, i.e. link is initialized and
 * device is able to process NON_DATA PIO command, as eject needs to
 * send command for the ODD to process.
 *
 * The from_notify flag set in wake notification handler function
 * zpodd_wake_dev represents if power on is due to user's action.
 *
 * For both types of ODD, several fields need to be reset.
 */
void zpodd_post_poweron(struct ata_device *dev)
{
	struct zpodd *zpodd = dev->zpodd;

	if (!zpodd->powered_off)
		return;

	zpodd->powered_off = false;

	if (zpodd->from_notify) {
		zpodd->from_notify = false;
		if (zpodd->mech_type == ODD_MECH_TYPE_DRAWER)
			eject_tray(dev);
	}

	zpodd->zp_sampled = false;
	zpodd->zp_ready = false;

	sdev_enable_disk_events(dev->sdev);
}

static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context)
{
	struct ata_device *ata_dev = context;
	struct zpodd *zpodd = ata_dev->zpodd;
	struct device *dev = &ata_dev->sdev->sdev_gendev;

	if (event == ACPI_NOTIFY_DEVICE_WAKE && pm_runtime_suspended(dev)) {
		zpodd->from_notify = true;
		pm_runtime_resume(dev);
	}
}

static void ata_acpi_add_pm_notifier(struct ata_device *dev)
{
	acpi_handle handle = ata_dev_acpi_handle(dev);
	acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
				    zpodd_wake_dev, dev);
}

static void ata_acpi_remove_pm_notifier(struct ata_device *dev)
{
	acpi_handle handle = ata_dev_acpi_handle(dev);
	acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, zpodd_wake_dev);
}

void zpodd_init(struct ata_device *dev)
{
	struct acpi_device *adev = ACPI_COMPANION(&dev->tdev);
	enum odd_mech_type mech_type;
	struct zpodd *zpodd;

	if (dev->zpodd || !adev || !acpi_device_can_poweroff(adev))
		return;

	mech_type = zpodd_get_mech_type(dev);
	if (mech_type == ODD_MECH_TYPE_UNSUPPORTED)
		return;

	zpodd = kzalloc(sizeof(struct zpodd), GFP_KERNEL);
	if (!zpodd)
		return;

	zpodd->mech_type = mech_type;

	ata_acpi_add_pm_notifier(dev);
	zpodd->dev = dev;
	dev->zpodd = zpodd;
	dev_pm_qos_expose_flags(&dev->tdev, 0);
}

void zpodd_exit(struct ata_device *dev)
{
	ata_acpi_remove_pm_notifier(dev);
	kfree(dev->zpodd);
	dev->zpodd = NULL;
}
