diff options
-rw-r--r-- | drivers/scsi/cxlflash/common.h | 2 | ||||
-rw-r--r-- | drivers/scsi/cxlflash/main.c | 27 |
2 files changed, 26 insertions, 3 deletions
diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index c11cd193f896..5ada9268a450 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h | |||
@@ -165,6 +165,8 @@ struct afu { | |||
165 | struct sisl_host_map __iomem *host_map; /* MC host map */ | 165 | struct sisl_host_map __iomem *host_map; /* MC host map */ |
166 | struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ | 166 | struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ |
167 | 167 | ||
168 | struct kref mapcount; | ||
169 | |||
168 | ctx_hndl_t ctx_hndl; /* master's context handle */ | 170 | ctx_hndl_t ctx_hndl; /* master's context handle */ |
169 | u64 *hrrq_start; | 171 | u64 *hrrq_start; |
170 | u64 *hrrq_end; | 172 | u64 *hrrq_end; |
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index ac39856a74b4..30542ca9415b 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c | |||
@@ -368,6 +368,7 @@ out: | |||
368 | 368 | ||
369 | no_room: | 369 | no_room: |
370 | afu->read_room = true; | 370 | afu->read_room = true; |
371 | kref_get(&cfg->afu->mapcount); | ||
371 | schedule_work(&cfg->work_q); | 372 | schedule_work(&cfg->work_q); |
372 | rc = SCSI_MLQUEUE_HOST_BUSY; | 373 | rc = SCSI_MLQUEUE_HOST_BUSY; |
373 | goto out; | 374 | goto out; |
@@ -473,6 +474,16 @@ out: | |||
473 | return rc; | 474 | return rc; |
474 | } | 475 | } |
475 | 476 | ||
477 | static void afu_unmap(struct kref *ref) | ||
478 | { | ||
479 | struct afu *afu = container_of(ref, struct afu, mapcount); | ||
480 | |||
481 | if (likely(afu->afu_map)) { | ||
482 | cxl_psa_unmap((void __iomem *)afu->afu_map); | ||
483 | afu->afu_map = NULL; | ||
484 | } | ||
485 | } | ||
486 | |||
476 | /** | 487 | /** |
477 | * cxlflash_driver_info() - information handler for this host driver | 488 | * cxlflash_driver_info() - information handler for this host driver |
478 | * @host: SCSI host associated with device. | 489 | * @host: SCSI host associated with device. |
@@ -503,6 +514,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) | |||
503 | ulong lock_flags; | 514 | ulong lock_flags; |
504 | short lflag = 0; | 515 | short lflag = 0; |
505 | int rc = 0; | 516 | int rc = 0; |
517 | int kref_got = 0; | ||
506 | 518 | ||
507 | dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu " | 519 | dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu " |
508 | "cdb=(%08X-%08X-%08X-%08X)\n", | 520 | "cdb=(%08X-%08X-%08X-%08X)\n", |
@@ -547,6 +559,9 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) | |||
547 | goto out; | 559 | goto out; |
548 | } | 560 | } |
549 | 561 | ||
562 | kref_get(&cfg->afu->mapcount); | ||
563 | kref_got = 1; | ||
564 | |||
550 | cmd->rcb.ctx_id = afu->ctx_hndl; | 565 | cmd->rcb.ctx_id = afu->ctx_hndl; |
551 | cmd->rcb.port_sel = port_sel; | 566 | cmd->rcb.port_sel = port_sel; |
552 | cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); | 567 | cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); |
@@ -587,6 +602,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) | |||
587 | } | 602 | } |
588 | 603 | ||
589 | out: | 604 | out: |
605 | if (kref_got) | ||
606 | kref_put(&afu->mapcount, afu_unmap); | ||
590 | pr_devel("%s: returning rc=%d\n", __func__, rc); | 607 | pr_devel("%s: returning rc=%d\n", __func__, rc); |
591 | return rc; | 608 | return rc; |
592 | } | 609 | } |
@@ -661,6 +678,7 @@ static void stop_afu(struct cxlflash_cfg *cfg) | |||
661 | cxl_psa_unmap((void __iomem *)afu->afu_map); | 678 | cxl_psa_unmap((void __iomem *)afu->afu_map); |
662 | afu->afu_map = NULL; | 679 | afu->afu_map = NULL; |
663 | } | 680 | } |
681 | kref_put(&afu->mapcount, afu_unmap); | ||
664 | } | 682 | } |
665 | } | 683 | } |
666 | 684 | ||
@@ -746,8 +764,8 @@ static void cxlflash_remove(struct pci_dev *pdev) | |||
746 | scsi_remove_host(cfg->host); | 764 | scsi_remove_host(cfg->host); |
747 | /* fall through */ | 765 | /* fall through */ |
748 | case INIT_STATE_AFU: | 766 | case INIT_STATE_AFU: |
749 | term_afu(cfg); | ||
750 | cancel_work_sync(&cfg->work_q); | 767 | cancel_work_sync(&cfg->work_q); |
768 | term_afu(cfg); | ||
751 | case INIT_STATE_PCI: | 769 | case INIT_STATE_PCI: |
752 | pci_release_regions(cfg->dev); | 770 | pci_release_regions(cfg->dev); |
753 | pci_disable_device(pdev); | 771 | pci_disable_device(pdev); |
@@ -1331,6 +1349,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) | |||
1331 | __func__, port); | 1349 | __func__, port); |
1332 | cfg->lr_state = LINK_RESET_REQUIRED; | 1350 | cfg->lr_state = LINK_RESET_REQUIRED; |
1333 | cfg->lr_port = port; | 1351 | cfg->lr_port = port; |
1352 | kref_get(&cfg->afu->mapcount); | ||
1334 | schedule_work(&cfg->work_q); | 1353 | schedule_work(&cfg->work_q); |
1335 | } | 1354 | } |
1336 | 1355 | ||
@@ -1351,6 +1370,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) | |||
1351 | 1370 | ||
1352 | if (info->action & SCAN_HOST) { | 1371 | if (info->action & SCAN_HOST) { |
1353 | atomic_inc(&cfg->scan_host_needed); | 1372 | atomic_inc(&cfg->scan_host_needed); |
1373 | kref_get(&cfg->afu->mapcount); | ||
1354 | schedule_work(&cfg->work_q); | 1374 | schedule_work(&cfg->work_q); |
1355 | } | 1375 | } |
1356 | } | 1376 | } |
@@ -1746,6 +1766,7 @@ static int init_afu(struct cxlflash_cfg *cfg) | |||
1746 | rc = -ENOMEM; | 1766 | rc = -ENOMEM; |
1747 | goto err1; | 1767 | goto err1; |
1748 | } | 1768 | } |
1769 | kref_init(&afu->mapcount); | ||
1749 | 1770 | ||
1750 | /* No byte reverse on reading afu_version or string will be backwards */ | 1771 | /* No byte reverse on reading afu_version or string will be backwards */ |
1751 | reg = readq(&afu->afu_map->global.regs.afu_version); | 1772 | reg = readq(&afu->afu_map->global.regs.afu_version); |
@@ -1780,8 +1801,7 @@ out: | |||
1780 | return rc; | 1801 | return rc; |
1781 | 1802 | ||
1782 | err2: | 1803 | err2: |
1783 | cxl_psa_unmap((void __iomem *)afu->afu_map); | 1804 | kref_put(&afu->mapcount, afu_unmap); |
1784 | afu->afu_map = NULL; | ||
1785 | err1: | 1805 | err1: |
1786 | term_mc(cfg, UNDO_START); | 1806 | term_mc(cfg, UNDO_START); |
1787 | goto out; | 1807 | goto out; |
@@ -2354,6 +2374,7 @@ static void cxlflash_worker_thread(struct work_struct *work) | |||
2354 | 2374 | ||
2355 | if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0) | 2375 | if (atomic_dec_if_positive(&cfg->scan_host_needed) >= 0) |
2356 | scsi_scan_host(cfg->host); | 2376 | scsi_scan_host(cfg->host); |
2377 | kref_put(&afu->mapcount, afu_unmap); | ||
2357 | } | 2378 | } |
2358 | 2379 | ||
2359 | /** | 2380 | /** |