We are disabling the feature altogether if reading the configuration fails, or there are no HPB-luns configured, or no active regions are configure. Still, after reading the configuration successfully, there can be no HBP-enabled luns, e.g. if their pinned regions allocation has failed. So to avoid keep checking the upiu responses for nothing, we are verifying that indeed there are any HPB-enabled luns out there after 1min from the configuration read. By then all the luns were scanned and initialized their device handler. If there are no HPB-enabled luns – the feature is disabled altogether. Signed-off-by: Avri Altman <avri.altman@xxxxxxx> --- drivers/scsi/ufs/ufshcd.h | 1 + drivers/scsi/ufs/ufshpb.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index e7014a3..19a5613 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -743,6 +743,7 @@ struct ufs_hba { struct request_queue *bsg_queue; bool wb_buf_flush_enabled; bool wb_enabled; + struct delayed_work hpb_disable_work; }; /* Returns true if clocks can be gated. Otherwise false */ diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 4a10e7b..be926cb 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -299,6 +299,28 @@ static int ufshpb_get_unit_config(struct ufs_hba *hba, u8 dev_num_luns) return ret; } +static void ufshpb_disable_work(struct work_struct *work) +{ + struct ufs_hba *hba = container_of(work, struct ufs_hba, + hpb_disable_work.work); + + if (ufshpb_luns) { + unsigned int num_hpb_luns = ufshpb_conf->num_hpb_luns; + int i; + + for (i = 0; i < num_hpb_luns; i++) { + struct ufshpb_lun *hpb = ufshpb_luns + i; + + if (hpb->sdev && hpb->sdev->handler_data) + return; + } + } + + hba->caps &= ~UFSHCD_CAP_HPB; + ufshpb_remove(hba); + dev_info(hba->dev, "HPB was removed - no active HPB luns\n"); +} + /** * ufshpb_probe - read hpb config from the device * @hba: per adapter object @@ -368,6 +390,8 @@ int ufshpb_probe(struct ufs_hba *hba) if (ret) goto out; + INIT_DELAYED_WORK(&hba->hpb_disable_work, ufshpb_disable_work); + schedule_delayed_work(&hba->hpb_disable_work, 60 * HZ); out: kfree(dev_desc); if (ret) { -- 2.7.4