diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 74 | ||||
| -rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 2 |
2 files changed, 36 insertions, 40 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 497c38a4a866..59b654467d48 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
| @@ -2844,8 +2844,13 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev) | |||
| 2844 | hba = shost_priv(sdev->host); | 2844 | hba = shost_priv(sdev->host); |
| 2845 | scsi_deactivate_tcq(sdev, hba->nutrs); | 2845 | scsi_deactivate_tcq(sdev, hba->nutrs); |
| 2846 | /* Drop the reference as it won't be needed anymore */ | 2846 | /* Drop the reference as it won't be needed anymore */ |
| 2847 | if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) | 2847 | if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { |
| 2848 | unsigned long flags; | ||
| 2849 | |||
| 2850 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
| 2848 | hba->sdev_ufs_device = NULL; | 2851 | hba->sdev_ufs_device = NULL; |
| 2852 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 2853 | } | ||
| 2849 | } | 2854 | } |
| 2850 | 2855 | ||
| 2851 | /** | 2856 | /** |
| @@ -4062,6 +4067,8 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba) | |||
| 4062 | static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) | 4067 | static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) |
| 4063 | { | 4068 | { |
| 4064 | int ret = 0; | 4069 | int ret = 0; |
| 4070 | struct scsi_device *sdev_rpmb; | ||
| 4071 | struct scsi_device *sdev_boot; | ||
| 4065 | 4072 | ||
| 4066 | hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0, | 4073 | hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0, |
| 4067 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL); | 4074 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL); |
| @@ -4070,26 +4077,27 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) | |||
| 4070 | hba->sdev_ufs_device = NULL; | 4077 | hba->sdev_ufs_device = NULL; |
| 4071 | goto out; | 4078 | goto out; |
| 4072 | } | 4079 | } |
| 4080 | scsi_device_put(hba->sdev_ufs_device); | ||
| 4073 | 4081 | ||
| 4074 | hba->sdev_boot = __scsi_add_device(hba->host, 0, 0, | 4082 | sdev_boot = __scsi_add_device(hba->host, 0, 0, |
| 4075 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL); | 4083 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL); |
| 4076 | if (IS_ERR(hba->sdev_boot)) { | 4084 | if (IS_ERR(sdev_boot)) { |
| 4077 | ret = PTR_ERR(hba->sdev_boot); | 4085 | ret = PTR_ERR(sdev_boot); |
| 4078 | hba->sdev_boot = NULL; | ||
| 4079 | goto remove_sdev_ufs_device; | 4086 | goto remove_sdev_ufs_device; |
| 4080 | } | 4087 | } |
| 4088 | scsi_device_put(sdev_boot); | ||
| 4081 | 4089 | ||
| 4082 | hba->sdev_rpmb = __scsi_add_device(hba->host, 0, 0, | 4090 | sdev_rpmb = __scsi_add_device(hba->host, 0, 0, |
| 4083 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); | 4091 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); |
| 4084 | if (IS_ERR(hba->sdev_rpmb)) { | 4092 | if (IS_ERR(sdev_rpmb)) { |
| 4085 | ret = PTR_ERR(hba->sdev_rpmb); | 4093 | ret = PTR_ERR(sdev_rpmb); |
| 4086 | hba->sdev_rpmb = NULL; | ||
| 4087 | goto remove_sdev_boot; | 4094 | goto remove_sdev_boot; |
| 4088 | } | 4095 | } |
| 4096 | scsi_device_put(sdev_rpmb); | ||
| 4089 | goto out; | 4097 | goto out; |
| 4090 | 4098 | ||
| 4091 | remove_sdev_boot: | 4099 | remove_sdev_boot: |
| 4092 | scsi_remove_device(hba->sdev_boot); | 4100 | scsi_remove_device(sdev_boot); |
| 4093 | remove_sdev_ufs_device: | 4101 | remove_sdev_ufs_device: |
| 4094 | scsi_remove_device(hba->sdev_ufs_device); | 4102 | scsi_remove_device(hba->sdev_ufs_device); |
| 4095 | out: | 4103 | out: |
| @@ -4097,30 +4105,6 @@ out: | |||
| 4097 | } | 4105 | } |
| 4098 | 4106 | ||
| 4099 | /** | 4107 | /** |
| 4100 | * ufshcd_scsi_remove_wlus - Removes the W-LUs which were added by | ||
| 4101 | * ufshcd_scsi_add_wlus() | ||
| 4102 | * @hba: per-adapter instance | ||
| 4103 | * | ||
| 4104 | */ | ||
| 4105 | static void ufshcd_scsi_remove_wlus(struct ufs_hba *hba) | ||
| 4106 | { | ||
| 4107 | if (hba->sdev_ufs_device) { | ||
| 4108 | scsi_remove_device(hba->sdev_ufs_device); | ||
| 4109 | hba->sdev_ufs_device = NULL; | ||
| 4110 | } | ||
| 4111 | |||
| 4112 | if (hba->sdev_boot) { | ||
| 4113 | scsi_remove_device(hba->sdev_boot); | ||
| 4114 | hba->sdev_boot = NULL; | ||
| 4115 | } | ||
| 4116 | |||
| 4117 | if (hba->sdev_rpmb) { | ||
| 4118 | scsi_remove_device(hba->sdev_rpmb); | ||
| 4119 | hba->sdev_rpmb = NULL; | ||
| 4120 | } | ||
| 4121 | } | ||
| 4122 | |||
| 4123 | /** | ||
| 4124 | * ufshcd_probe_hba - probe hba to detect device and initialize | 4108 | * ufshcd_probe_hba - probe hba to detect device and initialize |
| 4125 | * @hba: per-adapter instance | 4109 | * @hba: per-adapter instance |
| 4126 | * | 4110 | * |
| @@ -4675,11 +4659,25 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, | |||
| 4675 | { | 4659 | { |
| 4676 | unsigned char cmd[6] = { START_STOP }; | 4660 | unsigned char cmd[6] = { START_STOP }; |
| 4677 | struct scsi_sense_hdr sshdr; | 4661 | struct scsi_sense_hdr sshdr; |
| 4678 | struct scsi_device *sdp = hba->sdev_ufs_device; | 4662 | struct scsi_device *sdp; |
| 4663 | unsigned long flags; | ||
| 4679 | int ret; | 4664 | int ret; |
| 4680 | 4665 | ||
| 4681 | if (!sdp || !scsi_device_online(sdp)) | 4666 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 4682 | return -ENODEV; | 4667 | sdp = hba->sdev_ufs_device; |
| 4668 | if (sdp) { | ||
| 4669 | ret = scsi_device_get(sdp); | ||
| 4670 | if (!ret && !scsi_device_online(sdp)) { | ||
| 4671 | ret = -ENODEV; | ||
| 4672 | scsi_device_put(sdp); | ||
| 4673 | } | ||
| 4674 | } else { | ||
| 4675 | ret = -ENODEV; | ||
| 4676 | } | ||
| 4677 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 4678 | |||
| 4679 | if (ret) | ||
| 4680 | return ret; | ||
| 4683 | 4681 | ||
| 4684 | /* | 4682 | /* |
| 4685 | * If scsi commands fail, the scsi mid-layer schedules scsi error- | 4683 | * If scsi commands fail, the scsi mid-layer schedules scsi error- |
| @@ -4718,6 +4716,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, | |||
| 4718 | if (!ret) | 4716 | if (!ret) |
| 4719 | hba->curr_dev_pwr_mode = pwr_mode; | 4717 | hba->curr_dev_pwr_mode = pwr_mode; |
| 4720 | out: | 4718 | out: |
| 4719 | scsi_device_put(sdp); | ||
| 4721 | hba->host->eh_noresume = 0; | 4720 | hba->host->eh_noresume = 0; |
| 4722 | return ret; | 4721 | return ret; |
| 4723 | } | 4722 | } |
| @@ -5231,7 +5230,6 @@ EXPORT_SYMBOL(ufshcd_shutdown); | |||
| 5231 | void ufshcd_remove(struct ufs_hba *hba) | 5230 | void ufshcd_remove(struct ufs_hba *hba) |
| 5232 | { | 5231 | { |
| 5233 | scsi_remove_host(hba->host); | 5232 | scsi_remove_host(hba->host); |
| 5234 | ufshcd_scsi_remove_wlus(hba); | ||
| 5235 | /* disable interrupts */ | 5233 | /* disable interrupts */ |
| 5236 | ufshcd_disable_intr(hba, hba->intr_mask); | 5234 | ufshcd_disable_intr(hba, hba->intr_mask); |
| 5237 | ufshcd_hba_stop(hba); | 5235 | ufshcd_hba_stop(hba); |
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 58ecdff5065c..4a574aa45855 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h | |||
| @@ -392,8 +392,6 @@ struct ufs_hba { | |||
| 392 | * "UFS device" W-LU. | 392 | * "UFS device" W-LU. |
| 393 | */ | 393 | */ |
| 394 | struct scsi_device *sdev_ufs_device; | 394 | struct scsi_device *sdev_ufs_device; |
| 395 | struct scsi_device *sdev_rpmb; | ||
| 396 | struct scsi_device *sdev_boot; | ||
| 397 | 395 | ||
| 398 | enum ufs_dev_pwr_mode curr_dev_pwr_mode; | 396 | enum ufs_dev_pwr_mode curr_dev_pwr_mode; |
| 399 | enum uic_link_state uic_link_state; | 397 | enum uic_link_state uic_link_state; |
