diff options
Diffstat (limited to 'drivers/scsi/pm8001')
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.h | 4 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_init.c | 91 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.h | 9 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.h | 2 |
7 files changed, 72 insertions, 42 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index f16ece91b94a..0a1296a87d66 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
| @@ -3403,6 +3403,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 3403 | unsigned long flags; | 3403 | unsigned long flags; |
| 3404 | u8 deviceType = pPayload->sas_identify.dev_type; | 3404 | u8 deviceType = pPayload->sas_identify.dev_type; |
| 3405 | port->port_state = portstate; | 3405 | port->port_state = portstate; |
| 3406 | phy->phy_state = PHY_STATE_LINK_UP_SPC; | ||
| 3406 | PM8001_MSG_DBG(pm8001_ha, | 3407 | PM8001_MSG_DBG(pm8001_ha, |
| 3407 | pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", | 3408 | pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", |
| 3408 | port_id, phy_id)); | 3409 | port_id, phy_id)); |
| @@ -3483,6 +3484,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 3483 | pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," | 3484 | pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," |
| 3484 | " phy id = %d\n", port_id, phy_id)); | 3485 | " phy id = %d\n", port_id, phy_id)); |
| 3485 | port->port_state = portstate; | 3486 | port->port_state = portstate; |
| 3487 | phy->phy_state = PHY_STATE_LINK_UP_SPC; | ||
| 3486 | port->port_attached = 1; | 3488 | port->port_attached = 1; |
| 3487 | pm8001_get_lrate_mode(phy, link_rate); | 3489 | pm8001_get_lrate_mode(phy, link_rate); |
| 3488 | phy->phy_type |= PORT_TYPE_SATA; | 3490 | phy->phy_type |= PORT_TYPE_SATA; |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 6d91e2446542..e4867e690c84 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h | |||
| @@ -131,6 +131,10 @@ | |||
| 131 | #define LINKRATE_30 (0x02 << 8) | 131 | #define LINKRATE_30 (0x02 << 8) |
| 132 | #define LINKRATE_60 (0x04 << 8) | 132 | #define LINKRATE_60 (0x04 << 8) |
| 133 | 133 | ||
| 134 | /* for phy state */ | ||
| 135 | |||
| 136 | #define PHY_STATE_LINK_UP_SPC 0x1 | ||
| 137 | |||
| 134 | /* for new SPC controllers MEMBASE III is shared between BIOS and DATA */ | 138 | /* for new SPC controllers MEMBASE III is shared between BIOS and DATA */ |
| 135 | #define GSM_SM_BASE 0x4F0000 | 139 | #define GSM_SM_BASE 0x4F0000 |
| 136 | struct mpi_msg_hdr{ | 140 | struct mpi_msg_hdr{ |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 34f5f5ffef05..73a120d81b4d 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
| @@ -175,20 +175,16 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha) | |||
| 175 | static void pm8001_tasklet(unsigned long opaque) | 175 | static void pm8001_tasklet(unsigned long opaque) |
| 176 | { | 176 | { |
| 177 | struct pm8001_hba_info *pm8001_ha; | 177 | struct pm8001_hba_info *pm8001_ha; |
| 178 | u32 vec; | 178 | struct isr_param *irq_vector; |
| 179 | pm8001_ha = (struct pm8001_hba_info *)opaque; | 179 | |
| 180 | irq_vector = (struct isr_param *)opaque; | ||
| 181 | pm8001_ha = irq_vector->drv_inst; | ||
| 180 | if (unlikely(!pm8001_ha)) | 182 | if (unlikely(!pm8001_ha)) |
| 181 | BUG_ON(1); | 183 | BUG_ON(1); |
| 182 | vec = pm8001_ha->int_vector; | 184 | PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id); |
| 183 | PM8001_CHIP_DISP->isr(pm8001_ha, vec); | ||
| 184 | } | 185 | } |
| 185 | #endif | 186 | #endif |
| 186 | 187 | ||
| 187 | static struct pm8001_hba_info *outq_to_hba(u8 *outq) | ||
| 188 | { | ||
| 189 | return container_of((outq - *outq), struct pm8001_hba_info, outq[0]); | ||
| 190 | } | ||
| 191 | |||
| 192 | /** | 188 | /** |
| 193 | * pm8001_interrupt_handler_msix - main MSIX interrupt handler. | 189 | * pm8001_interrupt_handler_msix - main MSIX interrupt handler. |
| 194 | * It obtains the vector number and calls the equivalent bottom | 190 | * It obtains the vector number and calls the equivalent bottom |
| @@ -198,18 +194,20 @@ static struct pm8001_hba_info *outq_to_hba(u8 *outq) | |||
| 198 | */ | 194 | */ |
| 199 | static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque) | 195 | static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque) |
| 200 | { | 196 | { |
| 201 | struct pm8001_hba_info *pm8001_ha = outq_to_hba(opaque); | 197 | struct isr_param *irq_vector; |
| 202 | u8 outq = *(u8 *)opaque; | 198 | struct pm8001_hba_info *pm8001_ha; |
| 203 | irqreturn_t ret = IRQ_HANDLED; | 199 | irqreturn_t ret = IRQ_HANDLED; |
| 200 | irq_vector = (struct isr_param *)opaque; | ||
| 201 | pm8001_ha = irq_vector->drv_inst; | ||
| 202 | |||
| 204 | if (unlikely(!pm8001_ha)) | 203 | if (unlikely(!pm8001_ha)) |
| 205 | return IRQ_NONE; | 204 | return IRQ_NONE; |
| 206 | if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) | 205 | if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) |
| 207 | return IRQ_NONE; | 206 | return IRQ_NONE; |
| 208 | pm8001_ha->int_vector = outq; | ||
| 209 | #ifdef PM8001_USE_TASKLET | 207 | #ifdef PM8001_USE_TASKLET |
| 210 | tasklet_schedule(&pm8001_ha->tasklet); | 208 | tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]); |
| 211 | #else | 209 | #else |
| 212 | ret = PM8001_CHIP_DISP->isr(pm8001_ha, outq); | 210 | ret = PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id); |
| 213 | #endif | 211 | #endif |
| 214 | return ret; | 212 | return ret; |
| 215 | } | 213 | } |
| @@ -230,9 +228,8 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) | |||
| 230 | if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) | 228 | if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) |
| 231 | return IRQ_NONE; | 229 | return IRQ_NONE; |
| 232 | 230 | ||
| 233 | pm8001_ha->int_vector = 0; | ||
| 234 | #ifdef PM8001_USE_TASKLET | 231 | #ifdef PM8001_USE_TASKLET |
| 235 | tasklet_schedule(&pm8001_ha->tasklet); | 232 | tasklet_schedule(&pm8001_ha->tasklet[0]); |
| 236 | #else | 233 | #else |
| 237 | ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0); | 234 | ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0); |
| 238 | #endif | 235 | #endif |
| @@ -457,7 +454,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, | |||
| 457 | { | 454 | { |
| 458 | struct pm8001_hba_info *pm8001_ha; | 455 | struct pm8001_hba_info *pm8001_ha; |
| 459 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); | 456 | struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); |
| 460 | 457 | int j; | |
| 461 | 458 | ||
| 462 | pm8001_ha = sha->lldd_ha; | 459 | pm8001_ha = sha->lldd_ha; |
| 463 | if (!pm8001_ha) | 460 | if (!pm8001_ha) |
| @@ -480,12 +477,14 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, | |||
| 480 | pm8001_ha->iomb_size = IOMB_SIZE_SPC; | 477 | pm8001_ha->iomb_size = IOMB_SIZE_SPC; |
| 481 | 478 | ||
| 482 | #ifdef PM8001_USE_TASKLET | 479 | #ifdef PM8001_USE_TASKLET |
| 483 | /** | 480 | /* Tasklet for non msi-x interrupt handler */ |
| 484 | * default tasklet for non msi-x interrupt handler/first msi-x | 481 | if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) |
| 485 | * interrupt handler | 482 | tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet, |
| 486 | **/ | 483 | (unsigned long)&(pm8001_ha->irq_vector[0])); |
| 487 | tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet, | 484 | else |
| 488 | (unsigned long)pm8001_ha); | 485 | for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) |
| 486 | tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet, | ||
| 487 | (unsigned long)&(pm8001_ha->irq_vector[j])); | ||
| 489 | #endif | 488 | #endif |
| 490 | pm8001_ioremap(pm8001_ha); | 489 | pm8001_ioremap(pm8001_ha); |
| 491 | if (!pm8001_alloc(pm8001_ha, ent)) | 490 | if (!pm8001_alloc(pm8001_ha, ent)) |
| @@ -733,19 +732,20 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) | |||
| 733 | "pci_enable_msix request ret:%d no of intr %d\n", | 732 | "pci_enable_msix request ret:%d no of intr %d\n", |
| 734 | rc, pm8001_ha->number_of_intr)); | 733 | rc, pm8001_ha->number_of_intr)); |
| 735 | 734 | ||
| 736 | for (i = 0; i < number_of_intr; i++) | ||
| 737 | pm8001_ha->outq[i] = i; | ||
| 738 | 735 | ||
| 739 | for (i = 0; i < number_of_intr; i++) { | 736 | for (i = 0; i < number_of_intr; i++) { |
| 740 | snprintf(intr_drvname[i], sizeof(intr_drvname[0]), | 737 | snprintf(intr_drvname[i], sizeof(intr_drvname[0]), |
| 741 | DRV_NAME"%d", i); | 738 | DRV_NAME"%d", i); |
| 739 | pm8001_ha->irq_vector[i].irq_id = i; | ||
| 740 | pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; | ||
| 741 | |||
| 742 | if (request_irq(pm8001_ha->msix_entries[i].vector, | 742 | if (request_irq(pm8001_ha->msix_entries[i].vector, |
| 743 | pm8001_interrupt_handler_msix, flag, | 743 | pm8001_interrupt_handler_msix, flag, |
| 744 | intr_drvname[i], &pm8001_ha->outq[i])) { | 744 | intr_drvname[i], &(pm8001_ha->irq_vector[i]))) { |
| 745 | for (j = 0; j < i; j++) | 745 | for (j = 0; j < i; j++) |
| 746 | free_irq( | 746 | free_irq( |
| 747 | pm8001_ha->msix_entries[j].vector, | 747 | pm8001_ha->msix_entries[j].vector, |
| 748 | &pm8001_ha->outq[j]); | 748 | &(pm8001_ha->irq_vector[i])); |
| 749 | pci_disable_msix(pm8001_ha->pdev); | 749 | pci_disable_msix(pm8001_ha->pdev); |
| 750 | break; | 750 | break; |
| 751 | } | 751 | } |
| @@ -907,7 +907,7 @@ static void pm8001_pci_remove(struct pci_dev *pdev) | |||
| 907 | { | 907 | { |
| 908 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); | 908 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
| 909 | struct pm8001_hba_info *pm8001_ha; | 909 | struct pm8001_hba_info *pm8001_ha; |
| 910 | int i; | 910 | int i, j; |
| 911 | pm8001_ha = sha->lldd_ha; | 911 | pm8001_ha = sha->lldd_ha; |
| 912 | sas_unregister_ha(sha); | 912 | sas_unregister_ha(sha); |
| 913 | sas_remove_host(pm8001_ha->shost); | 913 | sas_remove_host(pm8001_ha->shost); |
| @@ -921,13 +921,18 @@ static void pm8001_pci_remove(struct pci_dev *pdev) | |||
| 921 | synchronize_irq(pm8001_ha->msix_entries[i].vector); | 921 | synchronize_irq(pm8001_ha->msix_entries[i].vector); |
| 922 | for (i = 0; i < pm8001_ha->number_of_intr; i++) | 922 | for (i = 0; i < pm8001_ha->number_of_intr; i++) |
| 923 | free_irq(pm8001_ha->msix_entries[i].vector, | 923 | free_irq(pm8001_ha->msix_entries[i].vector, |
| 924 | &pm8001_ha->outq[i]); | 924 | &(pm8001_ha->irq_vector[i])); |
| 925 | pci_disable_msix(pdev); | 925 | pci_disable_msix(pdev); |
| 926 | #else | 926 | #else |
| 927 | free_irq(pm8001_ha->irq, sha); | 927 | free_irq(pm8001_ha->irq, sha); |
| 928 | #endif | 928 | #endif |
| 929 | #ifdef PM8001_USE_TASKLET | 929 | #ifdef PM8001_USE_TASKLET |
| 930 | tasklet_kill(&pm8001_ha->tasklet); | 930 | /* For non-msix and msix interrupts */ |
| 931 | if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) | ||
| 932 | tasklet_kill(&pm8001_ha->tasklet[0]); | ||
| 933 | else | ||
| 934 | for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) | ||
| 935 | tasklet_kill(&pm8001_ha->tasklet[j]); | ||
| 931 | #endif | 936 | #endif |
| 932 | pm8001_free(pm8001_ha); | 937 | pm8001_free(pm8001_ha); |
| 933 | kfree(sha->sas_phy); | 938 | kfree(sha->sas_phy); |
| @@ -948,7 +953,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 948 | { | 953 | { |
| 949 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); | 954 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
| 950 | struct pm8001_hba_info *pm8001_ha; | 955 | struct pm8001_hba_info *pm8001_ha; |
| 951 | int i; | 956 | int i, j; |
| 952 | u32 device_state; | 957 | u32 device_state; |
| 953 | pm8001_ha = sha->lldd_ha; | 958 | pm8001_ha = sha->lldd_ha; |
| 954 | flush_workqueue(pm8001_wq); | 959 | flush_workqueue(pm8001_wq); |
| @@ -964,13 +969,18 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 964 | synchronize_irq(pm8001_ha->msix_entries[i].vector); | 969 | synchronize_irq(pm8001_ha->msix_entries[i].vector); |
| 965 | for (i = 0; i < pm8001_ha->number_of_intr; i++) | 970 | for (i = 0; i < pm8001_ha->number_of_intr; i++) |
| 966 | free_irq(pm8001_ha->msix_entries[i].vector, | 971 | free_irq(pm8001_ha->msix_entries[i].vector, |
| 967 | &pm8001_ha->outq[i]); | 972 | &(pm8001_ha->irq_vector[i])); |
| 968 | pci_disable_msix(pdev); | 973 | pci_disable_msix(pdev); |
| 969 | #else | 974 | #else |
| 970 | free_irq(pm8001_ha->irq, sha); | 975 | free_irq(pm8001_ha->irq, sha); |
| 971 | #endif | 976 | #endif |
| 972 | #ifdef PM8001_USE_TASKLET | 977 | #ifdef PM8001_USE_TASKLET |
| 973 | tasklet_kill(&pm8001_ha->tasklet); | 978 | /* For non-msix and msix interrupts */ |
| 979 | if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) | ||
| 980 | tasklet_kill(&pm8001_ha->tasklet[0]); | ||
| 981 | else | ||
| 982 | for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) | ||
| 983 | tasklet_kill(&pm8001_ha->tasklet[j]); | ||
| 974 | #endif | 984 | #endif |
| 975 | device_state = pci_choose_state(pdev, state); | 985 | device_state = pci_choose_state(pdev, state); |
| 976 | pm8001_printk("pdev=0x%p, slot=%s, entering " | 986 | pm8001_printk("pdev=0x%p, slot=%s, entering " |
| @@ -993,7 +1003,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev) | |||
| 993 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); | 1003 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
| 994 | struct pm8001_hba_info *pm8001_ha; | 1004 | struct pm8001_hba_info *pm8001_ha; |
| 995 | int rc; | 1005 | int rc; |
| 996 | u8 i = 0; | 1006 | u8 i = 0, j; |
| 997 | u32 device_state; | 1007 | u32 device_state; |
| 998 | pm8001_ha = sha->lldd_ha; | 1008 | pm8001_ha = sha->lldd_ha; |
| 999 | device_state = pdev->current_state; | 1009 | device_state = pdev->current_state; |
| @@ -1033,10 +1043,14 @@ static int pm8001_pci_resume(struct pci_dev *pdev) | |||
| 1033 | if (rc) | 1043 | if (rc) |
| 1034 | goto err_out_disable; | 1044 | goto err_out_disable; |
| 1035 | #ifdef PM8001_USE_TASKLET | 1045 | #ifdef PM8001_USE_TASKLET |
| 1036 | /* default tasklet for non msi-x interrupt handler/first msi-x | 1046 | /* Tasklet for non msi-x interrupt handler */ |
| 1037 | * interrupt handler */ | 1047 | if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) |
| 1038 | tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet, | 1048 | tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet, |
| 1039 | (unsigned long)pm8001_ha); | 1049 | (unsigned long)&(pm8001_ha->irq_vector[0])); |
| 1050 | else | ||
| 1051 | for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) | ||
| 1052 | tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet, | ||
| 1053 | (unsigned long)&(pm8001_ha->irq_vector[j])); | ||
| 1040 | #endif | 1054 | #endif |
| 1041 | PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0); | 1055 | PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0); |
| 1042 | if (pm8001_ha->chip_id != chip_8001) { | 1056 | if (pm8001_ha->chip_id != chip_8001) { |
| @@ -1169,6 +1183,7 @@ module_exit(pm8001_exit); | |||
| 1169 | MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>"); | 1183 | MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>"); |
| 1170 | MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>"); | 1184 | MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>"); |
| 1171 | MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>"); | 1185 | MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>"); |
| 1186 | MODULE_AUTHOR("Nikith Ganigarakoppal <Nikith.Ganigarakoppal@pmcs.com>"); | ||
| 1172 | MODULE_DESCRIPTION( | 1187 | MODULE_DESCRIPTION( |
| 1173 | "PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 " | 1188 | "PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 " |
| 1174 | "SAS/SATA controller driver"); | 1189 | "SAS/SATA controller driver"); |
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index f4eb18e51631..f50ac44b950e 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c | |||
| @@ -1098,15 +1098,17 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) | |||
| 1098 | struct pm8001_tmf_task tmf_task; | 1098 | struct pm8001_tmf_task tmf_task; |
| 1099 | struct pm8001_device *pm8001_dev = dev->lldd_dev; | 1099 | struct pm8001_device *pm8001_dev = dev->lldd_dev; |
| 1100 | struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); | 1100 | struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev); |
| 1101 | DECLARE_COMPLETION_ONSTACK(completion_setstate); | ||
| 1101 | if (dev_is_sata(dev)) { | 1102 | if (dev_is_sata(dev)) { |
| 1102 | struct sas_phy *phy = sas_get_local_phy(dev); | 1103 | struct sas_phy *phy = sas_get_local_phy(dev); |
| 1103 | rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , | 1104 | rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , |
| 1104 | dev, 1, 0); | 1105 | dev, 1, 0); |
| 1105 | rc = sas_phy_reset(phy, 1); | 1106 | rc = sas_phy_reset(phy, 1); |
| 1106 | sas_put_local_phy(phy); | 1107 | sas_put_local_phy(phy); |
| 1108 | pm8001_dev->setds_completion = &completion_setstate; | ||
| 1107 | rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, | 1109 | rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, |
| 1108 | pm8001_dev, 0x01); | 1110 | pm8001_dev, 0x01); |
| 1109 | msleep(2000); | 1111 | wait_for_completion(&completion_setstate); |
| 1110 | } else { | 1112 | } else { |
| 1111 | tmf_task.tmf = TMF_LU_RESET; | 1113 | tmf_task.tmf = TMF_LU_RESET; |
| 1112 | rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task); | 1114 | rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task); |
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 6037d477a183..6c5fd5ee22d3 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h | |||
| @@ -466,6 +466,10 @@ struct pm8001_hba_memspace { | |||
| 466 | u64 membase; | 466 | u64 membase; |
| 467 | u32 memsize; | 467 | u32 memsize; |
| 468 | }; | 468 | }; |
| 469 | struct isr_param { | ||
| 470 | struct pm8001_hba_info *drv_inst; | ||
| 471 | u32 irq_id; | ||
| 472 | }; | ||
| 469 | struct pm8001_hba_info { | 473 | struct pm8001_hba_info { |
| 470 | char name[PM8001_NAME_LENGTH]; | 474 | char name[PM8001_NAME_LENGTH]; |
| 471 | struct list_head list; | 475 | struct list_head list; |
| @@ -519,14 +523,13 @@ struct pm8001_hba_info { | |||
| 519 | int number_of_intr;/*will be used in remove()*/ | 523 | int number_of_intr;/*will be used in remove()*/ |
| 520 | #endif | 524 | #endif |
| 521 | #ifdef PM8001_USE_TASKLET | 525 | #ifdef PM8001_USE_TASKLET |
| 522 | struct tasklet_struct tasklet; | 526 | struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC]; |
| 523 | #endif | 527 | #endif |
| 524 | u32 logging_level; | 528 | u32 logging_level; |
| 525 | u32 fw_status; | 529 | u32 fw_status; |
| 526 | u32 smp_exp_mode; | 530 | u32 smp_exp_mode; |
| 527 | u32 int_vector; | ||
| 528 | const struct firmware *fw_image; | 531 | const struct firmware *fw_image; |
| 529 | u8 outq[PM8001_MAX_MSIX_VEC]; | 532 | struct isr_param irq_vector[PM8001_MAX_MSIX_VEC]; |
| 530 | }; | 533 | }; |
| 531 | 534 | ||
| 532 | struct pm8001_work { | 535 | struct pm8001_work { |
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 8987b1706216..c950dc5c9943 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c | |||
| @@ -2894,6 +2894,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2894 | unsigned long flags; | 2894 | unsigned long flags; |
| 2895 | u8 deviceType = pPayload->sas_identify.dev_type; | 2895 | u8 deviceType = pPayload->sas_identify.dev_type; |
| 2896 | port->port_state = portstate; | 2896 | port->port_state = portstate; |
| 2897 | phy->phy_state = PHY_STATE_LINK_UP_SPCV; | ||
| 2897 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk( | 2898 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk( |
| 2898 | "portid:%d; phyid:%d; linkrate:%d; " | 2899 | "portid:%d; phyid:%d; linkrate:%d; " |
| 2899 | "portstate:%x; devicetype:%x\n", | 2900 | "portstate:%x; devicetype:%x\n", |
| @@ -2978,6 +2979,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2978 | port_id, phy_id, link_rate, portstate)); | 2979 | port_id, phy_id, link_rate, portstate)); |
| 2979 | 2980 | ||
| 2980 | port->port_state = portstate; | 2981 | port->port_state = portstate; |
| 2982 | phy->phy_state = PHY_STATE_LINK_UP_SPCV; | ||
| 2981 | port->port_attached = 1; | 2983 | port->port_attached = 1; |
| 2982 | pm8001_get_lrate_mode(phy, link_rate); | 2984 | pm8001_get_lrate_mode(phy, link_rate); |
| 2983 | phy->phy_type |= PORT_TYPE_SATA; | 2985 | phy->phy_type |= PORT_TYPE_SATA; |
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h index c86816bea424..9970a385795d 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.h +++ b/drivers/scsi/pm8001/pm80xx_hwi.h | |||
| @@ -215,6 +215,8 @@ | |||
| 215 | #define SAS_DOPNRJT_RTRY_TMO 128 | 215 | #define SAS_DOPNRJT_RTRY_TMO 128 |
| 216 | #define SAS_COPNRJT_RTRY_TMO 128 | 216 | #define SAS_COPNRJT_RTRY_TMO 128 |
| 217 | 217 | ||
| 218 | /* for phy state */ | ||
| 219 | #define PHY_STATE_LINK_UP_SPCV 0x2 | ||
| 218 | /* | 220 | /* |
| 219 | Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. | 221 | Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. |
| 220 | Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 | 222 | Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 |
