]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/pm8001/pm8001_init.c
Merge tag 'for-linus-4.4-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / drivers / scsi / pm8001 / pm8001_init.c
index 7ce7ea3d01619fb432d91dd071e732dd71930446..062ab34b86f8bcab08d24b8cfe1e4dffa938939d 100644 (file)
@@ -90,7 +90,6 @@ static struct scsi_host_template pm8001_sht = {
        .target_destroy         = sas_target_destroy,
        .ioctl                  = sas_ioctl,
        .shost_attrs            = pm8001_host_attrs,
-       .use_blk_tags           = 1,
        .track_queue_depth      = 1,
 };
 
@@ -482,7 +481,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
 
 #ifdef PM8001_USE_TASKLET
        /* Tasklet for non msi-x interrupt handler */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled())
+           || (pm8001_ha->chip_id == chip_8001))
                tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
                        (unsigned long)&(pm8001_ha->irq_vector[0]));
        else
@@ -951,7 +951,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
        pdev = pm8001_ha->pdev;
 
 #ifdef PM8001_USE_MSIX
-       if (pdev->msix_cap)
+       if (pdev->msix_cap && pci_msi_enabled())
                return pm8001_setup_msix(pm8001_ha);
        else {
                PM8001_INIT_DBG(pm8001_ha,
@@ -962,6 +962,8 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
 
 intx:
        /* initialize the INT-X interrupt */
+       pm8001_ha->irq_vector[0].irq_id = 0;
+       pm8001_ha->irq_vector[0].drv_inst = pm8001_ha;
        rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED,
                DRV_NAME, SHOST_TO_SAS_HA(pm8001_ha->shost));
        return rc;
@@ -1093,10 +1095,10 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
        struct pm8001_hba_info *pm8001_ha;
        int i, j;
        pm8001_ha = sha->lldd_ha;
+       scsi_remove_host(pm8001_ha->shost);
        sas_unregister_ha(sha);
        sas_remove_host(pm8001_ha->shost);
        list_del(&pm8001_ha->list);
-       scsi_remove_host(pm8001_ha->shost);
        PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);
        PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
 
@@ -1112,7 +1114,8 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
 #endif
 #ifdef PM8001_USE_TASKLET
        /* For non-msix and msix interrupts */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled()) ||
+           (pm8001_ha->chip_id == chip_8001))
                tasklet_kill(&pm8001_ha->tasklet[0]);
        else
                for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
@@ -1161,7 +1164,8 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 #endif
 #ifdef PM8001_USE_TASKLET
        /* For non-msix and msix interrupts */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled()) ||
+           (pm8001_ha->chip_id == chip_8001))
                tasklet_kill(&pm8001_ha->tasklet[0]);
        else
                for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
@@ -1230,7 +1234,8 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
                goto err_out_disable;
 #ifdef PM8001_USE_TASKLET
        /*  Tasklet for non msi-x interrupt handler */
-       if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
+       if ((!pdev->msix_cap || !pci_msi_enabled()) ||
+           (pm8001_ha->chip_id == chip_8001))
                tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
                        (unsigned long)&(pm8001_ha->irq_vector[0]));
        else
@@ -1243,6 +1248,19 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
                for (i = 1; i < pm8001_ha->number_of_intr; i++)
                        PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
        }
+
+       /* Chip documentation for the 8070 and 8072 SPCv    */
+       /* states that a 500ms minimum delay is required    */
+       /* before issuing commands.  Otherwise, the firmare */
+       /* will enter an unrecoverable state.               */
+
+       if (pm8001_ha->chip_id == chip_8070 ||
+               pm8001_ha->chip_id == chip_8072) {
+               mdelay(500);
+       }
+
+       /* Spin up the PHYs */
+
        pm8001_ha->flags = PM8001F_RUN_TIME;
        for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
                pm8001_ha->phy[i].enable_completion = &completion;