]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
scsi: hisi_sas: us start_phy in PHY_FUNC_LINK_RESET
[mirror_ubuntu-bionic-kernel.git] / drivers / scsi / hisi_sas / hisi_sas_v3_hw.c
index 3620a3e60a63d338d1bf01850a230227f31aaea6..67ebd8f6f84af018e33f3357a3f737af5cde5763 100644 (file)
 #define DMA_RX_STATUS_BUSY_OFF         0
 #define DMA_RX_STATUS_BUSY_MSK         (0x1 << DMA_RX_STATUS_BUSY_OFF)
 
-#define MAX_ITCT_HW                    4096 /* max the hw can support */
 #define DEFAULT_ITCT_HW                2048 /* reset value, not reprogrammed */
 #if (HISI_SAS_MAX_DEVICES > DEFAULT_ITCT_HW)
 #error Max ITCT exceeded
@@ -377,6 +376,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
        /* Global registers init */
        hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE,
                         (u32)((1ULL << hisi_hba->queue_count) - 1));
+       hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400);
        hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108);
        hisi_sas_write32(hisi_hba, CFG_1US_TIMER_TRSH, 0xd);
        hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
@@ -988,20 +988,6 @@ err_out_req:
        return rc;
 }
 
-static int get_ncq_tag_v3_hw(struct sas_task *task, u32 *tag)
-{
-       struct ata_queued_cmd *qc = task->uldd_task;
-
-       if (qc) {
-               if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-                       qc->tf.command == ATA_CMD_FPDMA_READ) {
-                       *tag = qc->tag;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
 static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
                          struct hisi_sas_slot *slot)
 {
@@ -1050,7 +1036,7 @@ static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
        hdr->dw1 = cpu_to_le32(dw1);
 
        /* dw2 */
-       if (task->ata_task.use_ncq && get_ncq_tag_v3_hw(task, &hdr_tag)) {
+       if (task->ata_task.use_ncq && hisi_sas_get_ncq_tag(task, &hdr_tag)) {
                task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
                dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF;
        }
@@ -1414,7 +1400,9 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
        ts->resp = SAS_TASK_COMPLETE;
        if (unlikely(aborted)) {
                ts->stat = SAS_ABORTED_TASK;
+               spin_lock_irqsave(&hisi_hba->lock, flags);
                hisi_sas_slot_task_free(hisi_hba, task, slot);
+               spin_unlock_irqrestore(&hisi_hba->lock, flags);
                return -1;
        }
 
@@ -1793,7 +1781,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
        .start_delivery = start_delivery_v3_hw,
        .slot_complete = slot_complete_v3_hw,
        .phys_init = phys_init_v3_hw,
-       .phy_enable = enable_phy_v3_hw,
+       .phy_start = start_phy_v3_hw,
        .phy_disable = disable_phy_v3_hw,
        .phy_hard_reset = phy_hard_reset_v3_hw,
        .phy_get_max_linkrate = phy_get_max_linkrate_v3_hw,
@@ -1811,8 +1799,10 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
        struct device *dev = &pdev->dev;
 
        shost = scsi_host_alloc(hisi_sas_sht, sizeof(*hisi_hba));
-       if (!shost)
-               goto err_out;
+       if (!shost) {
+               dev_err(dev, "shost alloc failed\n");
+               return NULL;
+       }
        hisi_hba = shost_priv(shost);
 
        hisi_hba->hw = &hisi_sas_v3_hw;
@@ -1833,6 +1823,7 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
 
        return shost;
 err_out:
+       scsi_host_put(shost);
        dev_err(dev, "shost alloc failed\n");
        return NULL;
 }
@@ -1941,7 +1932,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 err_out_register_ha:
        scsi_remove_host(shost);
 err_out_ha:
-       kfree(shost);
+       scsi_host_put(shost);
 err_out_regions:
        pci_release_regions(pdev);
 err_out_disable_device:
@@ -1971,14 +1962,16 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
        struct device *dev = &pdev->dev;
        struct sas_ha_struct *sha = dev_get_drvdata(dev);
        struct hisi_hba *hisi_hba = sha->lldd_ha;
+       struct Scsi_Host *shost = sha->core.shost;
 
        sas_unregister_ha(sha);
        sas_remove_host(sha->core.shost);
 
-       hisi_sas_free(hisi_hba);
        hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
+       hisi_sas_free(hisi_hba);
+       scsi_host_put(shost);
 }
 
 enum {
@@ -2000,7 +1993,6 @@ static struct pci_driver sas_v3_pci_driver = {
 
 module_pci_driver(sas_v3_pci_driver);
 
-MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
 MODULE_DESCRIPTION("HISILICON SAS controller v3 hw driver based on pci device");