aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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