コード例 #1
0
static int dme_send_query_upiu(struct ufs_dev *dev, struct utp_query_req_upiu_type *query)
{
	struct upiu_trans_mgmt_query_hdr resp_upiu;
	struct upiu_req_build_type       req_upiu;
	int                              ret;

	memset(&req_upiu, 0, sizeof(req_upiu));

	req_upiu.opcode        = query->opcode;
	req_upiu.selector      = query->selector;
	req_upiu.index         = query->index;
	req_upiu.idn           = query->idn;
	req_upiu.trans_type    = UPIU_TYPE_QUERY_REQ;
	req_upiu.dd            = UTRD_NO_DATA_TRANSFER;
	req_upiu.resp_ptr      = (struct upiu_basic_resp_hdr *) &resp_upiu;
	req_upiu.resp_len      = sizeof(resp_upiu);
	req_upiu.resp_data_ptr = query->buf;
	req_upiu.timeout_msecs = UTP_GENERIC_CMD_TIMEOUT;

	if (query->opcode == UPIU_QUERY_OP_READ_DESCRIPTOR)
	{
		req_upiu.resp_data_len = query->buf_len;
	}

	ret = utp_enqueue_upiu(dev, &req_upiu);
	if (ret)
		goto utp_send_query_upiu_err;

	ret = dme_get_query_resp(dev, &req_upiu, query->buf, query->buf_len);
	if (ret)
		goto utp_send_query_upiu_err;

utp_send_query_upiu_err:
	return ret;
}
コード例 #2
0
int dme_send_nop_query(struct ufs_dev *dev)
{
	struct upiu_req_build_type     req_upiu;
	struct upiu_basic_resp_hdr     resp_upiu;
	int                            ret;
	unsigned                       try_again;

	ret       = UFS_SUCCESS;
	try_again = DME_NOP_NUM_RETRIES;

	memset(&req_upiu, 0 , sizeof(struct upiu_req_build_type));

	req_upiu.trans_type        = UPIU_TYPE_NOP_OUT;
	req_upiu.flags             = 0;
	req_upiu.query_mgmt_func   = 0;
	req_upiu.cmd_type          = UTRD_DEV_MGMT_FUNC;
	req_upiu.dd                = UTRD_NO_DATA_TRANSFER;
	req_upiu.resp_ptr          = &resp_upiu;
	req_upiu.resp_len          = sizeof(struct upiu_basic_hdr);
	req_upiu.timeout_msecs     = DME_NOP_QUERY_TIMEOUT;

	while (try_again)
	{
		try_again--;

		ret = utp_enqueue_upiu(dev, &req_upiu);

		if (ret == -UFS_RETRY)
		{
			continue;
		}
		else if (ret == -UFS_FAILURE)
		{
			dprintf(CRITICAL, "%s:%d Sending nop out failed.\n", __func__, __LINE__);
			goto upiu_send_nop_out_err;
		}

		/* Check response UPIU */
		if (resp_upiu.trans_type != UPIU_TYPE_NOP_IN)
		{
			dprintf(CRITICAL, "%s:%d Command failed. command = %x. Invalid response.\n",__func__,__LINE__, req_upiu.trans_type);
			ret = -UFS_FAILURE;
			goto upiu_send_nop_out_err;
		}
		else
			break;
	}

upiu_send_nop_out_err:
	return ret;
}
コード例 #3
0
int ucs_do_scsi_cmd(struct ufs_dev *dev, struct scsi_req_build_type *req)
{
	struct upiu_req_build_type req_upiu;
	struct upiu_basic_hdr      resp_upiu;
	int                        ret;

	memset(&req_upiu, 0 , sizeof(struct upiu_req_build_type));

	req_upiu.cmd_set_type	   = UPIU_SCSI_CMD_SET;
	req_upiu.trans_type	       = UPIU_TYPE_COMMAND;
	req_upiu.data_buffer_addr  = req->data_buffer_addr;
	req_upiu.expected_data_len = req->data_len;
	req_upiu.data_seg_len	   = 0;
	req_upiu.ehs_len		   = 0;
	req_upiu.flags			   = req->flags;
	req_upiu.lun			   = req->lun;
	req_upiu.query_mgmt_func   = 0;
	req_upiu.cdb			   = req->cdb;
	req_upiu.cmd_type		   = UTRD_SCSCI_CMD;
	req_upiu.dd			       = req->dd;
	req_upiu.resp_ptr		   = &resp_upiu;
	req_upiu.resp_len		   = sizeof(resp_upiu);
	req_upiu.timeout_msecs	   = UTP_GENERIC_CMD_TIMEOUT;

	if (utp_enqueue_upiu(dev, &req_upiu))
	{
		dprintf(CRITICAL, "ucs_do_scsi_cmd: enqueue failed\n");
		return -UFS_FAILURE;
	}

	if (resp_upiu.status != SCSI_STATUS_GOOD)
	{
		if (resp_upiu.status == SCSI_STATUS_CHK_COND && (*((uint8_t *)(req->cdb)) != SCSI_CMD_SENSE_REQ))
		{
			ret = ucs_do_request_sense(dev);
			if (ret)
				dprintf(CRITICAL, "SCSI request sense failed.\n");
		}

		dprintf(CRITICAL, "ucs_do_scsi_cmd failed status = %x\n", resp_upiu.status);
		return -UFS_FAILURE;
	}

	return UFS_SUCCESS;
}