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: