aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>2012-03-20 02:38:11 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-04-23 14:27:33 -0400
commit43d6ddfa7aba2439d5bd22973046bdcb0faa78fb (patch)
treee09d9e36e5348feb7a6b5a008d9b54f85b52c5b9 /drivers/scsi/mpt2sas
parentd838c36cb7d9642b9b42dd18c511ba28c592b694 (diff)
[SCSI] mpt2sas : While enabling phy, read the current port number from sas iounit page 0 instead of page 1
The port number is changing after disabling/enabling phys using the SysFS interface This is because the firmware behavour changed where it would read the the port number then set it to some different value even though Auto Port Config is turned on. With this change of behavour in FW, it is possible that the expanders are moved from one port to another after disabling /enabling phys. This is occuring because the port number in sas iounit page 1 is not matching up to the current port in page 0. In order to fix this the driver is modified to read the current port number from sas iounit page 0 instead of page 1. Also copy the port and phy flags over from page 0 to page 1. Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index fed8b163afef..865deb9a5e5a 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -1639,11 +1639,13 @@ _transport_phy_enable(struct sas_phy *phy, int enable)
1639{ 1639{
1640 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1640 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1641 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; 1641 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1642 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
1642 Mpi2ConfigReply_t mpi_reply; 1643 Mpi2ConfigReply_t mpi_reply;
1643 u16 ioc_status; 1644 u16 ioc_status;
1644 u16 sz; 1645 u16 sz;
1645 int rc = 0; 1646 int rc = 0;
1646 unsigned long flags; 1647 unsigned long flags;
1648 int i, discovery_active;
1647 1649
1648 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1650 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1649 if (_transport_sas_node_find_by_sas_address(ioc, 1651 if (_transport_sas_node_find_by_sas_address(ioc,
@@ -1661,7 +1663,50 @@ _transport_phy_enable(struct sas_phy *phy, int enable)
1661 1663
1662 /* handle hba phys */ 1664 /* handle hba phys */
1663 1665
1664 /* sas_iounit page 1 */ 1666 /* read sas_iounit page 0 */
1667 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
1668 sizeof(Mpi2SasIOUnit0PhyData_t));
1669 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
1670 if (!sas_iounit_pg0) {
1671 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1672 ioc->name, __FILE__, __LINE__, __func__);
1673 rc = -ENOMEM;
1674 goto out;
1675 }
1676 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
1677 sas_iounit_pg0, sz))) {
1678 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1679 ioc->name, __FILE__, __LINE__, __func__);
1680 rc = -ENXIO;
1681 goto out;
1682 }
1683 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1684 MPI2_IOCSTATUS_MASK;
1685 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1686 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1687 ioc->name, __FILE__, __LINE__, __func__);
1688 rc = -EIO;
1689 goto out;
1690 }
1691
1692 /* unable to enable/disable phys when when discovery is active */
1693 for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
1694 if (sas_iounit_pg0->PhyData[i].PortFlags &
1695 MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
1696 printk(MPT2SAS_ERR_FMT "discovery is active on "
1697 "port = %d, phy = %d: unable to enable/disable "
1698 "phys, try again later!\n", ioc->name,
1699 sas_iounit_pg0->PhyData[i].Port, i);
1700 discovery_active = 1;
1701 }
1702 }
1703
1704 if (discovery_active) {
1705 rc = -EAGAIN;
1706 goto out;
1707 }
1708
1709 /* read sas_iounit page 1 */
1665 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * 1710 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1666 sizeof(Mpi2SasIOUnit1PhyData_t)); 1711 sizeof(Mpi2SasIOUnit1PhyData_t));
1667 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); 1712 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
@@ -1686,7 +1731,18 @@ _transport_phy_enable(struct sas_phy *phy, int enable)
1686 rc = -EIO; 1731 rc = -EIO;
1687 goto out; 1732 goto out;
1688 } 1733 }
1689 1734 /* copy Port/PortFlags/PhyFlags from page 0 */
1735 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
1736 sas_iounit_pg1->PhyData[i].Port =
1737 sas_iounit_pg0->PhyData[i].Port;
1738 sas_iounit_pg1->PhyData[i].PortFlags =
1739 (sas_iounit_pg0->PhyData[i].PortFlags &
1740 MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
1741 sas_iounit_pg1->PhyData[i].PhyFlags =
1742 (sas_iounit_pg0->PhyData[i].PhyFlags &
1743 (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
1744 MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
1745 }
1690 if (enable) 1746 if (enable)
1691 sas_iounit_pg1->PhyData[phy->number].PhyFlags 1747 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1692 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 1748 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
@@ -1702,6 +1758,7 @@ _transport_phy_enable(struct sas_phy *phy, int enable)
1702 1758
1703 out: 1759 out:
1704 kfree(sas_iounit_pg1); 1760 kfree(sas_iounit_pg1);
1761 kfree(sas_iounit_pg0);
1705 return rc; 1762 return rc;
1706} 1763}
1707 1764