Create an irq mapping for the hw_irq number provided from phyp firmware.
Request an irq assigned our Sub-CRQ interrupt handler. Unmap these irqs
at Sub-CRQ teardown.

Signed-off-by: Tyrel Datwyler <tyr...@linux.ibm.com>
Reviewed-by: Brian King <brk...@linux.vnet.ibm.com>
---
 drivers/scsi/ibmvscsi/ibmvfc.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 51bcafad9490..d3d7c6b53d4f 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -5292,12 +5292,34 @@ static int ibmvfc_register_scsi_channel(struct 
ibmvfc_host *vhost,
                goto reg_failed;
        }
 
+       scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
+
+       if (!scrq->irq) {
+               rc = -EINVAL;
+               dev_err(dev, "Error mapping sub-crq[%d] irq\n", index);
+               goto irq_failed;
+       }
+
+       snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-scsi%d",
+                vdev->unit_address, index);
+       rc = request_irq(scrq->irq, ibmvfc_interrupt_scsi, 0, scrq->name, scrq);
+
+       if (rc) {
+               dev_err(dev, "Couldn't register sub-crq[%d] irq\n", index);
+               irq_dispose_mapping(scrq->irq);
+               goto irq_failed;
+       }
+
        scrq->hwq_id = index;
        scrq->vhost = vhost;
 
        LEAVE;
        return 0;
 
+irq_failed:
+       do {
+               plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, 
scrq->cookie);
+       } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
 reg_failed:
        ibmvfc_free_queue(vhost, scrq);
        LEAVE;
@@ -5313,6 +5335,9 @@ static void ibmvfc_deregister_scsi_channel(struct 
ibmvfc_host *vhost, int index)
 
        ENTER;
 
+       free_irq(scrq->irq, scrq);
+       irq_dispose_mapping(scrq->irq);
+
        do {
                rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address,
                                        scrq->cookie);
-- 
2.27.0

Reply via email to