/**
 *
 * @controller: This is the controller object that receives the link down
 *    notification.
 * @port: This is the port object associated with the phy.  If the is no
 *    associated port this is an NULL.  The port is an invalid
 *    handle only if the phy was never port of this port.  This happens when
 *    the phy is not broadcasting the same SAS address as the other phys in the
 *    assigned port.
 * @phy: This is the phy object which has gone link down.
 *
 * This function handles the manual port configuration link down notifications.
 * Since all ports and phys are associated at initialization time we just turn
 * around and notifiy the port object of the link down event.  If this PHY is
 * not associated with a port there is no action taken. Is it possible to get a
 * link down notification from a phy that has no assocoated port?
 */
static void sci_mpc_agent_link_down(
	struct isci_host *ihost,
	struct sci_port_configuration_agent *port_agent,
	struct isci_port *iport,
	struct isci_phy *iphy)
{
	if (iport != NULL) {
		/*
		 * If we can form a new port from the remainder of the phys
		 * then we want to start the timer to allow the SCI User to
		 * cleanup old devices and rediscover the port before
		 * rebuilding the port with the phys that remain in the ready
		 * state.
		 */
		port_agent->phy_ready_mask &= ~(1 << iphy->phy_index);
		port_agent->phy_configured_mask &= ~(1 << iphy->phy_index);

		/*
		 * Check to see if there are more phys waiting to be
		 * configured into a port. If there are allow the SCI User
		 * to tear down this port, if necessary, and then reconstruct
		 * the port after the timeout.
		 */
		if ((port_agent->phy_configured_mask == 0x0000) &&
		    (port_agent->phy_ready_mask != 0x0000) &&
		    !port_agent->timer_pending) {
			port_agent->timer_pending = true;

			sci_mod_timer(&port_agent->timer,
				      SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT);
		}

		sci_port_link_down(iport, iphy);
	}
}
static void sci_mpc_agent_link_down(
	struct isci_host *ihost,
	struct sci_port_configuration_agent *port_agent,
	struct isci_port *iport,
	struct isci_phy *iphy)
{
	if (iport != NULL) {
		port_agent->phy_ready_mask &= ~(1 << iphy->phy_index);
		port_agent->phy_configured_mask &= ~(1 << iphy->phy_index);

		if ((port_agent->phy_configured_mask == 0x0000) &&
		    (port_agent->phy_ready_mask != 0x0000) &&
		    !port_agent->timer_pending) {
			port_agent->timer_pending = true;

			sci_mod_timer(&port_agent->timer,
				      SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT);
		}

		sci_port_link_down(iport, iphy);
	}
}