181 lines
5.3 KiB
C
181 lines
5.3 KiB
C
/* Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of The Linux Foundation nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef _UCS_H
|
|
#define _UCS_H
|
|
|
|
#include <upiu.h>
|
|
|
|
#define SCSI_MAX_DATA_TRANS_BLK_LEN 0xFFFF
|
|
#define UFS_DEFAULT_SECTORE_SIZE 4096
|
|
|
|
#define SCSI_STATUS_GOOD 0x00
|
|
#define SCSI_STATUS_CHK_COND 0x02
|
|
#define SCSI_STATUS_BUSY 0x08
|
|
#define SCSI_STATUS_TASK_SET_FULL 0x08
|
|
|
|
#define SCSI_SENSE_BUF_LEN 0x20
|
|
#define SCSI_INQUIRY_LEN 36
|
|
#define SCSI_CDB_PARAM_LEN 16
|
|
#define SCSI_SEC_PROT 0xEC
|
|
#define SCSI_SEC_UFS_PROT_ID 0x0001
|
|
|
|
/* FLAGS for indication of read or write */
|
|
enum scsi_upiu_flags
|
|
{
|
|
UPIU_FLAGS_READ = 0x40,
|
|
UPIU_FLAGS_WRITE = 0x20,
|
|
UPIU_FLAGS_ATTR_SIMPLE = 0x00,
|
|
UPIU_FLAGS_ATTR_ORDERED = 0x01,
|
|
UPIU_FLAGS_ATTR_HOQ = 0x02,
|
|
};
|
|
|
|
#define SCSI_READ_WRITE_10_CDB1(rd_protect, dpo, fua, fua_nv) ((rd_protect) << 5 | (dpo) << 4 | (fua) << 3 | (fua_nv) << 1)
|
|
|
|
/* SCSI commands */
|
|
enum utp_scsi_cmd_type
|
|
{
|
|
SCSI_CMD_TEST_UNIT_RDY = 0x00,
|
|
SCSI_CMD_SENSE_REQ = 0x03,
|
|
SCSI_CMD_INQUIRY = 0x12,
|
|
SCSI_CMD_READ10 = 0x28,
|
|
SCSI_CMD_READ_CAP10 = 0x25, // Read Capacity
|
|
SCSI_CMD_SYNC_CACHE10 = 0x35,
|
|
SCSI_CMD_UNMAP = 0x42,
|
|
SCSI_CMD_WRITE10 = 0x2A,
|
|
SCSI_CMD_SECPROT_IN = 0xA2, // Security Protocal in
|
|
SCSI_CMD_SECPROT_OUT = 0xB5, // Security Protocal out
|
|
SCSI_CMD_REPORT_LUNS = 0xA0,
|
|
};
|
|
|
|
struct scsi_req_build_type
|
|
{
|
|
addr_t cdb;
|
|
uint8_t lun;
|
|
addr_t data_buffer_addr;
|
|
uint32_t data_len;
|
|
enum scsi_upiu_flags flags;
|
|
enum upiu_dd_type dd;
|
|
};
|
|
|
|
struct scsi_rdwr_req
|
|
{
|
|
uint8_t lun;
|
|
uint32_t start_lba;
|
|
uint32_t num_blocks;
|
|
uint32_t data_buffer_base;
|
|
};
|
|
|
|
struct scsi_sec_protocol_cdb
|
|
{
|
|
uint8_t opcode;
|
|
uint8_t cdb1;
|
|
uint16_t sec_protocol_specific;
|
|
uint8_t resv1;
|
|
uint8_t resv2;
|
|
uint32_t alloc_tlen;
|
|
uint8_t resv3;
|
|
uint8_t control;
|
|
}__PACKED;
|
|
|
|
struct scsi_rdwr_cdb
|
|
{
|
|
uint8_t opcode;
|
|
uint8_t cdb1;
|
|
uint32_t lba;
|
|
uint8_t grp_num;
|
|
uint16_t trans_len;
|
|
uint8_t control;
|
|
uint8_t resv[6];
|
|
}__PACKED;
|
|
|
|
struct scsi_unmap_req
|
|
{
|
|
uint8_t lun;
|
|
uint64_t start_lba;
|
|
uint32_t num_blocks;
|
|
}__PACKED;
|
|
|
|
struct unmap_blk_desc
|
|
{
|
|
uint64_t lba;
|
|
uint32_t num_blks;
|
|
uint32_t reserved;
|
|
}__PACKED;
|
|
|
|
struct unmap_param_list
|
|
{
|
|
uint16_t data_len;
|
|
uint16_t blk_desc_data_len;
|
|
uint32_t reserved;
|
|
struct unmap_blk_desc blk_desc;
|
|
}__PACKED;
|
|
|
|
struct scsi_sense_cdb
|
|
{
|
|
uint8_t opcode;
|
|
uint8_t desc;
|
|
uint16_t resv_0;
|
|
uint8_t alloc_len;
|
|
uint8_t control;
|
|
uint8_t resv_1[10];
|
|
}__PACKED;
|
|
|
|
struct scsi_failure_sense_data
|
|
{
|
|
uint8_t valid_resp_code;
|
|
uint8_t obsolete;
|
|
uint16_t file_mark_eom_ili_resv_sense_key;
|
|
uint8_t sense_info[4];
|
|
uint8_t additional_sense_len;
|
|
uint32_t csi;
|
|
uint8_t asc;
|
|
uint8_t ascq;
|
|
uint8_t fruc;
|
|
uint8_t sense_key_specific;
|
|
}__PACKED;
|
|
|
|
int ucs_scsi_send_inquiry(struct ufs_dev *dev);
|
|
int ucs_do_scsi_cmd(struct ufs_dev *dev, struct scsi_req_build_type *req);
|
|
int ucs_do_scsi_read(struct ufs_dev *dev, struct scsi_rdwr_req *req);
|
|
int ucs_do_scsi_write(struct ufs_dev *dev, struct scsi_rdwr_req *req);
|
|
int ucs_do_scsi_unmap(struct ufs_dev *dev, struct scsi_unmap_req *req);
|
|
/*
|
|
* ucs_do_sci_rpmb_read function takes a RPMB frame, sector address and number of
|
|
* blocks to be read from RPMB partition as input and returns one or more RPMB
|
|
* frames as response along with total length of the reponse. The response is then
|
|
* processed by upper layers.
|
|
*/
|
|
int ucs_do_scsi_rpmb_read(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt,
|
|
uint32_t *resp_buffer, uint32_t *response_length);
|
|
|
|
/* This function parses the first byte of the sense data and returns the sense key */
|
|
int parse_sense_key(uint32_t sense_data);
|
|
int ucs_do_request_sense(struct ufs_dev *dev, uint8_t lun);
|
|
#endif
|