aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaeyoon Choi <jaeyoon@FreeBSD.org>2025-12-01 04:38:24 +0000
committerJaeyoon Choi <jaeyoon@FreeBSD.org>2025-12-01 04:40:15 +0000
commit3e3d7e590566c7e1a55bfb0f084c9f64c6c46898 (patch)
tree1bb2ead7187196990b91748b54d6005a194d2032
parent5bfdb66ad985774b123ecd0cadee65c071b7ded0 (diff)
ufshci: add helper to convert SCSI LUN to UPIU LUN formats
Reviewed by: imp (mentor) Sponsored by: Samsung Electronics Differential Revision: https://reviews.freebsd.org/D53919
-rw-r--r--sys/dev/ufshci/ufshci.h2
-rw-r--r--sys/dev/ufshci/ufshci_sim.c25
2 files changed, 26 insertions, 1 deletions
diff --git a/sys/dev/ufshci/ufshci.h b/sys/dev/ufshci/ufshci.h
index b055d2d2d769..188f8c41def1 100644
--- a/sys/dev/ufshci/ufshci.h
+++ b/sys/dev/ufshci/ufshci.h
@@ -335,6 +335,8 @@ struct ufshci_upiu_header {
uint8_t flags;
};
uint8_t lun;
+#define UFSHCI_UPIU_UNIT_NUMBER_ID_MASK 0x7f
+#define UFSHCI_UPIU_WLUN_ID_MASK 0x80
uint8_t task_tag;
/* dword 1 */
diff --git a/sys/dev/ufshci/ufshci_sim.c b/sys/dev/ufshci/ufshci_sim.c
index 828b520614a5..1b80df089a46 100644
--- a/sys/dev/ufshci/ufshci_sim.c
+++ b/sys/dev/ufshci/ufshci_sim.c
@@ -72,6 +72,28 @@ ufshci_sim_illegal_request(union ccb *ccb)
xpt_done(ccb);
}
+/*
+ * The SCSI LUN format and the UFS UPIU LUN format are different.
+ * This function converts the SCSI LUN format to the UFS UPIU LUN format.
+ */
+static uint8_t
+ufshci_sim_translate_scsi_to_ufs_lun(lun_id_t scsi_lun)
+{
+ const int address_format_offset = 8;
+ uint8_t address_format = scsi_lun >> address_format_offset;
+
+ /* Well known logical unit */
+ if (((address_format & RPL_LUNDATA_ATYP_MASK) ==
+ RPL_LUNDATA_ATYP_EXTLUN) &&
+ ((address_format & RPL_LUNDATA_EXT_EAM_MASK) ==
+ RPL_LUNDATA_EXT_EAM_WK))
+ return ((scsi_lun & UFSHCI_UPIU_UNIT_NUMBER_ID_MASK) |
+ UFSHCI_UPIU_WLUN_ID_MASK);
+
+ /* Logical unit */
+ return (scsi_lun & UFSHCI_UPIU_UNIT_NUMBER_ID_MASK);
+}
+
static void
ufshchi_sim_scsiio(struct cam_sim *sim, union ccb *ccb)
{
@@ -129,7 +151,8 @@ ufshchi_sim_scsiio(struct cam_sim *sim, union ccb *ccb)
upiu->header.trans_type = UFSHCI_UPIU_TRANSACTION_CODE_COMMAND;
upiu->header.operational_flags = is_write ? UFSHCI_OPERATIONAL_FLAG_W :
UFSHCI_OPERATIONAL_FLAG_R;
- upiu->header.lun = csio->ccb_h.target_lun;
+ upiu->header.lun = ufshci_sim_translate_scsi_to_ufs_lun(
+ csio->ccb_h.target_lun);
upiu->header.cmd_set_type = UFSHCI_COMMAND_SET_TYPE_SCSI;
upiu->expected_data_transfer_length = htobe32(payload_len);