mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-18 02:24:18 +00:00
fix(ufs): set the PRDT length field properly
The PRDT length field contains the count of the entries in the PRDT. See JEDEC Standard No. 223E, section 6.1.1, "UTP Transfer Request Descriptor," page 66. Previously we were setting the PRDT length field to the number of bytes in the PRDT divided by four (the size in units of 32 bits). This was incorrect according to the spec. Signed-off-by: Jorge Troncoso <jatron@google.com> Change-Id: I960771e6ce57002872392993042fae9ec505447e
This commit is contained in:
parent
83ef8698f9
commit
20fdbcf502
2 changed files with 7 additions and 10 deletions
|
@ -288,9 +288,8 @@ static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun,
|
|||
prdt_t *prdt;
|
||||
unsigned int ulba;
|
||||
unsigned int lba_cnt;
|
||||
int prdt_size;
|
||||
uintptr_t desc_limit;
|
||||
size_t flush_size;
|
||||
uintptr_t prdt_end;
|
||||
|
||||
hd = (utrd_header_t *)utrd->header;
|
||||
upiu = (cmd_upiu_t *)utrd->upiu;
|
||||
|
@ -350,14 +349,13 @@ static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun,
|
|||
inv_dcache_range(buf, length);
|
||||
}
|
||||
|
||||
utrd->size_prdt = 0;
|
||||
utrd->prdt_length = 0;
|
||||
if (length) {
|
||||
upiu->exp_data_trans_len = htobe32(length);
|
||||
assert(lba_cnt <= UINT16_MAX);
|
||||
prdt = (prdt_t *)utrd->prdt;
|
||||
|
||||
desc_limit = ufs_params.desc_base + ufs_params.desc_size;
|
||||
prdt_size = 0;
|
||||
while (length > 0) {
|
||||
if ((uintptr_t)prdt + sizeof(prdt_t) > desc_limit) {
|
||||
ERROR("UFS: Exceeded descriptor limit. Image is too large\n");
|
||||
|
@ -375,15 +373,14 @@ static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun,
|
|||
}
|
||||
buf += MAX_PRDT_SIZE;
|
||||
prdt++;
|
||||
prdt_size += sizeof(prdt_t);
|
||||
utrd->prdt_length++;
|
||||
}
|
||||
utrd->size_prdt = ALIGN_8(prdt_size);
|
||||
hd->prdtl = utrd->size_prdt >> 2;
|
||||
hd->prdtl = utrd->prdt_length;
|
||||
hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2;
|
||||
}
|
||||
|
||||
flush_size = utrd->prdt + utrd->size_prdt - utrd->header;
|
||||
flush_dcache_range(utrd->header, flush_size);
|
||||
prdt_end = utrd->prdt + utrd->prdt_length * sizeof(prdt_t);
|
||||
flush_dcache_range(utrd->header, prdt_end - utrd->header);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -519,7 +519,7 @@ typedef struct utp_utrd {
|
|||
uintptr_t prdt;
|
||||
size_t size_upiu;
|
||||
size_t size_resp_upiu;
|
||||
size_t size_prdt;
|
||||
size_t prdt_length;
|
||||
int task_tag;
|
||||
} utp_utrd_t;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue