aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSakthivel K <Sakthivel.SaravananKamalRaju@pmcs.com>2013-03-19 08:38:40 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-10 10:47:51 -0400
commita6cb3d012b983b350ae3892cff2e692665df0e1e (patch)
treee22bce8642adf4f4b5caf08ab0995a131db2e39e
parentc6b9ef5779c3e1edfa9de949d2a51252bc347663 (diff)
[SCSI] pm80xx: thermal, sas controller config and error handling update
Modified thermal configuration to happen after interrupt registration Added SAS controller configuration during initialization Added error handling logic to handle I_T_Nexus errors and variants [jejb: fix up tabs and spaces issues] Signed-off-by: Anand Kumar S <AnandKumar.Santhanam@pmcs.com> Acked-by: Jack Wang <jack_wang@usish.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c2
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c2
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c66
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h2
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c150
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.h44
6 files changed, 249 insertions, 17 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index dbdd9d386f10..95d04cc78c0b 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1670,7 +1670,7 @@ void pm8001_work_fn(struct work_struct *work)
1670 } break; 1670 } break;
1671 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 1671 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
1672 dev = pm8001_dev->sas_device; 1672 dev = pm8001_dev->sas_device;
1673 pm8001_I_T_nexus_reset(dev); 1673 pm8001_I_T_nexus_event_handler(dev);
1674 break; 1674 break;
1675 case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: 1675 case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
1676 dev = pm8001_dev->sas_device; 1676 dev = pm8001_dev->sas_device;
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 055f7d0e15d8..1c718520036a 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -838,6 +838,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
838 if (pm8001_ha->chip_id != chip_8001) { 838 if (pm8001_ha->chip_id != chip_8001) {
839 for (i = 1; i < pm8001_ha->number_of_intr; i++) 839 for (i = 1; i < pm8001_ha->number_of_intr; i++)
840 PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i); 840 PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
841 /* setup thermal configuration. */
842 pm80xx_set_thermal_config(pm8001_ha);
841 } 843 }
842 844
843 pm8001_init_sas_add(pm8001_ha); 845 pm8001_init_sas_add(pm8001_ha);
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index c720917d1388..9af95853f840 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -1018,6 +1018,72 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev)
1018 return rc; 1018 return rc;
1019} 1019}
1020 1020
1021/*
1022* This function handle the IT_NEXUS_XXX event or completion
1023* status code for SSP/SATA/SMP I/O request.
1024*/
1025int pm8001_I_T_nexus_event_handler(struct domain_device *dev)
1026{
1027 int rc = TMF_RESP_FUNC_FAILED;
1028 struct pm8001_device *pm8001_dev;
1029 struct pm8001_hba_info *pm8001_ha;
1030 struct sas_phy *phy;
1031 u32 device_id = 0;
1032
1033 if (!dev || !dev->lldd_dev)
1034 return -1;
1035
1036 pm8001_dev = dev->lldd_dev;
1037 device_id = pm8001_dev->device_id;
1038 pm8001_ha = pm8001_find_ha_by_dev(dev);
1039
1040 PM8001_EH_DBG(pm8001_ha,
1041 pm8001_printk("I_T_Nexus handler invoked !!"));
1042
1043 phy = sas_get_local_phy(dev);
1044
1045 if (dev_is_sata(dev)) {
1046 DECLARE_COMPLETION_ONSTACK(completion_setstate);
1047 if (scsi_is_sas_phy_local(phy)) {
1048 rc = 0;
1049 goto out;
1050 }
1051 /* send internal ssp/sata/smp abort command to FW */
1052 rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
1053 dev, 1, 0);
1054 msleep(100);
1055
1056 /* deregister the target device */
1057 pm8001_dev_gone_notify(dev);
1058 msleep(200);
1059
1060 /*send phy reset to hard reset target */
1061 rc = sas_phy_reset(phy, 1);
1062 msleep(2000);
1063 pm8001_dev->setds_completion = &completion_setstate;
1064
1065 wait_for_completion(&completion_setstate);
1066 } else {
1067 /* send internal ssp/sata/smp abort command to FW */
1068 rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
1069 dev, 1, 0);
1070 msleep(100);
1071
1072 /* deregister the target device */
1073 pm8001_dev_gone_notify(dev);
1074 msleep(200);
1075
1076 /*send phy reset to hard reset target */
1077 rc = sas_phy_reset(phy, 1);
1078 msleep(2000);
1079 }
1080 PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n",
1081 pm8001_dev->device_id, rc));
1082out:
1083 sas_put_local_phy(phy);
1084
1085 return rc;
1086}
1021/* mandatory SAM-3, the task reset the specified LUN*/ 1087/* mandatory SAM-3, the task reset the specified LUN*/
1022int pm8001_lu_reset(struct domain_device *dev, u8 *lun) 1088int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
1023{ 1089{
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index ab30193f235f..72d46ea398dc 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -563,6 +563,7 @@ int pm8001_dev_found(struct domain_device *dev);
563void pm8001_dev_gone(struct domain_device *dev); 563void pm8001_dev_gone(struct domain_device *dev);
564int pm8001_lu_reset(struct domain_device *dev, u8 *lun); 564int pm8001_lu_reset(struct domain_device *dev, u8 *lun);
565int pm8001_I_T_nexus_reset(struct domain_device *dev); 565int pm8001_I_T_nexus_reset(struct domain_device *dev);
566int pm8001_I_T_nexus_event_handler(struct domain_device *dev);
566int pm8001_query_task(struct sas_task *task); 567int pm8001_query_task(struct sas_task *task);
567void pm8001_open_reject_retry( 568void pm8001_open_reject_retry(
568 struct pm8001_hba_info *pm8001_ha, 569 struct pm8001_hba_info *pm8001_ha,
@@ -625,6 +626,7 @@ void pm8001_free_task(struct sas_task *task);
625void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag); 626void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag);
626struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha, 627struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha,
627 u32 device_id); 628 u32 device_id);
629int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);
628 630
629int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue); 631int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
630 632
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index f0dbe79b049c..670998a8ca79 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -613,7 +613,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
613 * pm80xx_set_thermal_config - support the thermal configuration 613 * pm80xx_set_thermal_config - support the thermal configuration
614 * @pm8001_ha: our hba card information. 614 * @pm8001_ha: our hba card information.
615 */ 615 */
616static int 616int
617pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha) 617pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
618{ 618{
619 struct set_ctrl_cfg_req payload; 619 struct set_ctrl_cfg_req payload;
@@ -639,6 +639,86 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
639} 639}
640 640
641/** 641/**
642* pm80xx_set_sas_protocol_timer_config - support the SAS Protocol
643* Timer configuration page
644* @pm8001_ha: our hba card information.
645*/
646static int
647pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
648{
649 struct set_ctrl_cfg_req payload;
650 struct inbound_queue_table *circularQ;
651 SASProtocolTimerConfig_t SASConfigPage;
652 int rc;
653 u32 tag;
654 u32 opc = OPC_INB_SET_CONTROLLER_CONFIG;
655
656 memset(&payload, 0, sizeof(struct set_ctrl_cfg_req));
657 memset(&SASConfigPage, 0, sizeof(SASProtocolTimerConfig_t));
658
659 rc = pm8001_tag_alloc(pm8001_ha, &tag);
660
661 if (rc)
662 return -1;
663
664 circularQ = &pm8001_ha->inbnd_q_tbl[0];
665 payload.tag = cpu_to_le32(tag);
666
667 SASConfigPage.pageCode = SAS_PROTOCOL_TIMER_CONFIG_PAGE;
668 SASConfigPage.MST_MSI = 3 << 15;
669 SASConfigPage.STP_SSP_MCT_TMO = (STP_MCT_TMO << 16) | SSP_MCT_TMO;
670 SASConfigPage.STP_FRM_TMO = (SAS_MAX_OPEN_TIME << 24) |
671 (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER;
672 SASConfigPage.STP_IDLE_TMO = STP_IDLE_TIME;
673
674 if (SASConfigPage.STP_IDLE_TMO > 0x3FFFFFF)
675 SASConfigPage.STP_IDLE_TMO = 0x3FFFFFF;
676
677
678 SASConfigPage.OPNRJT_RTRY_INTVL = (SAS_MFD << 16) |
679 SAS_OPNRJT_RTRY_INTVL;
680 SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO = (SAS_DOPNRJT_RTRY_TMO << 16)
681 | SAS_COPNRJT_RTRY_TMO;
682 SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR = (SAS_DOPNRJT_RTRY_THR << 16)
683 | SAS_COPNRJT_RTRY_THR;
684 SASConfigPage.MAX_AIP = SAS_MAX_AIP;
685
686 PM8001_INIT_DBG(pm8001_ha,
687 pm8001_printk("SASConfigPage.pageCode "
688 "0x%08x\n", SASConfigPage.pageCode));
689 PM8001_INIT_DBG(pm8001_ha,
690 pm8001_printk("SASConfigPage.MST_MSI "
691 " 0x%08x\n", SASConfigPage.MST_MSI));
692 PM8001_INIT_DBG(pm8001_ha,
693 pm8001_printk("SASConfigPage.STP_SSP_MCT_TMO "
694 " 0x%08x\n", SASConfigPage.STP_SSP_MCT_TMO));
695 PM8001_INIT_DBG(pm8001_ha,
696 pm8001_printk("SASConfigPage.STP_FRM_TMO "
697 " 0x%08x\n", SASConfigPage.STP_FRM_TMO));
698 PM8001_INIT_DBG(pm8001_ha,
699 pm8001_printk("SASConfigPage.STP_IDLE_TMO "
700 " 0x%08x\n", SASConfigPage.STP_IDLE_TMO));
701 PM8001_INIT_DBG(pm8001_ha,
702 pm8001_printk("SASConfigPage.OPNRJT_RTRY_INTVL "
703 " 0x%08x\n", SASConfigPage.OPNRJT_RTRY_INTVL));
704 PM8001_INIT_DBG(pm8001_ha,
705 pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO "
706 " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO));
707 PM8001_INIT_DBG(pm8001_ha,
708 pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR "
709 " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR));
710 PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.MAX_AIP "
711 " 0x%08x\n", SASConfigPage.MAX_AIP));
712
713 memcpy(&payload.cfg_pg, &SASConfigPage,
714 sizeof(SASProtocolTimerConfig_t));
715
716 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
717
718 return rc;
719}
720
721/**
642 * pm80xx_get_encrypt_info - Check for encryption 722 * pm80xx_get_encrypt_info - Check for encryption
643 * @pm8001_ha: our hba card information. 723 * @pm8001_ha: our hba card information.
644 */ 724 */
@@ -800,11 +880,8 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha)
800 } else 880 } else
801 return -EBUSY; 881 return -EBUSY;
802 882
803 /* configure thermal */ 883 /* send SAS protocol timer configuration page to FW */
804 pm80xx_set_thermal_config(pm8001_ha); 884 ret = pm80xx_set_sas_protocol_timer_config(pm8001_ha);
805
806 PM8001_INIT_DBG(pm8001_ha,
807 pm8001_printk("Thermal configuration successful!\n"));
808 885
809 /* Check for encryption */ 886 /* Check for encryption */
810 if (pm8001_ha->chip->encrypt) { 887 if (pm8001_ha->chip->encrypt) {
@@ -1269,6 +1346,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
1269 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; 1346 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1270 break; 1347 break;
1271 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 1348 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
1349 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
1350 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
1351 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
1352 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
1353 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
1272 PM8001_IO_DBG(pm8001_ha, 1354 PM8001_IO_DBG(pm8001_ha,
1273 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); 1355 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
1274 ts->resp = SAS_TASK_COMPLETE; 1356 ts->resp = SAS_TASK_COMPLETE;
@@ -1472,6 +1554,11 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
1472 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; 1554 ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
1473 break; 1555 break;
1474 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 1556 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
1557 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
1558 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
1559 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
1560 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
1561 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
1475 PM8001_IO_DBG(pm8001_ha, 1562 PM8001_IO_DBG(pm8001_ha,
1476 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); 1563 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
1477 ts->resp = SAS_TASK_COMPLETE; 1564 ts->resp = SAS_TASK_COMPLETE;
@@ -1557,6 +1644,13 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
1557 ts->resp = SAS_TASK_COMPLETE; 1644 ts->resp = SAS_TASK_COMPLETE;
1558 ts->stat = SAS_DATA_OVERRUN; 1645 ts->stat = SAS_DATA_OVERRUN;
1559 break; 1646 break;
1647 case IO_XFER_ERROR_INTERNAL_CRC_ERROR:
1648 PM8001_IO_DBG(pm8001_ha,
1649 pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n"));
1650 /* TBC: used default set values */
1651 ts->resp = SAS_TASK_COMPLETE;
1652 ts->stat = SAS_DATA_OVERRUN;
1653 break;
1560 case IO_XFER_CMD_FRAME_ISSUED: 1654 case IO_XFER_CMD_FRAME_ISSUED:
1561 PM8001_IO_DBG(pm8001_ha, 1655 PM8001_IO_DBG(pm8001_ha,
1562 pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n")); 1656 pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n"));
@@ -1761,6 +1855,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
1761 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; 1855 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
1762 break; 1856 break;
1763 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 1857 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
1858 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
1859 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
1860 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
1861 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
1862 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
1764 PM8001_IO_DBG(pm8001_ha, 1863 PM8001_IO_DBG(pm8001_ha,
1765 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); 1864 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
1766 ts->resp = SAS_TASK_COMPLETE; 1865 ts->resp = SAS_TASK_COMPLETE;
@@ -2051,7 +2150,12 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2051 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; 2150 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
2052 break; 2151 break;
2053 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 2152 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
2054 PM8001_IO_DBG(pm8001_ha, 2153 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
2154 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
2155 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
2156 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
2157 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
2158 PM8001_FAIL_DBG(pm8001_ha,
2055 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); 2159 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
2056 ts->resp = SAS_TASK_UNDELIVERED; 2160 ts->resp = SAS_TASK_UNDELIVERED;
2057 ts->stat = SAS_DEV_NO_RESPONSE; 2161 ts->stat = SAS_DEV_NO_RESPONSE;
@@ -2154,6 +2258,20 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2154 ts->resp = SAS_TASK_COMPLETE; 2258 ts->resp = SAS_TASK_COMPLETE;
2155 ts->stat = SAS_OPEN_TO; 2259 ts->stat = SAS_OPEN_TO;
2156 break; 2260 break;
2261 case IO_XFER_ERROR_INTERNAL_CRC_ERROR:
2262 PM8001_FAIL_DBG(pm8001_ha,
2263 pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n"));
2264 /* TBC: used default set values */
2265 ts->resp = SAS_TASK_COMPLETE;
2266 ts->stat = SAS_OPEN_TO;
2267 break;
2268 case IO_XFER_DMA_ACTIVATE_TIMEOUT:
2269 PM8001_FAIL_DBG(pm8001_ha,
2270 pm8001_printk("IO_XFR_DMA_ACTIVATE_TIMEOUT\n"));
2271 /* TBC: used default set values */
2272 ts->resp = SAS_TASK_COMPLETE;
2273 ts->stat = SAS_OPEN_TO;
2274 break;
2157 default: 2275 default:
2158 PM8001_IO_DBG(pm8001_ha, 2276 PM8001_IO_DBG(pm8001_ha,
2159 pm8001_printk("Unknown status 0x%x\n", event)); 2277 pm8001_printk("Unknown status 0x%x\n", event));
@@ -2305,6 +2423,11 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2305 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; 2423 ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
2306 break; 2424 break;
2307 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 2425 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
2426 case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
2427 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
2428 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
2429 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
2430 case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
2308 PM8001_IO_DBG(pm8001_ha, 2431 PM8001_IO_DBG(pm8001_ha,
2309 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); 2432 pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
2310 ts->resp = SAS_TASK_COMPLETE; 2433 ts->resp = SAS_TASK_COMPLETE;
@@ -2862,6 +2985,9 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
2862 case HW_EVENT_PORT_RECOVERY_TIMER_TMO: 2985 case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
2863 PM8001_MSG_DBG(pm8001_ha, 2986 PM8001_MSG_DBG(pm8001_ha,
2864 pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO\n")); 2987 pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO\n"));
2988 pm80xx_hw_event_ack_req(pm8001_ha, 0,
2989 HW_EVENT_PORT_RECOVERY_TIMER_TMO,
2990 port_id, phy_id, 0, 0);
2865 sas_phy_disconnected(sas_phy); 2991 sas_phy_disconnected(sas_phy);
2866 phy->phy_attached = 0; 2992 phy->phy_attached = 0;
2867 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); 2993 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
@@ -3499,10 +3625,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
3499 ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); 3625 ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
3500 ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); 3626 ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
3501 memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); 3627 memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16);
3502 circularQ = &pm8001_ha->inbnd_q_tbl[inb++]; 3628 circularQ = &pm8001_ha->inbnd_q_tbl[0];
3503
3504 /* rotate the inb queue */
3505 inb = inb%PM8001_MAX_SPCV_INB_NUM;
3506 3629
3507 /* Check if encryption is set */ 3630 /* Check if encryption is set */
3508 if (pm8001_ha->chip->encrypt && 3631 if (pm8001_ha->chip->encrypt &&
@@ -3603,10 +3726,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
3603 unsigned long flags; 3726 unsigned long flags;
3604 u32 opc = OPC_INB_SATA_HOST_OPSTART; 3727 u32 opc = OPC_INB_SATA_HOST_OPSTART;
3605 memset(&sata_cmd, 0, sizeof(sata_cmd)); 3728 memset(&sata_cmd, 0, sizeof(sata_cmd));
3606 circularQ = &pm8001_ha->inbnd_q_tbl[inb++]; 3729 circularQ = &pm8001_ha->inbnd_q_tbl[0];
3607
3608 /* rotate the inb queue */
3609 inb = inb%PM8001_MAX_SPCV_INB_NUM;
3610 3730
3611 if (task->data_dir == PCI_DMA_NONE) { 3731 if (task->data_dir == PCI_DMA_NONE) {
3612 ATAP = 0x04; /* no data*/ 3732 ATAP = 0x04; /* no data*/
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index b7c864f16402..2b760ba75d7b 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -197,6 +197,30 @@
197#define CIPHER_MODE_XTS 0x00000002 197#define CIPHER_MODE_XTS 0x00000002
198#define KEK_MGMT_SUBOP_KEYCARDUPDATE 0x4 198#define KEK_MGMT_SUBOP_KEYCARDUPDATE 0x4
199 199
200/* SAS protocol timer configuration page */
201#define SAS_PROTOCOL_TIMER_CONFIG_PAGE 0x04
202#define STP_MCT_TMO 32
203#define SSP_MCT_TMO 32
204#define SAS_MAX_OPEN_TIME 5
205#define SMP_MAX_CONN_TIMER 0xFF
206#define STP_FRM_TIMER 0
207#define STP_IDLE_TIME 5 /* 5 us; controller default */
208#define SAS_MFD 0
209#define SAS_OPNRJT_RTRY_INTVL 2
210#define SAS_DOPNRJT_RTRY_TMO 128
211#define SAS_COPNRJT_RTRY_TMO 128
212
213/*
214 Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
215 Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
216 is DOPNRJT_RTRY_TMO
217*/
218#define SAS_DOPNRJT_RTRY_THR 23438
219#define SAS_COPNRJT_RTRY_THR 23438
220#define SAS_MAX_AIP 0x200000
221#define IT_NEXUS_TIMEOUT 0x7D0
222#define PORT_RECOVERY_TIMEOUT ((IT_NEXUS_TIMEOUT/100) + 30)
223
200struct mpi_msg_hdr { 224struct mpi_msg_hdr {
201 __le32 header; /* Bits [11:0] - Message operation code */ 225 __le32 header; /* Bits [11:0] - Message operation code */
202 /* Bits [15:12] - Message Category */ 226 /* Bits [15:12] - Message Category */
@@ -996,6 +1020,23 @@ struct ssp_coalesced_comp_resp {
996 1020
997/* new outbound structure for spcv - ends */ 1021/* new outbound structure for spcv - ends */
998 1022
1023/* brief data structure for SAS protocol timer configuration page.
1024 *
1025 */
1026struct SASProtocolTimerConfig {
1027 __le32 pageCode; /* 0 */
1028 __le32 MST_MSI; /* 1 */
1029 __le32 STP_SSP_MCT_TMO; /* 2 */
1030 __le32 STP_FRM_TMO; /* 3 */
1031 __le32 STP_IDLE_TMO; /* 4 */
1032 __le32 OPNRJT_RTRY_INTVL; /* 5 */
1033 __le32 Data_Cmd_OPNRJT_RTRY_TMO; /* 6 */
1034 __le32 Data_Cmd_OPNRJT_RTRY_THR; /* 7 */
1035 __le32 MAX_AIP; /* 8 */
1036} __attribute__((packed, aligned(4)));
1037
1038typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
1039
999#define NDS_BITS 0x0F 1040#define NDS_BITS 0x0F
1000#define PDS_BITS 0xF0 1041#define PDS_BITS 0xF0
1001 1042
@@ -1122,7 +1163,8 @@ struct ssp_coalesced_comp_resp {
1122#define IO_DS_INVALID 0x49 1163#define IO_DS_INVALID 0x49
1123/* WARNING: the value is not contiguous from here */ 1164/* WARNING: the value is not contiguous from here */
1124#define IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR 0x52 1165#define IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR 0x52
1125#define IO_XFR_ERROR_INTERNAL_CRC_ERROR 0x54 1166#define IO_XFER_DMA_ACTIVATE_TIMEOUT 0x53
1167#define IO_XFER_ERROR_INTERNAL_CRC_ERROR 0x54
1126#define MPI_IO_RQE_BUSY_FULL 0x55 1168#define MPI_IO_RQE_BUSY_FULL 0x55
1127#define IO_XFER_ERR_EOB_DATA_OVERRUN 0x56 1169#define IO_XFER_ERR_EOB_DATA_OVERRUN 0x56
1128#define IO_XFR_ERROR_INVALID_SSP_RSP_FRAME 0x57 1170#define IO_XFR_ERROR_INVALID_SSP_RSP_FRAME 0x57