/*
 * Aic94xx SAS/SATA driver SCB management.
 *
 * 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/pci.h>

#include "aic94xx.h"
#include "aic94xx_reg.h"
#include "aic94xx_hwi.h"
#include "aic94xx_seq.h"

#include "aic94xx_dump.h"

/* ---------- EMPTY SCB ---------- */

#define DL_PHY_MASK      7
#define BYTES_DMAED      0
#define PRIMITIVE_RECVD  0x08
#define PHY_EVENT        0x10
#define LINK_RESET_ERROR 0x18
#define TIMER_EVENT      0x20
#define REQ_TASK_ABORT   0xF0
#define REQ_DEVICE_RESET 0xF1
#define SIGNAL_NCQ_ERROR 0xF2
#define CLEAR_NCQ_ERROR  0xF3

#define PHY_EVENTS_STATUS (CURRENT_LOSS_OF_SIGNAL | CURRENT_OOB_DONE   \
			   | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
			   | CURRENT_OOB_ERROR)

static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
{
	struct sas_phy *sas_phy = phy->sas_phy.phy;

	switch (oob_mode & 7) {
	case PHY_SPEED_60:
		/* FIXME: sas transport class doesn't have this */
		phy->sas_phy.linkrate = SAS_LINK_RATE_6_0_GBPS;
		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
		break;
	case PHY_SPEED_30:
		phy->sas_phy.linkrate = SAS_LINK_RATE_3_0_GBPS;
		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
		break;
	case PHY_SPEED_15:
		phy->sas_phy.linkrate = SAS_LINK_RATE_1_5_GBPS;
		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
		break;
	}
	sas_phy->negotiated_linkrate = phy->sas_phy.linkrate;
	sas_phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
	sas_phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
	sas_phy->maximum_linkrate = phy->phy_desc->max_sas_lrate;
	sas_phy->minimum_linkrate = phy->phy_desc->min_sas_lrate;

	if (oob_mode & SAS_MODE)
		phy->sas_phy.oob_mode = SAS_OOB_MODE;
	else if (oob_mode & SATA_MODE)
		phy->sas_phy.oob_mode = SATA_OOB_MODE;
}

static inline void asd_phy_event_tasklet(struct asd_ascb *ascb,
					 struct done_list_struct *dl)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
	int phy_id = dl->status_block[0] & DL_PHY_MASK;
	struct asd_phy *phy = &asd_ha->phys[phy_id];

	u8 oob_status = dl->status_block[1] & PHY_EVENTS_STATUS;
	u8 oob_mode   = dl->status_block[2];

	switch (oob_status) {
	case CURRENT_LOSS_OF_SIGNAL:
		/* directly attached device was removed */
		ASD_DPRINTK("phy%d: device unplugged\n", phy_id);
		asd_turn_led(asd_ha, phy_id, 0);
		sas_phy_disconnected(&phy->sas_phy);
		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
		break;
	case CURRENT_OOB_DONE:
		/* hot plugged device */
		asd_turn_led(asd_ha, phy_id, 1);
		get_lrate_mode(phy, oob_mode);
		ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n",
			    phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto);
		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
		break;
	case CURRENT_SPINUP_HOLD:
		/* hot plug SATA, no COMWAKE sent */
		asd_turn_led(asd_ha, phy_id, 1);
		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
		break;
	case CURRENT_GTO_TIMEOUT:
	case CURRENT_OOB_ERROR:
		ASD_DPRINTK("phy%d error while OOB: oob status:0x%x\n", phy_id,
			    dl->status_block[1]);
		asd_turn_led(asd_ha, phy_id, 0);
		sas_phy_disconnected(&phy->sas_phy);
		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
		break;
	}
}

/* If phys are enabled sparsely, this will do the right thing. */
static inline unsigned ord_phy(struct asd_ha_struct *asd_ha,
			       struct asd_phy *phy)
{
	u8 enabled_mask = asd_ha->hw_prof.enabled_phys;
	int i, k = 0;

	for_each_phy(enabled_mask, enabled_mask, i) {
		if (&asd_ha->phys[i] == phy)
			return k;
		k++;
	}
	return 0;
}

/**
 * asd_get_attached_sas_addr -- extract/generate attached SAS address
 * phy: pointer to asd_phy
 * sas_addr: pointer to buffer where the SAS address is to be written
 *
 * This function extracts the SAS address from an IDENTIFY frame
 * received.  If OOB is SATA, then a SAS address is generated from the
 * HA tables.
 *
 * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
 * buffer.
 */
static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
{
	if (phy->sas_phy.frame_rcvd[0] == 0x34
	    && phy->sas_phy.oob_mode == SATA_OOB_MODE) {
		struct asd_ha_struct *asd_ha = phy->sas_phy.ha->lldd_ha;
		/* FIS device-to-host */
		u64 addr = be64_to_cpu(*(__be64 *)phy->phy_desc->sas_addr);

		addr += asd_ha->hw_prof.sata_name_base + ord_phy(asd_ha, phy);
		*(__be64 *)sas_addr = cpu_to_be64(addr);
	} else {
		struct sas_identify_frame *idframe =
			(void *) phy->sas_phy.frame_rcvd;
		memcpy(sas_addr, idframe->sas_addr, SAS_ADDR_SIZE);
	}
}

static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
					   struct done_list_struct *dl,
					   int edb_id, int phy_id)
{
	unsigned long flags;
	int edb_el = edb_id + ascb->edb_index;
	struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el];
	struct asd_phy *phy = &ascb->ha->phys[phy_id];
	struct sas_ha_struct *sas_ha = phy->sas_phy.ha;
	u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2];

	size = min(size, (u16) sizeof(phy->frame_rcvd));

	spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
	memcpy(phy->sas_phy.frame_rcvd, edb->vaddr, size);
	phy->sas_phy.frame_rcvd_size = size;
	asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
	asd_dump_frame_rcvd(phy, dl);
	sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
}

static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
					      struct done_list_struct *dl,
					      int phy_id)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
	u8 lr_error = dl->status_block[1];
	u8 retries_left = dl->status_block[2];

	switch (lr_error) {
	case 0:
		ASD_DPRINTK("phy%d: Receive ID timer expired\n", phy_id);
		break;
	case 1:
		ASD_DPRINTK("phy%d: Loss of signal\n", phy_id);
		break;
	case 2:
		ASD_DPRINTK("phy%d: Loss of dword sync\n", phy_id);
		break;
	case 3:
		ASD_DPRINTK("phy%d: Receive FIS timeout\n", phy_id);
		break;
	default:
		ASD_DPRINTK("phy%d: unknown link reset error code: 0x%x\n",
			    phy_id, lr_error);
		break;
	}

	asd_turn_led(asd_ha, phy_id, 0);
	sas_phy_disconnected(sas_phy);
	sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);

	if (retries_left == 0) {
		int num = 1;
		struct asd_ascb *cp = asd_ascb_alloc_list(ascb->ha, &num,
							  GFP_ATOMIC);
		if (!cp) {
			asd_printk("%s: out of memory\n", __FUNCTION__);
			goto out;
		}
		ASD_DPRINTK("phy%d: retries:0 performing link reset seq\n",
			    phy_id);
		asd_build_control_phy(cp, phy_id, ENABLE_PHY);
		if (asd_post_ascb_list(ascb->ha, cp, 1) != 0)
			asd_ascb_free(cp);
	}
out:
	;
}

static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
					      struct done_list_struct *dl,
					      int phy_id)
{
	unsigned long flags;
	struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
	u8  reg  = dl->status_block[1];
	u32 cont = dl->status_block[2] << ((reg & 3)*8);

	reg &= ~3;
	switch (reg) {
	case LmPRMSTAT0BYTE0:
		switch (cont) {
		case LmBROADCH:
		case LmBROADRVCH0:
		case LmBROADRVCH1:
		case LmBROADSES:
			ASD_DPRINTK("phy%d: BROADCAST change received:%d\n",
				    phy_id, cont);
			spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
			sas_phy->sas_prim = ffs(cont);
			spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
			sas_ha->notify_port_event(sas_phy,PORTE_BROADCAST_RCVD);
			break;

		case LmUNKNOWNP:
			ASD_DPRINTK("phy%d: unknown BREAK\n", phy_id);
			break;

		default:
			ASD_DPRINTK("phy%d: primitive reg:0x%x, cont:0x%04x\n",
				    phy_id, reg, cont);
			break;
		}
		break;
	case LmPRMSTAT1BYTE0:
		switch (cont) {
		case LmHARDRST:
			ASD_DPRINTK("phy%d: HARD_RESET primitive rcvd\n",
				    phy_id);
			/* The sequencer disables all phys on that port.
			 * We have to re-enable the phys ourselves. */
			sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
			break;

		default:
			ASD_DPRINTK("phy%d: primitive reg:0x%x, cont:0x%04x\n",
				    phy_id, reg, cont);
			break;
		}
		break;
	default:
		ASD_DPRINTK("unknown primitive register:0x%x\n",
			    dl->status_block[1]);
		break;
	}
}

/**
 * asd_invalidate_edb -- invalidate an EDB and if necessary post the ESCB
 * @ascb: pointer to Empty SCB
 * @edb_id: index [0,6] to the empty data buffer which is to be invalidated
 *
 * After an EDB has been invalidated, if all EDBs in this ESCB have been
 * invalidated, the ESCB is posted back to the sequencer.
 * Context is tasklet/IRQ.
 */
void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id)
{
	struct asd_seq_data *seq = &ascb->ha->seq;
	struct empty_scb *escb = &ascb->scb->escb;
	struct sg_el     *eb   = &escb->eb[edb_id];
	struct asd_dma_tok *edb = seq->edb_arr[ascb->edb_index + edb_id];

	memset(edb->vaddr, 0, ASD_EDB_SIZE);
	eb->flags |= ELEMENT_NOT_VALID;
	escb->num_valid--;

	if (escb->num_valid == 0) {
		int i;
		/* ASD_DPRINTK("reposting escb: vaddr: 0x%p, "
			    "dma_handle: 0x%08llx, next: 0x%08llx, "
			    "index:%d, opcode:0x%02x\n",
			    ascb->dma_scb.vaddr,
			    (u64)ascb->dma_scb.dma_handle,
			    le64_to_cpu(ascb->scb->header.next_scb),
			    le16_to_cpu(ascb->scb->header.index),
			    ascb->scb->header.opcode);
		*/
		escb->num_valid = ASD_EDBS_PER_SCB;
		for (i = 0; i < ASD_EDBS_PER_SCB; i++)
			escb->eb[i].flags = 0;
		if (!list_empty(&ascb->list))
			list_del_init(&ascb->list);
		i = asd_post_escb_list(ascb->ha, ascb, 1);
		if (i)
			asd_printk("couldn't post escb, err:%d\n", i);
	}
}

static void escb_tasklet_complete(struct asd_ascb *ascb,
				  struct done_list_struct *dl)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
	int edb = (dl->opcode & DL_PHY_MASK) - 1; /* [0xc1,0xc7] -> [0,6] */
	u8  sb_opcode = dl->status_block[0];
	int phy_id = sb_opcode & DL_PHY_MASK;
	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];

	if (edb > 6 || edb < 0) {
		ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
			    edb, dl->opcode);
		ASD_DPRINTK("sb_opcode : 0x%x, phy_id: 0x%x\n",
			    sb_opcode, phy_id);
		ASD_DPRINTK("escb: vaddr: 0x%p, "
			    "dma_handle: 0x%llx, next: 0x%llx, "
			    "index:%d, opcode:0x%02x\n",
			    ascb->dma_scb.vaddr,
			    (unsigned long long)ascb->dma_scb.dma_handle,
			    (unsigned long long)
			    le64_to_cpu(ascb->scb->header.next_scb),
			    le16_to_cpu(ascb->scb->header.index),
			    ascb->scb->header.opcode);
	}

	sb_opcode &= ~DL_PHY_MASK;

	switch (sb_opcode) {
	case BYTES_DMAED:
		ASD_DPRINTK("%s: phy%d: BYTES_DMAED\n", __FUNCTION__, phy_id);
		asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id);
		break;
	case PRIMITIVE_RECVD:
		ASD_DPRINTK("%s: phy%d: PRIMITIVE_RECVD\n", __FUNCTION__,
			    phy_id);
		asd_primitive_rcvd_tasklet(ascb, dl, phy_id);
		break;
	case PHY_EVENT:
		ASD_DPRINTK("%s: phy%d: PHY_EVENT\n", __FUNCTION__, phy_id);
		asd_phy_event_tasklet(ascb, dl);
		break;
	case LINK_RESET_ERROR:
		ASD_DPRINTK("%s: phy%d: LINK_RESET_ERROR\n", __FUNCTION__,
			    phy_id);
		asd_link_reset_err_tasklet(ascb, dl, phy_id);
		break;
	case TIMER_EVENT:
		ASD_DPRINTK("%s: phy%d: TIMER_EVENT, lost dw sync\n",
			    __FUNCTION__, phy_id);
		asd_turn_led(asd_ha, phy_id, 0);
		/* the device is gone */
		sas_phy_disconnected(sas_phy);
		sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
		break;
	case REQ_TASK_ABORT:
		ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__,
			    phy_id);
		break;
	case REQ_DEVICE_RESET:
		ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__,
			    phy_id);
		break;
	case SIGNAL_NCQ_ERROR:
		ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__,
			    phy_id);
		break;
	case CLEAR_NCQ_ERROR:
		ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__,
			    phy_id);
		break;
	default:
		ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__,
			    phy_id, sb_opcode);
		ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
			    edb, dl->opcode);
		ASD_DPRINTK("sb_opcode : 0x%x, phy_id: 0x%x\n",
			    sb_opcode, phy_id);
		ASD_DPRINTK("escb: vaddr: 0x%p, "
			    "dma_handle: 0x%llx, next: 0x%llx, "
			    "index:%d, opcode:0x%02x\n",
			    ascb->dma_scb.vaddr,
			    (unsigned long long)ascb->dma_scb.dma_handle,
			    (unsigned long long)
			    le64_to_cpu(ascb->scb->header.next_scb),
			    le16_to_cpu(ascb->scb->header.index),
			    ascb->scb->header.opcode);

		break;
	}

	asd_invalidate_edb(ascb, edb);
}

int asd_init_post_escbs(struct asd_ha_struct *asd_ha)
{
	struct asd_seq_data *seq = &asd_ha->seq;
	int i;

	for (i = 0; i < seq->num_escbs; i++)
		seq->escb_arr[i]->tasklet_complete = escb_tasklet_complete;

	ASD_DPRINTK("posting %d escbs\n", i);
	return asd_post_escb_list(asd_ha, seq->escb_arr[0], seq->num_escbs);
}

/* ---------- CONTROL PHY ---------- */

#define CONTROL_PHY_STATUS (CURRENT_DEVICE_PRESENT | CURRENT_OOB_DONE   \
			    | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
			    | CURRENT_OOB_ERROR)

/**
 * control_phy_tasklet_complete -- tasklet complete for CONTROL PHY ascb
 * @ascb: pointer to an ascb
 * @dl: pointer to the done list entry
 *
 * This function completes a CONTROL PHY scb and frees the ascb.
 * A note on LEDs:
 *  - an LED blinks if there is IO though it,
 *  - if a device is connected to the LED, it is lit,
 *  - if no device is connected to the LED, is is dimmed (off).
 */
static void control_phy_tasklet_complete(struct asd_ascb *ascb,
					 struct done_list_struct *dl)
{
	struct asd_ha_struct *asd_ha = ascb->ha;
	struct scb *scb = ascb->scb;
	struct control_phy *control_phy = &scb->control_phy;
	u8 phy_id = control_phy->phy_id;
	struct asd_phy *phy = &ascb->ha->phys[phy_id];

	u8 status     = dl->status_block[0];
	u8 oob_status = dl->status_block[1];
	u8 oob_mode   = dl->status_block[2];
	/* u8 oob_signals= dl->status_block[3]; */

	if (status != 0) {
		ASD_DPRINTK("%s: phy%d status block opcode:0x%x\n",
			    __FUNCTION__, phy_id, status);
		goto out;
	}

	switch (control_phy->sub_func) {
	case DISABLE_PHY:
		asd_ha->hw_prof.enabled_phys &= ~(1 << phy_id);
		asd_turn_led(asd_ha, phy_id, 0);
		asd_control_led(asd_ha, phy_id, 0);
		ASD_DPRINTK("%s: disable phy%d\n", __FUNCTION__, phy_id);
		break;

	case ENABLE_PHY:
		asd_control_led(asd_ha, phy_id, 1);
		if (oob_status & CURRENT_OOB_DONE) {
			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
			get_lrate_mode(phy, oob_mode);
			asd_turn_led(asd_ha, phy_id, 1);
			ASD_DPRINTK("%s: phy%d, lrate:0x%x, proto:0x%x\n",
				    __FUNCTION__, phy_id,phy->sas_phy.linkrate,
				    phy->sas_phy.iproto);
		} else if (oob_status & CURRENT_SPINUP_HOLD) {
			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
			asd_turn_led(asd_ha, phy_id, 1);
			ASD_DPRINTK("%s: phy%d, spinup hold\n", __FUNCTION__,
				    phy_id);
		} else if (oob_status & CURRENT_ERR_MASK) {
			asd_turn_led(asd_ha, phy_id, 0);
			ASD_DPRINTK("%s: phy%d: error: oob status:0x%02x\n",
				    __FUNCTION__, phy_id, oob_status);
		} else if (oob_status & (CURRENT_HOT_PLUG_CNCT
					 | CURRENT_DEVICE_PRESENT))  {
			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
			asd_turn_led(asd_ha, phy_id, 1);
			ASD_DPRINTK("%s: phy%d: hot plug or device present\n",
				    __FUNCTION__, phy_id);
		} else {
			asd_ha->hw_prof.enabled_phys |= (1 << phy_id);
			asd_turn_led(asd_ha, phy_id, 0);
			ASD_DPRINTK("%s: phy%d: no device present: "
				    "oob_status:0x%x\n",
				    __FUNCTION__, phy_id, oob_status);
		}
		break;
	case RELEASE_SPINUP_HOLD:
	case PHY_NO_OP:
	case EXECUTE_HARD_RESET:
		ASD_DPRINTK("%s: phy%d: sub_func:0x%x\n", __FUNCTION__,
			    phy_id, control_phy->sub_func);
		/* XXX finish */
		break;
	default:
		ASD_DPRINTK("%s: phy%d: sub_func:0x%x?\n", __FUNCTION__,
			    phy_id, control_phy->sub_func);
		break;
	}
out:
	asd_ascb_free(ascb);
}

static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
{
	/* disable all speeds, then enable defaults */
	*speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS
		| SATA_SPEED_30_DIS | SATA_SPEED_15_DIS;

	switch (pd->max_sas_lrate) {
	case SAS_LINK_RATE_6_0_GBPS:
		*speed_mask &= ~SAS_SPEED_60_DIS;
	default:
	case SAS_LINK_RATE_3_0_GBPS:
		*speed_mask &= ~SAS_SPEED_30_DIS;
	case SAS_LINK_RATE_1_5_GBPS:
		*speed_mask &= ~SAS_SPEED_15_DIS;
	}

	switch (pd->min_sas_lrate) {
	case SAS_LINK_RATE_6_0_GBPS:
		*speed_mask |= SAS_SPEED_30_DIS;
	case SAS_LINK_RATE_3_0_GBPS:
		*speed_mask |= SAS_SPEED_15_DIS;
	default:
	case SAS_LINK_RATE_1_5_GBPS:
		/* nothing to do */
		;
	}

	switch (pd->max_sata_lrate) {
	case SAS_LINK_RATE_3_0_GBPS:
		*speed_mask &= ~SATA_SPEED_30_DIS;
	default:
	case SAS_LINK_RATE_1_5_GBPS:
		*speed_mask &= ~SATA_SPEED_15_DIS;
	}

	switch (pd->min_sata_lrate) {
	case SAS_LINK_RATE_3_0_GBPS:
		*speed_mask |= SATA_SPEED_15_DIS;
	default:
	case SAS_LINK_RATE_1_5_GBPS:
		/* nothing to do */
		;
	}
}

/**
 * asd_build_control_phy -- build a CONTROL PHY SCB
 * @ascb: pointer to an ascb
 * @phy_id: phy id to control, integer
 * @subfunc: subfunction, what to actually to do the phy
 *
 * This function builds a CONTROL PHY scb.  No allocation of any kind
 * is performed. @ascb is allocated with the list function.
 * The caller can override the ascb->tasklet_complete to point
 * to its own callback function.  It must call asd_ascb_free()
 * at its tasklet complete function.
 * See the default implementation.
 */
void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc)
{
	struct asd_phy *phy = &ascb->ha->phys[phy_id];
	struct scb *scb = ascb->scb;
	struct control_phy *control_phy = &scb->control_phy;

	scb->header.opcode = CONTROL_PHY;
	control_phy->phy_id = (u8) phy_id;
	control_phy->sub_func = subfunc;

	switch (subfunc) {
	case EXECUTE_HARD_RESET:  /* 0x81 */
	case ENABLE_PHY:          /* 0x01 */
		/* decide hot plug delay */
		control_phy->hot_plug_delay = HOTPLUG_DELAY_TIMEOUT;

		/* decide speed mask */
		set_speed_mask(&control_phy->speed_mask, phy->phy_desc);

		/* initiator port settings are in the hi nibble */
		if (phy->sas_phy.role == PHY_ROLE_INITIATOR)
			control_phy->port_type = SAS_PROTO_ALL << 4;
		else if (phy->sas_phy.role == PHY_ROLE_TARGET)
			control_phy->port_type = SAS_PROTO_ALL;
		else
			control_phy->port_type =
				(SAS_PROTO_ALL << 4) | SAS_PROTO_ALL;

		/* link reset retries, this should be nominal */
		control_phy->link_reset_retries = 10;

	case RELEASE_SPINUP_HOLD: /* 0x02 */
		/* decide the func_mask */
		control_phy->func_mask = FUNCTION_MASK_DEFAULT;
		if (phy->phy_desc->flags & ASD_SATA_SPINUP_HOLD)
			control_phy->func_mask &= ~SPINUP_HOLD_DIS;
		else
			control_phy->func_mask |= SPINUP_HOLD_DIS;
	}

	control_phy->conn_handle = cpu_to_le16(0xFFFF);

	ascb->tasklet_complete = control_phy_tasklet_complete;
}

/* ---------- INITIATE LINK ADM TASK ---------- */

static void link_adm_tasklet_complete(struct asd_ascb *ascb,
				      struct done_list_struct *dl)
{
	u8 opcode = dl->opcode;
	struct initiate_link_adm *link_adm = &ascb->scb->link_adm;
	u8 phy_id = link_adm->phy_id;

	if (opcode != TC_NO_ERROR) {
		asd_printk("phy%d: link adm task 0x%x completed with error "
			   "0x%x\n", phy_id, link_adm->sub_func, opcode);
	}
	ASD_DPRINTK("phy%d: link adm task 0x%x: 0x%x\n",
		    phy_id, link_adm->sub_func, opcode);

	asd_ascb_free(ascb);
}

void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
				      u8 subfunc)
{
	struct scb *scb = ascb->scb;
	struct initiate_link_adm *link_adm = &scb->link_adm;

	scb->header.opcode = INITIATE_LINK_ADM_TASK;

	link_adm->phy_id = phy_id;
	link_adm->sub_func = subfunc;
	link_adm->conn_handle = cpu_to_le16(0xFFFF);

	ascb->tasklet_complete = link_adm_tasklet_complete;
}

/* ---------- SCB timer ---------- */

/**
 * asd_ascb_timedout -- called when a pending SCB's timer has expired
 * @data: unsigned long, a pointer to the ascb in question
 *
 * This is the default timeout function which does the most necessary.
 * Upper layers can implement their own timeout function, say to free
 * resources they have with this SCB, and then call this one at the
 * end of their timeout function.  To do this, one should initialize
 * the ascb->timer.{function, data, expires} prior to calling the post
 * funcion.  The timer is started by the post function.
 */
void asd_ascb_timedout(unsigned long data)
{
	struct asd_ascb *ascb = (void *) data;
	struct asd_seq_data *seq = &ascb->ha->seq;
	unsigned long flags;

	ASD_DPRINTK("scb:0x%x timed out\n", ascb->scb->header.opcode);

	spin_lock_irqsave(&seq->pend_q_lock, flags);
	seq->pending--;
	list_del_init(&ascb->list);
	spin_unlock_irqrestore(&seq->pend_q_lock, flags);

	asd_ascb_free(ascb);
}

/* ---------- CONTROL PHY ---------- */

/* Given the spec value, return a driver value. */
static const int phy_func_table[] = {
	[PHY_FUNC_NOP]        = PHY_NO_OP,
	[PHY_FUNC_LINK_RESET] = ENABLE_PHY,
	[PHY_FUNC_HARD_RESET] = EXECUTE_HARD_RESET,
	[PHY_FUNC_DISABLE]    = DISABLE_PHY,
	[PHY_FUNC_RELEASE_SPINUP_HOLD] = RELEASE_SPINUP_HOLD,
};

int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func, void *arg)
{
	struct asd_ha_struct *asd_ha = phy->ha->lldd_ha;
	struct asd_phy_desc *pd = asd_ha->phys[phy->id].phy_desc;
	struct asd_ascb *ascb;
	struct sas_phy_linkrates *rates;
	int res = 1;

	switch (func) {
	case PHY_FUNC_CLEAR_ERROR_LOG:
		return -ENOSYS;
	case PHY_FUNC_SET_LINK_RATE:
		rates = arg;
		if (rates->minimum_linkrate) {
			pd->min_sas_lrate = rates->minimum_linkrate;
			pd->min_sata_lrate = rates->minimum_linkrate;
		}
		if (rates->maximum_linkrate) {
			pd->max_sas_lrate = rates->maximum_linkrate;
			pd->max_sata_lrate = rates->maximum_linkrate;
		}
		func = PHY_FUNC_LINK_RESET;
		break;
	default:
		break;
	}

	ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
	if (!ascb)
		return -ENOMEM;

	asd_build_control_phy(ascb, phy->id, phy_func_table[func]);
	res = asd_post_ascb_list(asd_ha, ascb , 1);
	if (res)
		asd_ascb_free(ascb);

	return res;
}
