/*
 * This module provides common API to set Diagnostic trigger for MPT
 * (Message Passing Technology) based controllers
 *
 * This code is based on drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c
 * Copyright (C) 2012-2014  LSI Corporation
 * Copyright (C) 2013-2014 Avago Technologies
 *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * NO WARRANTY
 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
 * solely responsible for determining the appropriateness of using and
 * distributing the Program and assumes all risks associated with its
 * exercise of rights under this Agreement, including but not limited to
 * the risks and costs of program errors, damage to or loss of data,
 * programs or equipment, and unavailability or interruption of operations.

 * DISCLAIMER OF LIABILITY
 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/compat.h>
#include <linux/poll.h>

#include <linux/io.h>
#include <linux/uaccess.h>

#include "mpt3sas_base.h"

/**
 * _mpt3sas_raise_sigio - notifiy app
 * @ioc: per adapter object
 * @event_data: ?
 */
static void
_mpt3sas_raise_sigio(struct MPT3SAS_ADAPTER *ioc,
	struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data)
{
	Mpi2EventNotificationReply_t *mpi_reply;
	u16 sz, event_data_sz;
	unsigned long flags;

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n",
	    ioc->name, __func__));

	sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
	    sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4;
	mpi_reply = kzalloc(sz, GFP_KERNEL);
	if (!mpi_reply)
		goto out;
	mpi_reply->Event = cpu_to_le16(MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED);
	event_data_sz = (sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4) / 4;
	mpi_reply->EventDataLength = cpu_to_le16(event_data_sz);
	memcpy(&mpi_reply->EventData, event_data,
	    sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: add to driver event log\n",
		ioc->name, __func__));
	mpt3sas_ctl_add_to_event_log(ioc, mpi_reply);
	kfree(mpi_reply);
 out:

	/* clearing the diag_trigger_active flag */
	spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: clearing diag_trigger_active flag\n",
		ioc->name, __func__));
	ioc->diag_trigger_active = 0;
	spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
	    __func__));
}

/**
 * mpt3sas_process_trigger_data - process the event data for the trigger
 * @ioc: per adapter object
 * @event_data: ?
 */
void
mpt3sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc,
	struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data)
{
	u8 issue_reset = 0;

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n",
	    ioc->name, __func__));

	/* release the diag buffer trace */
	if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {
		dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: release trace diag buffer\n", ioc->name, __func__));
		mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,
		    &issue_reset);
	}

	_mpt3sas_raise_sigio(ioc, event_data);

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
	    __func__));
}

/**
 * mpt3sas_trigger_master - Master trigger handler
 * @ioc: per adapter object
 * @trigger_bitmask:
 *
 */
void
mpt3sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, u32 trigger_bitmask)
{
	struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
	unsigned long flags;
	u8 found_match = 0;

	spin_lock_irqsave(&ioc->diag_trigger_lock, flags);

	if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
	    trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET)
		goto by_pass_checks;

	/* check to see if trace buffers are currently registered */
	if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	/* check to see if trace buffers are currently released */
	if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_RELEASED) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

 by_pass_checks:

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: enter - trigger_bitmask = 0x%08x\n",
		ioc->name, __func__, trigger_bitmask));

	/* don't send trigger if an trigger is currently active */
	if (ioc->diag_trigger_active) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		goto out;
	}

	/* check for the trigger condition */
	if (ioc->diag_trigger_master.MasterData & trigger_bitmask) {
		found_match = 1;
		ioc->diag_trigger_active = 1;
		dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: setting diag_trigger_active flag\n",
		ioc->name, __func__));
	}
	spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);

	if (!found_match)
		goto out;

	memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
	event_data.trigger_type = MPT3SAS_TRIGGER_MASTER;
	event_data.u.master.MasterData = trigger_bitmask;

	if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
	    trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET)
		_mpt3sas_raise_sigio(ioc, &event_data);
	else
		mpt3sas_send_trigger_data_event(ioc, &event_data);

 out:
	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
	    __func__));
}

/**
 * mpt3sas_trigger_event - Event trigger handler
 * @ioc: per adapter object
 * @event: ?
 * @log_entry_qualifier: ?
 *
 */
void
mpt3sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event,
	u16 log_entry_qualifier)
{
	struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
	struct SL_WH_EVENT_TRIGGER_T *event_trigger;
	int i;
	unsigned long flags;
	u8 found_match;

	spin_lock_irqsave(&ioc->diag_trigger_lock, flags);

	/* check to see if trace buffers are currently registered */
	if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	/* check to see if trace buffers are currently released */
	if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_RELEASED) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: enter - event = 0x%04x, log_entry_qualifier = 0x%04x\n",
		ioc->name, __func__, event, log_entry_qualifier));

	/* don't send trigger if an trigger is currently active */
	if (ioc->diag_trigger_active) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		goto out;
	}

	/* check for the trigger condition */
	event_trigger = ioc->diag_trigger_event.EventTriggerEntry;
	for (i = 0 , found_match = 0; i < ioc->diag_trigger_event.ValidEntries
	    && !found_match; i++, event_trigger++) {
		if (event_trigger->EventValue != event)
			continue;
		if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
			if (event_trigger->LogEntryQualifier ==
			    log_entry_qualifier)
				found_match = 1;
			continue;
		}
		found_match = 1;
		ioc->diag_trigger_active = 1;
		dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
			"%s: setting diag_trigger_active flag\n",
			ioc->name, __func__));
	}
	spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);

	if (!found_match)
		goto out;

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: setting diag_trigger_active flag\n",
		ioc->name, __func__));
	memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
	event_data.trigger_type = MPT3SAS_TRIGGER_EVENT;
	event_data.u.event.EventValue = event;
	event_data.u.event.LogEntryQualifier = log_entry_qualifier;
	mpt3sas_send_trigger_data_event(ioc, &event_data);
 out:
	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
	    __func__));
}

/**
 * mpt3sas_trigger_scsi - SCSI trigger handler
 * @ioc: per adapter object
 * @sense_key: ?
 * @asc: ?
 * @ascq: ?
 *
 */
void
mpt3sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, u8 asc,
	u8 ascq)
{
	struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
	struct SL_WH_SCSI_TRIGGER_T *scsi_trigger;
	int i;
	unsigned long flags;
	u8 found_match;

	spin_lock_irqsave(&ioc->diag_trigger_lock, flags);

	/* check to see if trace buffers are currently registered */
	if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	/* check to see if trace buffers are currently released */
	if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_RELEASED) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: enter - sense_key = 0x%02x, asc = 0x%02x, ascq = 0x%02x\n",
		ioc->name, __func__, sense_key, asc, ascq));

	/* don't send trigger if an trigger is currently active */
	if (ioc->diag_trigger_active) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		goto out;
	}

	/* check for the trigger condition */
	scsi_trigger = ioc->diag_trigger_scsi.SCSITriggerEntry;
	for (i = 0 , found_match = 0; i < ioc->diag_trigger_scsi.ValidEntries
	    && !found_match; i++, scsi_trigger++) {
		if (scsi_trigger->SenseKey != sense_key)
			continue;
		if (!(scsi_trigger->ASC == 0xFF || scsi_trigger->ASC == asc))
			continue;
		if (!(scsi_trigger->ASCQ == 0xFF || scsi_trigger->ASCQ == ascq))
			continue;
		found_match = 1;
		ioc->diag_trigger_active = 1;
	}
	spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);

	if (!found_match)
		goto out;

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: setting diag_trigger_active flag\n",
		ioc->name, __func__));
	memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
	event_data.trigger_type = MPT3SAS_TRIGGER_SCSI;
	event_data.u.scsi.SenseKey = sense_key;
	event_data.u.scsi.ASC = asc;
	event_data.u.scsi.ASCQ = ascq;
	mpt3sas_send_trigger_data_event(ioc, &event_data);
 out:
	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
	    __func__));
}

/**
 * mpt3sas_trigger_mpi - MPI trigger handler
 * @ioc: per adapter object
 * @ioc_status: ?
 * @loginfo: ?
 *
 */
void
mpt3sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status, u32 loginfo)
{
	struct SL_WH_TRIGGERS_EVENT_DATA_T event_data;
	struct SL_WH_MPI_TRIGGER_T *mpi_trigger;
	int i;
	unsigned long flags;
	u8 found_match;

	spin_lock_irqsave(&ioc->diag_trigger_lock, flags);

	/* check to see if trace buffers are currently registered */
	if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	/* check to see if trace buffers are currently released */
	if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
	    MPT3_DIAG_BUFFER_IS_RELEASED) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		return;
	}

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: enter - ioc_status = 0x%04x, loginfo = 0x%08x\n",
		ioc->name, __func__, ioc_status, loginfo));

	/* don't send trigger if an trigger is currently active */
	if (ioc->diag_trigger_active) {
		spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
		goto out;
	}

	/* check for the trigger condition */
	mpi_trigger = ioc->diag_trigger_mpi.MPITriggerEntry;
	for (i = 0 , found_match = 0; i < ioc->diag_trigger_mpi.ValidEntries
	    && !found_match; i++, mpi_trigger++) {
		if (mpi_trigger->IOCStatus != ioc_status)
			continue;
		if (!(mpi_trigger->IocLogInfo == 0xFFFFFFFF ||
		    mpi_trigger->IocLogInfo == loginfo))
			continue;
		found_match = 1;
		ioc->diag_trigger_active = 1;
	}
	spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);

	if (!found_match)
		goto out;

	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT
		"%s: setting diag_trigger_active flag\n",
		ioc->name, __func__));
	memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
	event_data.trigger_type = MPT3SAS_TRIGGER_MPI;
	event_data.u.mpi.IOCStatus = ioc_status;
	event_data.u.mpi.IocLogInfo = loginfo;
	mpt3sas_send_trigger_data_event(ioc, &event_data);
 out:
	dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
	    __func__));
}
