|
24 | 24 | #include <linux/pm_opp.h> |
25 | 25 | #include <linux/regulator/consumer.h> |
26 | 26 | #include <linux/sched/clock.h> |
| 27 | +#include <linux/sizes.h> |
27 | 28 | #include <linux/iopoll.h> |
28 | 29 | #include <scsi/scsi_cmnd.h> |
29 | 30 | #include <scsi/scsi_dbg.h> |
@@ -517,8 +518,8 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, struct scsi_cmnd *cmd, |
517 | 518 |
|
518 | 519 | if (hba->mcq_enabled) { |
519 | 520 | struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, rq); |
520 | | - |
521 | | - hwq_id = hwq->id; |
| 521 | + if (hwq) |
| 522 | + hwq_id = hwq->id; |
522 | 523 | } else { |
523 | 524 | doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); |
524 | 525 | } |
@@ -4389,14 +4390,6 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) |
4389 | 4390 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
4390 | 4391 | mutex_unlock(&hba->uic_cmd_mutex); |
4391 | 4392 |
|
4392 | | - /* |
4393 | | - * If the h8 exit fails during the runtime resume process, it becomes |
4394 | | - * stuck and cannot be recovered through the error handler. To fix |
4395 | | - * this, use link recovery instead of the error handler. |
4396 | | - */ |
4397 | | - if (ret && hba->pm_op_in_progress) |
4398 | | - ret = ufshcd_link_recovery(hba); |
4399 | | - |
4400 | 4393 | return ret; |
4401 | 4394 | } |
4402 | 4395 |
|
@@ -5249,6 +5242,25 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev) |
5249 | 5242 | hba->dev_info.rpmb_region_size[1] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION1_SIZE]; |
5250 | 5243 | hba->dev_info.rpmb_region_size[2] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION2_SIZE]; |
5251 | 5244 | hba->dev_info.rpmb_region_size[3] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION3_SIZE]; |
| 5245 | + |
| 5246 | + if (hba->dev_info.wspecversion <= 0x0220) { |
| 5247 | + /* |
| 5248 | + * These older spec chips have only one RPMB region, |
| 5249 | + * sized between 128 kB minimum and 16 MB maximum. |
| 5250 | + * No per region size fields are provided (respective |
| 5251 | + * REGIONX_SIZE fields always contain zeros), so get |
| 5252 | + * it from the logical block count and size fields for |
| 5253 | + * compatibility |
| 5254 | + * |
| 5255 | + * (See JESD220C-2_2 Section 14.1.4.6 |
| 5256 | + * RPMB Unit Descriptor,* offset 13h, 4 bytes) |
| 5257 | + */ |
| 5258 | + hba->dev_info.rpmb_region_size[0] = |
| 5259 | + (get_unaligned_be64(desc_buf |
| 5260 | + + RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT) |
| 5261 | + << desc_buf[RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE]) |
| 5262 | + / SZ_128K; |
| 5263 | + } |
5252 | 5264 | } |
5253 | 5265 |
|
5254 | 5266 |
|
@@ -5963,6 +5975,7 @@ static int ufshcd_disable_auto_bkops(struct ufs_hba *hba) |
5963 | 5975 |
|
5964 | 5976 | hba->auto_bkops_enabled = false; |
5965 | 5977 | trace_ufshcd_auto_bkops_state(hba, "Disabled"); |
| 5978 | + hba->urgent_bkops_lvl = BKOPS_STATUS_PERF_IMPACT; |
5966 | 5979 | hba->is_urgent_bkops_lvl_checked = false; |
5967 | 5980 | out: |
5968 | 5981 | return err; |
@@ -6066,7 +6079,7 @@ static void ufshcd_bkops_exception_event_handler(struct ufs_hba *hba) |
6066 | 6079 | * impacted or critical. Handle these device by determining their urgent |
6067 | 6080 | * bkops status at runtime. |
6068 | 6081 | */ |
6069 | | - if (curr_status < BKOPS_STATUS_PERF_IMPACT) { |
| 6082 | + if ((curr_status > BKOPS_STATUS_NO_OP) && (curr_status < BKOPS_STATUS_PERF_IMPACT)) { |
6070 | 6083 | dev_err(hba->dev, "%s: device raised urgent BKOPS exception for bkops status %d\n", |
6071 | 6084 | __func__, curr_status); |
6072 | 6085 | /* update the current status as the urgent bkops level */ |
@@ -7097,7 +7110,7 @@ static irqreturn_t ufshcd_handle_mcq_cq_events(struct ufs_hba *hba) |
7097 | 7110 |
|
7098 | 7111 | ret = ufshcd_vops_get_outstanding_cqs(hba, &outstanding_cqs); |
7099 | 7112 | if (ret) |
7100 | | - outstanding_cqs = (1U << hba->nr_hw_queues) - 1; |
| 7113 | + outstanding_cqs = (1ULL << hba->nr_hw_queues) - 1; |
7101 | 7114 |
|
7102 | 7115 | /* Exclude the poll queues */ |
7103 | 7116 | nr_queues = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL]; |
@@ -10179,7 +10192,15 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) |
10179 | 10192 | } else { |
10180 | 10193 | dev_err(hba->dev, "%s: hibern8 exit failed %d\n", |
10181 | 10194 | __func__, ret); |
10182 | | - goto vendor_suspend; |
| 10195 | + /* |
| 10196 | + * If the h8 exit fails during the runtime resume |
| 10197 | + * process, it becomes stuck and cannot be recovered |
| 10198 | + * through the error handler. To fix this, use link |
| 10199 | + * recovery instead of the error handler. |
| 10200 | + */ |
| 10201 | + ret = ufshcd_link_recovery(hba); |
| 10202 | + if (ret) |
| 10203 | + goto vendor_suspend; |
10183 | 10204 | } |
10184 | 10205 | } else if (ufshcd_is_link_off(hba)) { |
10185 | 10206 | /* |
|
0 commit comments