aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/host.c67
-rw-r--r--drivers/scsi/isci/host.h3
-rw-r--r--drivers/scsi/isci/port_config.c18
3 files changed, 50 insertions, 38 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 95c3da66ea4b..577a8369274c 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -816,7 +816,7 @@ static void sci_controller_initialize_unsolicited_frame_queue(struct isci_host *
816 &ihost->scu_registers->sdma.unsolicited_frame_put_pointer); 816 &ihost->scu_registers->sdma.unsolicited_frame_put_pointer);
817} 817}
818 818
819static void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status) 819void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status)
820{ 820{
821 if (ihost->sm.current_state_id == SCIC_STARTING) { 821 if (ihost->sm.current_state_id == SCIC_STARTING) {
822 /* 822 /*
@@ -843,6 +843,7 @@ static bool is_phy_starting(struct isci_phy *iphy)
843 case SCI_PHY_SUB_AWAIT_SATA_POWER: 843 case SCI_PHY_SUB_AWAIT_SATA_POWER:
844 case SCI_PHY_SUB_AWAIT_SATA_PHY_EN: 844 case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
845 case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN: 845 case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
846 case SCI_PHY_SUB_AWAIT_OSSP_EN:
846 case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: 847 case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
847 case SCI_PHY_SUB_FINAL: 848 case SCI_PHY_SUB_FINAL:
848 return true; 849 return true;
@@ -851,6 +852,39 @@ static bool is_phy_starting(struct isci_phy *iphy)
851 } 852 }
852} 853}
853 854
855bool is_controller_start_complete(struct isci_host *ihost)
856{
857 int i;
858
859 for (i = 0; i < SCI_MAX_PHYS; i++) {
860 struct isci_phy *iphy = &ihost->phys[i];
861 u32 state = iphy->sm.current_state_id;
862
863 /* in apc mode we need to check every phy, in
864 * mpc mode we only need to check phys that have
865 * been configured into a port
866 */
867 if (is_port_config_apc(ihost))
868 /* pass */;
869 else if (!phy_get_non_dummy_port(iphy))
870 continue;
871
872 /* The controller start operation is complete iff:
873 * - all links have been given an opportunity to start
874 * - have no indication of a connected device
875 * - have an indication of a connected device and it has
876 * finished the link training process.
877 */
878 if ((iphy->is_in_link_training == false && state == SCI_PHY_INITIAL) ||
879 (iphy->is_in_link_training == false && state == SCI_PHY_STOPPED) ||
880 (iphy->is_in_link_training == true && is_phy_starting(iphy)) ||
881 (ihost->port_agent.phy_ready_mask != ihost->port_agent.phy_configured_mask))
882 return false;
883 }
884
885 return true;
886}
887
854/** 888/**
855 * sci_controller_start_next_phy - start phy 889 * sci_controller_start_next_phy - start phy
856 * @scic: controller 890 * @scic: controller
@@ -871,36 +905,7 @@ static enum sci_status sci_controller_start_next_phy(struct isci_host *ihost)
871 return status; 905 return status;
872 906
873 if (ihost->next_phy_to_start >= SCI_MAX_PHYS) { 907 if (ihost->next_phy_to_start >= SCI_MAX_PHYS) {
874 bool is_controller_start_complete = true; 908 if (is_controller_start_complete(ihost)) {
875 u32 state;
876 u8 index;
877
878 for (index = 0; index < SCI_MAX_PHYS; index++) {
879 iphy = &ihost->phys[index];
880 state = iphy->sm.current_state_id;
881
882 if (!phy_get_non_dummy_port(iphy))
883 continue;
884
885 /* The controller start operation is complete iff:
886 * - all links have been given an opportunity to start
887 * - have no indication of a connected device
888 * - have an indication of a connected device and it has
889 * finished the link training process.
890 */
891 if ((iphy->is_in_link_training == false && state == SCI_PHY_INITIAL) ||
892 (iphy->is_in_link_training == false && state == SCI_PHY_STOPPED) ||
893 (iphy->is_in_link_training == true && is_phy_starting(iphy)) ||
894 (ihost->port_agent.phy_ready_mask != ihost->port_agent.phy_configured_mask)) {
895 is_controller_start_complete = false;
896 break;
897 }
898 }
899
900 /*
901 * The controller has successfully finished the start process.
902 * Inform the SCI Core user and transition to the READY state. */
903 if (is_controller_start_complete == true) {
904 sci_controller_transition_to_ready(ihost, SCI_SUCCESS); 909 sci_controller_transition_to_ready(ihost, SCI_SUCCESS);
905 sci_del_timer(&ihost->phy_timer); 910 sci_del_timer(&ihost->phy_timer);
906 ihost->phy_startup_timer_pending = false; 911 ihost->phy_startup_timer_pending = false;
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index a89c0e3c5a14..9dc910b9d921 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -109,6 +109,8 @@ struct sci_port_configuration_agent;
109typedef void (*port_config_fn)(struct isci_host *, 109typedef void (*port_config_fn)(struct isci_host *,
110 struct sci_port_configuration_agent *, 110 struct sci_port_configuration_agent *,
111 struct isci_port *, struct isci_phy *); 111 struct isci_port *, struct isci_phy *);
112bool is_port_config_apc(struct isci_host *ihost);
113bool is_controller_start_complete(struct isci_host *ihost);
112 114
113struct sci_port_configuration_agent { 115struct sci_port_configuration_agent {
114 u16 phy_configured_mask; 116 u16 phy_configured_mask;
@@ -473,6 +475,7 @@ void isci_host_completion_routine(unsigned long data);
473void isci_host_deinit(struct isci_host *); 475void isci_host_deinit(struct isci_host *);
474void sci_controller_disable_interrupts(struct isci_host *ihost); 476void sci_controller_disable_interrupts(struct isci_host *ihost);
475bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost); 477bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost);
478void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status);
476 479
477enum sci_status sci_controller_start_io( 480enum sci_status sci_controller_start_io(
478 struct isci_host *ihost, 481 struct isci_host *ihost,
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c
index 6d1e9544cbe5..cd962da4a57a 100644
--- a/drivers/scsi/isci/port_config.c
+++ b/drivers/scsi/isci/port_config.c
@@ -57,7 +57,7 @@
57 57
58#define SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT (10) 58#define SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT (10)
59#define SCIC_SDS_APC_RECONFIGURATION_TIMEOUT (10) 59#define SCIC_SDS_APC_RECONFIGURATION_TIMEOUT (10)
60#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (250) 60#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (1000)
61 61
62enum SCIC_SDS_APC_ACTIVITY { 62enum SCIC_SDS_APC_ACTIVITY {
63 SCIC_SDS_APC_SKIP_PHY, 63 SCIC_SDS_APC_SKIP_PHY,
@@ -472,13 +472,9 @@ sci_apc_agent_validate_phy_configuration(struct isci_host *ihost,
472 * down event or a link up event where we can not yet tell to which a phy 472 * down event or a link up event where we can not yet tell to which a phy
473 * belongs. 473 * belongs.
474 */ 474 */
475static void sci_apc_agent_start_timer( 475static void sci_apc_agent_start_timer(struct sci_port_configuration_agent *port_agent,
476 struct sci_port_configuration_agent *port_agent, 476 u32 timeout)
477 u32 timeout)
478{ 477{
479 if (port_agent->timer_pending)
480 sci_del_timer(&port_agent->timer);
481
482 port_agent->timer_pending = true; 478 port_agent->timer_pending = true;
483 sci_mod_timer(&port_agent->timer, timeout); 479 sci_mod_timer(&port_agent->timer, timeout);
484} 480}
@@ -697,6 +693,9 @@ static void apc_agent_timeout(unsigned long data)
697 &ihost->phys[index], false); 693 &ihost->phys[index], false);
698 } 694 }
699 695
696 if (is_controller_start_complete(ihost))
697 sci_controller_transition_to_ready(ihost, SCI_SUCCESS);
698
700done: 699done:
701 spin_unlock_irqrestore(&ihost->scic_lock, flags); 700 spin_unlock_irqrestore(&ihost->scic_lock, flags);
702} 701}
@@ -732,6 +731,11 @@ void sci_port_configuration_agent_construct(
732 } 731 }
733} 732}
734 733
734bool is_port_config_apc(struct isci_host *ihost)
735{
736 return ihost->port_agent.link_up_handler == sci_apc_agent_link_up;
737}
738
735enum sci_status sci_port_configuration_agent_initialize( 739enum sci_status sci_port_configuration_agent_initialize(
736 struct isci_host *ihost, 740 struct isci_host *ihost,
737 struct sci_port_configuration_agent *port_agent) 741 struct sci_port_configuration_agent *port_agent)