/*
 * Aic94xx SAS/SATA Tasks
 *
 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
 *
 * This file is licensed under GPLv2.
 *
 * This file is part of the aic94xx driver.
 *
 * The aic94xx driver 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; version 2 of the
 * License.
 *
 * The aic94xx driver 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with the aic94xx driver; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <linux/spinlock.h>
#include "aic94xx.h"
#include "aic94xx_sas.h"
#include "aic94xx_hwi.h"

static void asd_unbuild_ata_ascb(struct asd_ascb *a);
static void asd_unbuild_smp_ascb(struct asd_ascb *a);
static void asd_unbuild_ssp_ascb(struct asd_ascb *a);

static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
{
	unsigned long flags;

	spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
	asd_ha->seq.can_queue += num;
	spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
}

/* PCI_DMA_... to our direction translation.
 */
static const u8 data_dir_flags[] = {
	[PCI_DMA_BIDIRECTIONAL] = DATA_DIR_BYRECIPIENT,	/* UNSPECIFIED */
	[PCI_DMA_TODEVICE]      = DATA_DIR_OUT, /* OUTBOUND */
	[PCI_DMA_FROMDEVICE]    = DATA_DIR_IN, /* INBOUND */
	[PCI_DMA_NONE]          = DATA_DIR_NONE, /* NO TRANSFER */
};

static inline int asd_map_scatterlist(struct sas_task *task,
				      struct sg_el *sg_arr,
				      unsigned long gfp_flags)
{
	struct asd_ascb *ascb = task->lldd_task;
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct scatterlist *sc;
	int num_sg, res;

	if (task->data_dir == PCI_DMA_NONE)
		return 0;

	if (task->num_scatter == 0) {
		void *p = task->scatter;
		dma_addr_t dma = pci_map_single(asd_ha->pcidev, p,
						task->total_xfer_len,
						task->data_dir);
		sg_arr[0].bus_addr = cpu_to_le64((u64)dma);
		sg_arr[0].size = cpu_to_le32(task->total_xfer_len);
		sg_arr[0].flags |= ASD_SG_EL_LIST_EOL;
		return 0;
	}

	num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
			    task->data_dir);
	if (num_sg == 0)
		return -ENOMEM;

	if (num_sg > 3) {
		int i;

		ascb->sg_arr = asd_alloc_coherent(asd_ha,
						  num_sg*sizeof(struct sg_el),
						  gfp_flags);
		if (!ascb->sg_arr) {
			res = -ENOMEM;
			goto err_unmap;
		}
		for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
			struct sg_el *sg =
				&((struct sg_el *)ascb->sg_arr->vaddr)[i];
			sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
			sg->size = cpu_to_le32((u32)sg_dma_len(sc));
			if (i == num_sg-1)
				sg->flags |= ASD_SG_EL_LIST_EOL;
		}

		for (sc = task->scatter, i = 0; i < 2; i++, sc++) {
			sg_arr[i].bus_addr =
				cpu_to_le64((u64)sg_dma_address(sc));
			sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
		}
		sg_arr[1].next_sg_offs = 2 * sizeof(*sg_arr);
		sg_arr[1].flags |= ASD_SG_EL_LIST_EOS;

		memset(&sg_arr[2], 0, sizeof(*sg_arr));
		sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
	} else {
		int i;
		for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
			sg_arr[i].bus_addr =
				cpu_to_le64((u64)sg_dma_address(sc));
			sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
		}
		sg_arr[i-1].flags |= ASD_SG_EL_LIST_EOL;
	}

	return 0;
err_unmap:
	pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
		     task->data_dir);
	return res;
}

static inline void asd_unmap_scatterlist(struct asd_ascb *ascb)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_task *task = ascb->uldd_task;

	if (task->data_dir == PCI_DMA_NONE)
		return;

	if (task->num_scatter == 0) {
		dma_addr_t dma = (dma_addr_t)
		       le64_to_cpu(ascb->scb->ssp_task.sg_element[0].bus_addr);
		pci_unmap_single(ascb->ha->pcidev, dma, task->total_xfer_len,
				 task->data_dir);
		return;
	}

	asd_free_coherent(asd_ha, ascb->sg_arr);
	pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
		     task->data_dir);
}

/* ---------- Task complete tasklet ---------- */

static void asd_get_response_tasklet(struct asd_ascb *ascb,
				     struct done_list_struct *dl)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_task *task = ascb->uldd_task;
	struct task_status_struct *ts = &task->task_status;
	unsigned long flags;
	struct tc_resp_sb_struct {
		__le16 index_escb;
		u8     len_lsb;
		u8     flags;
	} __attribute__ ((packed)) *resp_sb = (void *) dl->status_block;

/* 	int  size   = ((resp_sb->flags & 7) << 8) | resp_sb->len_lsb; */
	int  edb_id = ((resp_sb->flags & 0x70) >> 4)-1;
	struct asd_ascb *escb;
	struct asd_dma_tok *edb;
	void *r;

	spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags);
	escb = asd_tc_index_find(&asd_ha->seq,
				 (int)le16_to_cpu(resp_sb->index_escb));
	spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags);

	if (!escb) {
		ASD_DPRINTK("Uh-oh! No escb for this dl?!\n");
		return;
	}

	ts->buf_valid_size = 0;
	edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index];
	r = edb->vaddr;
	if (task->task_proto == SAS_PROTO_SSP) {
		struct ssp_response_iu *iu =
			r + 16 + sizeof(struct ssp_frame_hdr);

		ts->residual = le32_to_cpu(*(__le32 *)r);
		ts->resp = SAS_TASK_COMPLETE;
		if (iu->datapres == 0)
			ts->stat = iu->status;
		else if (iu->datapres == 1)
			ts->stat = iu->resp_data[3];
		else if (iu->datapres == 2) {
			ts->stat = SAM_CHECK_COND;
			ts->buf_valid_size = min((u32) SAS_STATUS_BUF_SIZE,
					 be32_to_cpu(iu->sense_data_len));
			memcpy(ts->buf, iu->sense_data, ts->buf_valid_size);
			if (iu->status != SAM_CHECK_COND) {
				ASD_DPRINTK("device %llx sent sense data, but "
					    "stat(0x%x) is not CHECK_CONDITION"
					    "\n",
					    SAS_ADDR(task->dev->sas_addr),
					    ts->stat);
			}
		}
	}  else {
		struct ata_task_resp *resp = (void *) &ts->buf[0];

		ts->residual = le32_to_cpu(*(__le32 *)r);

		if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
			resp->frame_len = le16_to_cpu(*(__le16 *)(r+6));
			memcpy(&resp->ending_fis[0], r+16, 24);
			ts->buf_valid_size = sizeof(*resp);
		}
	}

	asd_invalidate_edb(escb, edb_id);
}

static void asd_task_tasklet_complete(struct asd_ascb *ascb,
				      struct done_list_struct *dl)
{
	struct sas_task *task = ascb->uldd_task;
	struct task_status_struct *ts = &task->task_status;
	unsigned long flags;
	u8 opcode = dl->opcode;

	asd_can_dequeue(ascb->ha, 1);

Again:
	switch (opcode) {
	case TC_NO_ERROR:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAM_GOOD;
		break;
	case TC_UNDERRUN:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_DATA_UNDERRUN;
		ts->residual = le32_to_cpu(*(__le32 *)dl->status_block);
		break;
	case TC_OVERRUN:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_DATA_OVERRUN;
		ts->residual = 0;
		break;
	case TC_SSP_RESP:
	case TC_ATA_RESP:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_PROTO_RESPONSE;
		asd_get_response_tasklet(ascb, dl);
		break;
	case TF_OPEN_REJECT:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_OPEN_REJECT;
		if (dl->status_block[1] & 2)
			ts->open_rej_reason = 1 + dl->status_block[2];
		else if (dl->status_block[1] & 1)
			ts->open_rej_reason = (dl->status_block[2] >> 4)+10;
		else
			ts->open_rej_reason = SAS_OREJ_UNKNOWN;
		break;
	case TF_OPEN_TO:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_OPEN_TO;
		break;
	case TF_PHY_DOWN:
	case TU_PHY_DOWN:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_PHY_DOWN;
		break;
	case TI_PHY_DOWN:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_PHY_DOWN;
		break;
	case TI_BREAK:
	case TI_PROTO_ERR:
	case TI_NAK:
	case TI_ACK_NAK_TO:
	case TF_SMP_XMIT_RCV_ERR:
	case TC_ATA_R_ERR_RECV:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_INTERRUPTED;
		break;
	case TF_BREAK:
	case TU_BREAK:
	case TU_ACK_NAK_TO:
	case TF_SMPRSP_TO:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_DEV_NO_RESPONSE;
		break;
	case TF_NAK_RECV:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_NAK_R_ERR;
		break;
	case TA_I_T_NEXUS_LOSS:
		opcode = dl->status_block[0];
		goto Again;
		break;
	case TF_INV_CONN_HANDLE:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_DEVICE_UNKNOWN;
		break;
	case TF_REQUESTED_N_PENDING:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_PENDING;
		break;
	case TC_TASK_CLEARED:
	case TA_ON_REQ:
		ts->resp = SAS_TASK_COMPLETE;
		ts->stat = SAS_ABORTED_TASK;
		break;

	case TF_NO_SMP_CONN:
	case TF_TMF_NO_CTX:
	case TF_TMF_NO_TAG:
	case TF_TMF_TAG_FREE:
	case TF_TMF_TASK_DONE:
	case TF_TMF_NO_CONN_HANDLE:
	case TF_IRTT_TO:
	case TF_IU_SHORT:
	case TF_DATA_OFFS_ERR:
		ts->resp = SAS_TASK_UNDELIVERED;
		ts->stat = SAS_DEV_NO_RESPONSE;
		break;

	case TC_LINK_ADM_RESP:
	case TC_CONTROL_PHY:
	case TC_RESUME:
	case TC_PARTIAL_SG_LIST:
	default:
		ASD_DPRINTK("%s: dl opcode: 0x%x?\n", __FUNCTION__, opcode);
		break;
	}

	switch (task->task_proto) {
	case SATA_PROTO:
	case SAS_PROTO_STP:
		asd_unbuild_ata_ascb(ascb);
		break;
	case SAS_PROTO_SMP:
		asd_unbuild_smp_ascb(ascb);
		break;
	case SAS_PROTO_SSP:
		asd_unbuild_ssp_ascb(ascb);
	default:
		break;
	}

	spin_lock_irqsave(&task->task_state_lock, flags);
	task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
	task->task_state_flags |= SAS_TASK_STATE_DONE;
	if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
		spin_unlock_irqrestore(&task->task_state_lock, flags);
		ASD_DPRINTK("task 0x%p done with opcode 0x%x resp 0x%x "
			    "stat 0x%x but aborted by upper layer!\n",
			    task, opcode, ts->resp, ts->stat);
		complete(&ascb->completion);
	} else {
		spin_unlock_irqrestore(&task->task_state_lock, flags);
		task->lldd_task = NULL;
		asd_ascb_free(ascb);
		mb();
		task->task_done(task);
	}
}

/* ---------- ATA ---------- */

static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
			      unsigned long gfp_flags)
{
	struct domain_device *dev = task->dev;
	struct scb *scb;
	u8     flags;
	int    res = 0;

	scb = ascb->scb;

	if (unlikely(task->ata_task.device_control_reg_update))
		scb->header.opcode = CONTROL_ATA_DEV;
	else if (dev->sata_dev.command_set == ATA_COMMAND_SET)
		scb->header.opcode = INITIATE_ATA_TASK;
	else
		scb->header.opcode = INITIATE_ATAPI_TASK;

	scb->ata_task.proto_conn_rate = (1 << 5); /* STP */
	if (dev->port->oob_mode == SAS_OOB_MODE)
		scb->ata_task.proto_conn_rate |= dev->linkrate;

	scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
	scb->ata_task.fis = task->ata_task.fis;
	scb->ata_task.fis.fis_type = 0x27;
	if (likely(!task->ata_task.device_control_reg_update))
		scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
	scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */
	if (dev->sata_dev.command_set == ATAPI_COMMAND_SET)
		memcpy(scb->ata_task.atapi_packet, task->ata_task.atapi_packet,
		       16);
	scb->ata_task.sister_scb = cpu_to_le16(0xFFFF);
	scb->ata_task.conn_handle = cpu_to_le16(
		(u16)(unsigned long)dev->lldd_dev);

	if (likely(!task->ata_task.device_control_reg_update)) {
		flags = 0;
		if (task->ata_task.dma_xfer)
			flags |= DATA_XFER_MODE_DMA;
		if (task->ata_task.use_ncq &&
		    dev->sata_dev.command_set != ATAPI_COMMAND_SET)
			flags |= ATA_Q_TYPE_NCQ;
		flags |= data_dir_flags[task->data_dir];
		scb->ata_task.ata_flags = flags;

		scb->ata_task.retry_count = task->ata_task.retry_count;

		flags = 0;
		if (task->ata_task.set_affil_pol)
			flags |= SET_AFFIL_POLICY;
		if (task->ata_task.stp_affil_pol)
			flags |= STP_AFFIL_POLICY;
		scb->ata_task.flags = flags;
	}
	ascb->tasklet_complete = asd_task_tasklet_complete;

	if (likely(!task->ata_task.device_control_reg_update))
		res = asd_map_scatterlist(task, scb->ata_task.sg_element,
					  gfp_flags);

	return res;
}

static void asd_unbuild_ata_ascb(struct asd_ascb *a)
{
	asd_unmap_scatterlist(a);
}

/* ---------- SMP ---------- */

static int asd_build_smp_ascb(struct asd_ascb *ascb, struct sas_task *task,
			      unsigned long gfp_flags)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct domain_device *dev = task->dev;
	struct scb *scb;

	pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_req, 1,
		   PCI_DMA_FROMDEVICE);
	pci_map_sg(asd_ha->pcidev, &task->smp_task.smp_resp, 1,
		   PCI_DMA_FROMDEVICE);

	scb = ascb->scb;

	scb->header.opcode = INITIATE_SMP_TASK;

	scb->smp_task.proto_conn_rate = dev->linkrate;

	scb->smp_task.smp_req.bus_addr =
		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
	scb->smp_task.smp_req.size =
		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4);

	scb->smp_task.smp_resp.bus_addr =
		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_resp));
	scb->smp_task.smp_resp.size =
		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);

	scb->smp_task.sister_scb = cpu_to_le16(0xFFFF);
	scb->smp_task.conn_handle = cpu_to_le16((u16)
						(unsigned long)dev->lldd_dev);

	ascb->tasklet_complete = asd_task_tasklet_complete;

	return 0;
}

static void asd_unbuild_smp_ascb(struct asd_ascb *a)
{
	struct sas_task *task = a->uldd_task;

	BUG_ON(!task);
	pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_req, 1,
		     PCI_DMA_FROMDEVICE);
	pci_unmap_sg(a->ha->pcidev, &task->smp_task.smp_resp, 1,
		     PCI_DMA_FROMDEVICE);
}

/* ---------- SSP ---------- */

static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task,
			      unsigned long gfp_flags)
{
	struct domain_device *dev = task->dev;
	struct scb *scb;
	int    res = 0;

	scb = ascb->scb;

	scb->header.opcode = INITIATE_SSP_TASK;

	scb->ssp_task.proto_conn_rate  = (1 << 4); /* SSP */
	scb->ssp_task.proto_conn_rate |= dev->linkrate;
	scb->ssp_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
	scb->ssp_task.ssp_frame.frame_type = SSP_DATA;
	memcpy(scb->ssp_task.ssp_frame.hashed_dest_addr, dev->hashed_sas_addr,
	       HASHED_SAS_ADDR_SIZE);
	memcpy(scb->ssp_task.ssp_frame.hashed_src_addr,
	       dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
	scb->ssp_task.ssp_frame.tptt = cpu_to_be16(0xFFFF);

	memcpy(scb->ssp_task.ssp_cmd.lun, task->ssp_task.LUN, 8);
	if (task->ssp_task.enable_first_burst)
		scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK;
	scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3);
	scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7);
	memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16);

	scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF);
	scb->ssp_task.conn_handle = cpu_to_le16(
		(u16)(unsigned long)dev->lldd_dev);
	scb->ssp_task.data_dir = data_dir_flags[task->data_dir];
	scb->ssp_task.retry_count = scb->ssp_task.retry_count;

	ascb->tasklet_complete = asd_task_tasklet_complete;

	res = asd_map_scatterlist(task, scb->ssp_task.sg_element, gfp_flags);

	return res;
}

static void asd_unbuild_ssp_ascb(struct asd_ascb *a)
{
	asd_unmap_scatterlist(a);
}

/* ---------- Execute Task ---------- */

static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
{
	int res = 0;
	unsigned long flags;

	spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
	if ((asd_ha->seq.can_queue - num) < 0)
		res = -SAS_QUEUE_FULL;
	else
		asd_ha->seq.can_queue -= num;
	spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);

	return res;
}

int asd_execute_task(struct sas_task *task, const int num,
		     unsigned long gfp_flags)
{
	int res = 0;
	LIST_HEAD(alist);
	struct sas_task *t = task;
	struct asd_ascb *ascb = NULL, *a;
	struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;

	res = asd_can_queue(asd_ha, num);
	if (res)
		return res;

	res = num;
	ascb = asd_ascb_alloc_list(asd_ha, &res, gfp_flags);
	if (res) {
		res = -ENOMEM;
		goto out_err;
	}

	__list_add(&alist, ascb->list.prev, &ascb->list);
	list_for_each_entry(a, &alist, list) {
		a->uldd_task = t;
		t->lldd_task = a;
		t = list_entry(t->list.next, struct sas_task, list);
	}
	list_for_each_entry(a, &alist, list) {
		t = a->uldd_task;
		a->uldd_timer = 1;
		if (t->task_proto & SAS_PROTO_STP)
			t->task_proto = SAS_PROTO_STP;
		switch (t->task_proto) {
		case SATA_PROTO:
		case SAS_PROTO_STP:
			res = asd_build_ata_ascb(a, t, gfp_flags);
			break;
		case SAS_PROTO_SMP:
			res = asd_build_smp_ascb(a, t, gfp_flags);
			break;
		case SAS_PROTO_SSP:
			res = asd_build_ssp_ascb(a, t, gfp_flags);
			break;
		default:
			asd_printk("unknown sas_task proto: 0x%x\n",
				   t->task_proto);
			res = -ENOMEM;
			break;
		}
		if (res)
			goto out_err_unmap;
	}
	list_del_init(&alist);

	res = asd_post_ascb_list(asd_ha, ascb, num);
	if (unlikely(res)) {
		a = NULL;
		__list_add(&alist, ascb->list.prev, &ascb->list);
		goto out_err_unmap;
	}

	return 0;
out_err_unmap:
	{
		struct asd_ascb *b = a;
		list_for_each_entry(a, &alist, list) {
			if (a == b)
				break;
			t = a->uldd_task;
			switch (t->task_proto) {
			case SATA_PROTO:
			case SAS_PROTO_STP:
				asd_unbuild_ata_ascb(a);
				break;
			case SAS_PROTO_SMP:
				asd_unbuild_smp_ascb(a);
				break;
			case SAS_PROTO_SSP:
				asd_unbuild_ssp_ascb(a);
			default:
				break;
			}
			t->lldd_task = NULL;
		}
	}
	list_del_init(&alist);
out_err:
	if (ascb)
		asd_ascb_free_list(ascb);
	asd_can_dequeue(asd_ha, num);
	return res;
}
