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; }
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; }
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; }