diff options
Diffstat (limited to 'drivers/scsi/cxlflash/superpipe.c')
-rw-r--r-- | drivers/scsi/cxlflash/superpipe.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index fe9f17a6268b..ed46e8df2e42 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -57,6 +57,19 @@ static void marshal_det_to_rele(struct dk_cxlflash_detach *detach, } /** + * marshal_udir_to_rele() - translate udirect to release structure + * @udirect: Source structure from which to translate/copy. + * @release: Destination structure for the translate/copy. + */ +static void marshal_udir_to_rele(struct dk_cxlflash_udirect *udirect, + struct dk_cxlflash_release *release) +{ + release->hdr = udirect->hdr; + release->context_id = udirect->context_id; + release->rsrc_handle = udirect->rsrc_handle; +} + +/** * cxlflash_free_errpage() - frees resources associated with global error page */ void cxlflash_free_errpage(void) @@ -622,6 +635,7 @@ int _cxlflash_disk_release(struct scsi_device *sdev, res_hndl_t rhndl = release->rsrc_handle; int rc = 0; + int rcr = 0; u64 ctxid = DECODE_CTXID(release->context_id), rctxid = release->context_id; @@ -686,8 +700,12 @@ int _cxlflash_disk_release(struct scsi_device *sdev, rhte_f1->dw = 0; dma_wmb(); /* Make RHT entry bottom-half clearing visible */ - if (!ctxi->err_recovery_active) - cxlflash_afu_sync(afu, ctxid, rhndl, AFU_HW_SYNC); + if (!ctxi->err_recovery_active) { + rcr = cxlflash_afu_sync(afu, ctxid, rhndl, AFU_HW_SYNC); + if (unlikely(rcr)) + dev_dbg(dev, "%s: AFU sync failed rc=%d\n", + __func__, rcr); + } break; default: WARN(1, "Unsupported LUN mode!"); @@ -1372,6 +1390,7 @@ static int cxlflash_disk_attach(struct scsi_device *sdev, if (unlikely(!ctxi)) { dev_err(dev, "%s: Failed to create context ctxid=%d\n", __func__, ctxid); + rc = -ENOMEM; goto err; } @@ -1632,6 +1651,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev, u64 ctxid = DECODE_CTXID(recover->context_id), rctxid = recover->context_id; long reg; + bool locked = true; int lretry = 20; /* up to 2 seconds */ int new_adap_fd = -1; int rc = 0; @@ -1640,8 +1660,11 @@ static int cxlflash_afu_recover(struct scsi_device *sdev, up_read(&cfg->ioctl_rwsem); rc = mutex_lock_interruptible(mutex); down_read(&cfg->ioctl_rwsem); - if (rc) + if (rc) { + locked = false; goto out; + } + rc = check_state(cfg); if (rc) { dev_err(dev, "%s: Failed state rc=%d\n", __func__, rc); @@ -1675,8 +1698,10 @@ retry_recover: mutex_unlock(mutex); msleep(100); rc = mutex_lock_interruptible(mutex); - if (rc) + if (rc) { + locked = false; goto out; + } goto retry_recover; } @@ -1720,7 +1745,8 @@ retry_recover: out: if (likely(ctxi)) put_context(ctxi); - mutex_unlock(mutex); + if (locked) + mutex_unlock(mutex); atomic_dec_if_positive(&cfg->recovery_threads); return rc; } @@ -1929,6 +1955,7 @@ static int cxlflash_disk_direct_open(struct scsi_device *sdev, void *arg) struct afu *afu = cfg->afu; struct llun_info *lli = sdev->hostdata; struct glun_info *gli = lli->parent; + struct dk_cxlflash_release rel = { { 0 }, 0 }; struct dk_cxlflash_udirect *pphys = (struct dk_cxlflash_udirect *)arg; @@ -1970,13 +1997,18 @@ static int cxlflash_disk_direct_open(struct scsi_device *sdev, void *arg) rsrc_handle = (rhte - ctxi->rht_start); rht_format1(rhte, lli->lun_id[sdev->channel], ctxi->rht_perms, port); - cxlflash_afu_sync(afu, ctxid, rsrc_handle, AFU_LW_SYNC); last_lba = gli->max_lba; pphys->hdr.return_flags = 0; pphys->last_lba = last_lba; pphys->rsrc_handle = rsrc_handle; + rc = cxlflash_afu_sync(afu, ctxid, rsrc_handle, AFU_LW_SYNC); + if (unlikely(rc)) { + dev_dbg(dev, "%s: AFU sync failed rc=%d\n", __func__, rc); + goto err2; + } + out: if (likely(ctxi)) put_context(ctxi); @@ -1984,6 +2016,10 @@ out: __func__, rsrc_handle, rc, last_lba); return rc; +err2: + marshal_udir_to_rele(pphys, &rel); + _cxlflash_disk_release(sdev, ctxi, &rel); + goto out; err1: cxlflash_lun_detach(gli); goto out; |