static void slot_err_v2_hw()

in hisi_sas/hisi_sas_v2_hw.c [2016:2319]


static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
			   struct sas_task *task,
			   struct hisi_sas_slot *slot,
			   int err_phase)
{
	struct task_status_struct *ts = &task->task_status;
	struct hisi_sas_err_record_v2 *err_record =
			hisi_sas_status_buf_addr_mem(slot);
	u32 trans_tx_fail_type = le32_to_cpu(err_record->trans_tx_fail_type);
	u32 trans_rx_fail_type = le32_to_cpu(err_record->trans_rx_fail_type);
	u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
	u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
	u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
	int error = -1;

	if (err_phase == 1) {
		/* error in TX phase, the priority of error is: DW2 > DW0 */
		error = parse_dma_tx_err_code_v2_hw(dma_tx_err_type);
		if (error == -1)
			error = parse_trans_tx_err_code_v2_hw(
					trans_tx_fail_type);
	} else if (err_phase == 2) {
		/* error in RX phase, the priority is: DW1 > DW3 > DW2 */
		error = parse_trans_rx_err_code_v2_hw(trans_rx_fail_type);
		if (error == -1) {
			error = parse_dma_rx_err_code_v2_hw(
					dma_rx_err_type);
			if (error == -1)
				error = parse_sipc_rx_err_code_v2_hw(
						sipc_rx_err_type);
		}
	}

	switch (task->task_proto) {
	case SAS_PROTOCOL_SSP:
	{
		switch (error) {
		case TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_NO_DEST;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_EPROTO;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_CONN_RATE;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_BAD_DEST;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
			break;
		}
		case DMA_RX_UNEXP_NORM_RESP_ERR:
		case TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION:
		case DMA_RX_RESP_BUF_OVERFLOW:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_UNKNOWN;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER:
		{
			/* not sure */
			ts->stat = SAS_DEV_NO_RESPONSE;
			break;
		}
		case DMA_RX_DATA_LEN_OVERFLOW:
		{
			ts->stat = SAS_DATA_OVERRUN;
			ts->residual = 0;
			break;
		}
		case DMA_RX_DATA_LEN_UNDERFLOW:
		{
			ts->residual = trans_tx_fail_type;
			ts->stat = SAS_DATA_UNDERRUN;
			break;
		}
		case TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS:
		case TRANS_TX_ERR_PHY_NOT_ENABLE:
		case TRANS_TX_OPEN_CNX_ERR_BY_OTHER:
		case TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT:
		case TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD:
		case TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED:
		case TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT:
		case TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED:
		case TRANS_TX_ERR_WITH_BREAK_TIMEOUT:
		case TRANS_TX_ERR_WITH_BREAK_REQUEST:
		case TRANS_TX_ERR_WITH_BREAK_RECEVIED:
		case TRANS_TX_ERR_WITH_CLOSE_TIMEOUT:
		case TRANS_TX_ERR_WITH_CLOSE_NORMAL:
		case TRANS_TX_ERR_WITH_CLOSE_PHYDISALE:
		case TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT:
		case TRANS_TX_ERR_WITH_CLOSE_COMINIT:
		case TRANS_TX_ERR_WITH_NAK_RECEVIED:
		case TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT:
		case TRANS_TX_ERR_WITH_CREDIT_TIMEOUT:
		case TRANS_TX_ERR_WITH_IPTT_CONFLICT:
		case TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR:
		case TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR:
		case TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM:
		case TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN:
		case TRANS_RX_ERR_WITH_BREAK_TIMEOUT:
		case TRANS_RX_ERR_WITH_BREAK_REQUEST:
		case TRANS_RX_ERR_WITH_BREAK_RECEVIED:
		case TRANS_RX_ERR_WITH_CLOSE_NORMAL:
		case TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT:
		case TRANS_RX_ERR_WITH_CLOSE_COMINIT:
		case TRANS_TX_ERR_FRAME_TXED:
		case TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE:
		case TRANS_RX_ERR_WITH_DATA_LEN0:
		case TRANS_RX_ERR_WITH_BAD_HASH:
		case TRANS_RX_XRDY_WLEN_ZERO_ERR:
		case TRANS_RX_SSP_FRM_LEN_ERR:
		case TRANS_RX_ERR_WITH_BAD_FRM_TYPE:
		case DMA_TX_DATA_SGL_OVERFLOW:
		case DMA_TX_UNEXP_XFER_ERR:
		case DMA_TX_UNEXP_RETRANS_ERR:
		case DMA_TX_XFER_LEN_OVERFLOW:
		case DMA_TX_XFER_OFFSET_ERR:
		case SIPC_RX_DATA_UNDERFLOW_ERR:
		case DMA_RX_DATA_SGL_OVERFLOW:
		case DMA_RX_DATA_OFFSET_ERR:
		case DMA_RX_RDSETUP_LEN_ODD_ERR:
		case DMA_RX_RDSETUP_LEN_ZERO_ERR:
		case DMA_RX_RDSETUP_LEN_OVER_ERR:
		case DMA_RX_SATA_FRAME_TYPE_ERR:
		case DMA_RX_UNKNOWN_FRM_ERR:
		{
			/* This will request a retry */
			ts->stat = SAS_QUEUE_FULL;
			slot->abort = 1;
			break;
		}
		default:
			break;
		}
	}
		break;
	case SAS_PROTOCOL_SMP:
		ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
		break;

	case SAS_PROTOCOL_SATA:
	case SAS_PROTOCOL_STP:
	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
	{
		switch (error) {
		case TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_NO_DEST;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER:
		{
			ts->resp = SAS_TASK_UNDELIVERED;
			ts->stat = SAS_DEV_NO_RESPONSE;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_EPROTO;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_CONN_RATE;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_CONN_RATE;
			break;
		}
		case TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
			break;
		}
		case DMA_RX_RESP_BUF_OVERFLOW:
		case DMA_RX_UNEXP_NORM_RESP_ERR:
		case TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION:
		{
			ts->stat = SAS_OPEN_REJECT;
			ts->open_rej_reason = SAS_OREJ_UNKNOWN;
			break;
		}
		case DMA_RX_DATA_LEN_OVERFLOW:
		{
			ts->stat = SAS_DATA_OVERRUN;
			ts->residual = 0;
			break;
		}
		case DMA_RX_DATA_LEN_UNDERFLOW:
		{
			ts->residual = trans_tx_fail_type;
			ts->stat = SAS_DATA_UNDERRUN;
			break;
		}
		case TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS:
		case TRANS_TX_ERR_PHY_NOT_ENABLE:
		case TRANS_TX_OPEN_CNX_ERR_BY_OTHER:
		case TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT:
		case TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD:
		case TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED:
		case TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT:
		case TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED:
		case TRANS_TX_ERR_WITH_BREAK_TIMEOUT:
		case TRANS_TX_ERR_WITH_BREAK_REQUEST:
		case TRANS_TX_ERR_WITH_BREAK_RECEVIED:
		case TRANS_TX_ERR_WITH_CLOSE_TIMEOUT:
		case TRANS_TX_ERR_WITH_CLOSE_NORMAL:
		case TRANS_TX_ERR_WITH_CLOSE_PHYDISALE:
		case TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT:
		case TRANS_TX_ERR_WITH_CLOSE_COMINIT:
		case TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT:
		case TRANS_TX_ERR_WITH_CREDIT_TIMEOUT:
		case TRANS_TX_ERR_WITH_OPEN_BY_DES_OR_OTHERS:
		case TRANS_TX_ERR_WITH_WAIT_RECV_TIMEOUT:
		case TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM:
		case TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR:
		case TRANS_RX_ERR_WITH_RXFIS_DECODE_ERROR:
		case TRANS_RX_ERR_WITH_RXFIS_CRC_ERR:
		case TRANS_RX_ERR_WITH_RXFRAME_LENGTH_OVERRUN:
		case TRANS_RX_ERR_WITH_RXFIS_RX_SYNCP:
		case TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN:
		case TRANS_RX_ERR_WITH_BREAK_TIMEOUT:
		case TRANS_RX_ERR_WITH_BREAK_REQUEST:
		case TRANS_RX_ERR_WITH_BREAK_RECEVIED:
		case TRANS_RX_ERR_WITH_CLOSE_NORMAL:
		case TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE:
		case TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT:
		case TRANS_RX_ERR_WITH_CLOSE_COMINIT:
		case TRANS_RX_ERR_WITH_DATA_LEN0:
		case TRANS_RX_ERR_WITH_BAD_HASH:
		case TRANS_RX_XRDY_WLEN_ZERO_ERR:
		case TRANS_RX_ERR_WITH_BAD_FRM_TYPE:
		case DMA_TX_DATA_SGL_OVERFLOW:
		case DMA_TX_UNEXP_XFER_ERR:
		case DMA_TX_UNEXP_RETRANS_ERR:
		case DMA_TX_XFER_LEN_OVERFLOW:
		case DMA_TX_XFER_OFFSET_ERR:
		case SIPC_RX_FIS_STATUS_ERR_BIT_VLD:
		case SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR:
		case SIPC_RX_FIS_STATUS_BSY_BIT_ERR:
		case SIPC_RX_WRSETUP_LEN_ODD_ERR:
		case SIPC_RX_WRSETUP_LEN_ZERO_ERR:
		case SIPC_RX_WRDATA_LEN_NOT_MATCH_ERR:
		case SIPC_RX_SATA_UNEXP_FIS_ERR:
		case DMA_RX_DATA_SGL_OVERFLOW:
		case DMA_RX_DATA_OFFSET_ERR:
		case DMA_RX_SATA_FRAME_TYPE_ERR:
		case DMA_RX_UNEXP_RDFRAME_ERR:
		case DMA_RX_PIO_DATA_LEN_ERR:
		case DMA_RX_RDSETUP_STATUS_ERR:
		case DMA_RX_RDSETUP_STATUS_DRQ_ERR:
		case DMA_RX_RDSETUP_STATUS_BSY_ERR:
		case DMA_RX_RDSETUP_LEN_ODD_ERR:
		case DMA_RX_RDSETUP_LEN_ZERO_ERR:
		case DMA_RX_RDSETUP_LEN_OVER_ERR:
		case DMA_RX_RDSETUP_OFFSET_ERR:
		case DMA_RX_RDSETUP_ACTIVE_ERR:
		case DMA_RX_RDSETUP_ESTATUS_ERR:
		case DMA_RX_UNKNOWN_FRM_ERR:
		case TRANS_RX_SSP_FRM_LEN_ERR:
		case TRANS_TX_OPEN_CNX_ERR_STP_RESOURCES_BUSY:
		{
			slot->abort = 1;
			ts->stat = SAS_PHY_DOWN;
			break;
		}
		default:
		{
			ts->stat = SAS_PROTO_RESPONSE;
			break;
		}
		}
		hisi_sas_sata_done(task, slot);
	}
		break;
	default:
		break;
	}
}