Merge "platform: msm_shared: Add flashing support for multiple LUNs in UFS."
diff --git a/platform/msm_shared/dme.c b/platform/msm_shared/dme.c
index ba195d7..670d344 100644
--- a/platform/msm_shared/dme.c
+++ b/platform/msm_shared/dme.c
@@ -285,9 +285,9 @@
/* Flush buffer. */
arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_unit_desc));
- dev->capacity = BE64(desc->logical_blk_cnt) * dev->block_size;
+ dev->lun_cfg[index].logical_blk_cnt = BE64(desc->logical_blk_cnt);
- dev->erase_blk_size = BE32(desc->erase_blk_size) * dev->block_size;
+ dev->lun_cfg[index].erase_blk_size = BE32(desc->erase_blk_size);
return UFS_SUCCESS;
}
diff --git a/platform/msm_shared/include/dme.h b/platform/msm_shared/include/dme.h
index 5f4110f..31be6c5 100644
--- a/platform/msm_shared/include/dme.h
+++ b/platform/msm_shared/include/dme.h
@@ -147,27 +147,6 @@
uint8_t dev_rtt_cap;
}__PACKED;
-struct ufs_unit_desc
-{
- uint8_t desc_len;
- uint8_t desc_type;
- uint8_t unit_index;
- uint8_t lu_enable;
- uint8_t boot_lun_id;
- uint8_t lu_wp;
- uint8_t lu_queue_depth;
- uint8_t resv;
- uint8_t mem_type;
- uint8_t data_reliability;
- uint8_t logical_blk_size;
- uint64_t logical_blk_cnt;
- uint32_t erase_blk_size;
- uint8_t provisioning_type;
- uint8_t phy_mem_resource_cnt[8];
- uint16_t ctx_capabilities;
- uint8_t large_unit_size_m1;
-}__PACKED;
-
struct ufs_geometry_desc
{
uint8_t desc_len;
diff --git a/platform/msm_shared/include/ufs.h b/platform/msm_shared/include/ufs.h
index 01e6550..bbe9a40 100644
--- a/platform/msm_shared/include/ufs.h
+++ b/platform/msm_shared/include/ufs.h
@@ -65,15 +65,38 @@
event_t uic_event;
};
+struct ufs_unit_desc
+{
+ uint8_t desc_len;
+ uint8_t desc_type;
+ uint8_t unit_index;
+ uint8_t lu_enable;
+ uint8_t boot_lun_id;
+ uint8_t lu_wp;
+ uint8_t lu_queue_depth;
+ uint8_t resv;
+ uint8_t mem_type;
+ uint8_t data_reliability;
+ uint8_t logical_blk_size;
+ uint64_t logical_blk_cnt;
+ uint32_t erase_blk_size;
+ uint8_t provisioning_type;
+ uint8_t phy_mem_resource_cnt[8];
+ uint16_t ctx_capabilities;
+ uint8_t large_unit_size_m1;
+}__PACKED;
+
struct ufs_dev
{
uint8_t instance;
uint32_t base;
uint8_t num_lus;
- uint32_t serial_num;
+ uint8_t current_lun;
+ uint32_t serial_num;
uint32_t block_size;
uint32_t erase_blk_size;
uint64_t capacity;
+ struct ufs_unit_desc lun_cfg[8];
/* UTRD maintainance data structures.*/
struct ufs_utp_req_meta_data utrd_data;
@@ -95,6 +118,7 @@
int ufs_erase(struct ufs_dev* dev, uint64_t start_lba, uint32_t num_blocks);
uint64_t ufs_get_dev_capacity(struct ufs_dev* dev);
uint32_t ufs_get_serial_num(struct ufs_dev* dev);
+uint8_t ufs_get_num_of_luns(struct ufs_dev* dev);
uint32_t ufs_get_erase_blk_size(struct ufs_dev* dev);
void ufs_dump_hc_registers(struct ufs_dev* dev);
#endif
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
index 65321db..1e03410 100644
--- a/platform/msm_shared/ucs.c
+++ b/platform/msm_shared/ucs.c
@@ -243,7 +243,7 @@
req_upiu.data_buffer_addr = (addr_t) param;
req_upiu.data_len = sizeof(struct unmap_param_list);
req_upiu.flags = UPIU_FLAGS_WRITE;
- req_upiu.lun = 0;
+ req_upiu.lun = req->lun;
req_upiu.dd = UTRD_SYSTEM_TO_TARGET;
if (ucs_do_scsi_cmd(dev, &req_upiu))
diff --git a/platform/msm_shared/ufs.c b/platform/msm_shared/ufs.c
index 5728bf7..8244576 100644
--- a/platform/msm_shared/ufs.c
+++ b/platform/msm_shared/ufs.c
@@ -91,7 +91,7 @@
int ret;
req.data_buffer_base = buffer;
- req.lun = 0;
+ req.lun = dev->current_lun;
req.num_blocks = num_blocks;
req.start_lba = start_lba / dev->block_size;
@@ -111,7 +111,7 @@
int ret;
req.data_buffer_base = buffer;
- req.lun = 0;
+ req.lun = dev->current_lun;
req.num_blocks = num_blocks;
req.start_lba = start_lba / dev->block_size;
@@ -145,12 +145,22 @@
uint64_t ufs_get_dev_capacity(struct ufs_dev* dev)
{
- return dev->capacity;
+ uint64_t capacity;
+ uint8_t lun = dev->current_lun;
+
+ capacity = dev->lun_cfg[lun].logical_blk_cnt * dev->block_size;
+
+ return capacity;
}
uint32_t ufs_get_erase_blk_size(struct ufs_dev* dev)
{
- return dev->erase_blk_size;
+ uint32_t erase_blk_size;
+ uint8_t lun = dev->current_lun;
+
+ erase_blk_size = dev->lun_cfg[lun].erase_blk_size;
+
+ return erase_blk_size;
}
uint32_t ufs_get_serial_num(struct ufs_dev* dev)
@@ -172,10 +182,16 @@
return dev->block_size;
}
+uint8_t ufs_get_num_of_luns(struct ufs_dev* dev)
+{
+ return dev->num_lus;
+}
+
int ufs_init(struct ufs_dev *dev)
{
uint32_t ret = UFS_SUCCESS;
uint64_t cap;
+ uint8_t lun = 0;
dev->block_size = 4096;
@@ -220,13 +236,24 @@
goto ufs_init_err;
}
- ret = dme_read_unit_desc(dev, 0);
+ ret = dme_read_device_desc(dev);
if (ret != UFS_SUCCESS)
{
- dprintf(CRITICAL, "UFS dme_read_unit_desc failed\n");
+ dprintf(CRITICAL, "dme_read_dev_desc read failed\n");
goto ufs_init_err;
}
+
+ for(lun=0; lun < dev->num_lus; lun++)
+ {
+ ret = dme_read_unit_desc(dev, lun);
+ if (ret != UFS_SUCCESS)
+ {
+ dprintf(CRITICAL, "UFS dme_read_unit_desc failed\n");
+ goto ufs_init_err;
+ }
+ }
+
dprintf(CRITICAL,"UFS init success\n");
ufs_init_err: