scsi: ibmvfc: Map/request irq and register Sub-CRQ interrupt handler
authorTyrel Datwyler <tyreld@linux.ibm.com>
Thu, 14 Jan 2021 20:31:38 +0000 (14:31 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 15 Jan 2021 03:27:44 +0000 (22:27 -0500)
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.

Link: https://lore.kernel.org/r/20210114203148.246656-12-tyreld@linux.ibm.com
Reviewed-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ibmvscsi/ibmvfc.c

index 6e1910b..c54e488 100644 (file)
@@ -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);