aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Marek <pawel.marek@intel.com>2011-03-01 15:31:06 -0500
committerDan Williams <dan.j.williams@intel.com>2011-07-03 06:55:29 -0400
commitc658b109d3a9444293700471a278a741a1e5033d (patch)
tree2c218e8758eabb496f9bd4c2f3ceef477bc6aa43
parent3ff0121a704172aa4bca9c4026b419ddfe1921c8 (diff)
isci: controller stop/start fixes
Core reworks to support stopping and re-starting the controller, lays the groundwork for phy disable / re-enable and fixes other bugs around port/phy setup/teardown. Signed-off-by: Pawel Marek <pawel.marek@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.c129
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.h29
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.c83
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.h3
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.c21
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_device.c10
6 files changed, 206 insertions, 69 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c
index 5e26df7fcb3a..deee7ebef033 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.c
+++ b/drivers/scsi/isci/core/scic_sds_controller.c
@@ -252,7 +252,7 @@ static void scic_sds_controller_phy_startup_timeout_handler(
252 * 252 *
253 * This method initializes the phy startup operations for controller start. 253 * This method initializes the phy startup operations for controller start.
254 */ 254 */
255void scic_sds_controller_initialize_phy_startup( 255enum sci_status scic_sds_controller_initialize_phy_startup(
256 struct scic_sds_controller *this_controller) 256 struct scic_sds_controller *this_controller)
257{ 257{
258 this_controller->phy_startup_timer = isci_event_timer_create( 258 this_controller->phy_startup_timer = isci_event_timer_create(
@@ -261,8 +261,14 @@ void scic_sds_controller_initialize_phy_startup(
261 this_controller 261 this_controller
262 ); 262 );
263 263
264 this_controller->next_phy_to_start = 0; 264 if (this_controller->phy_startup_timer == NULL) {
265 this_controller->phy_startup_timer_pending = false; 265 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
266 } else {
267 this_controller->next_phy_to_start = 0;
268 this_controller->phy_startup_timer_pending = false;
269 }
270
271 return SCI_SUCCESS;
266} 272}
267 273
268/** 274/**
@@ -305,7 +311,7 @@ void scic_sds_controller_initialize_power_control(
305 * to build the memory table. 311 * to build the memory table.
306 * 312 *
307 */ 313 */
308static void scic_sds_controller_build_memory_descriptor_table( 314void scic_sds_controller_build_memory_descriptor_table(
309 struct scic_sds_controller *this_controller) 315 struct scic_sds_controller *this_controller)
310{ 316{
311 sci_base_mde_construct( 317 sci_base_mde_construct(
@@ -1699,6 +1705,91 @@ void scic_sds_controller_link_down(
1699} 1705}
1700 1706
1701/** 1707/**
1708 * This method is called by the remote device to inform the controller
1709 * that this remote device has started.
1710 *
1711 */
1712
1713void scic_sds_controller_remote_device_started(
1714 struct scic_sds_controller *this_controller,
1715 struct scic_sds_remote_device *the_device)
1716{
1717 u32 state;
1718 scic_sds_controller_device_handler_t remote_device_started_handler;
1719
1720 state = this_controller->parent.state_machine.current_state_id;
1721 remote_device_started_handler = scic_sds_controller_state_handler_table[state].remote_device_started_handler;
1722
1723 if (remote_device_started_handler != NULL)
1724 remote_device_started_handler(this_controller, the_device);
1725 else {
1726 dev_warn(scic_to_dev(this_controller),
1727 "%s: SCIC Controller 0x%p remote device started event "
1728 "from device 0x%p in unexpected state %d\n",
1729 __func__,
1730 this_controller,
1731 the_device,
1732 sci_base_state_machine_get_state(
1733 scic_sds_controller_get_base_state_machine(
1734 this_controller)));
1735 }
1736}
1737
1738/**
1739 * This is a helper method to determine if any remote devices on this
1740 * controller are still in the stopping state.
1741 *
1742 */
1743bool scic_sds_controller_has_remote_devices_stopping(
1744 struct scic_sds_controller *this_controller)
1745{
1746 u32 index;
1747
1748 for (index = 0; index < this_controller->remote_node_entries; index++) {
1749 if ((this_controller->device_table[index] != NULL) &&
1750 (this_controller->device_table[index]->parent.state_machine.current_state_id
1751 == SCI_BASE_REMOTE_DEVICE_STATE_STOPPING))
1752 return true;
1753 }
1754
1755 return false;
1756}
1757
1758/**
1759 * This method is called by the remote device to inform the controller
1760 * object that the remote device has stopped.
1761 *
1762 */
1763
1764void scic_sds_controller_remote_device_stopped(
1765 struct scic_sds_controller *this_controller,
1766 struct scic_sds_remote_device *the_device)
1767{
1768
1769 u32 state;
1770 scic_sds_controller_device_handler_t remote_device_stopped_handler;
1771
1772 state = this_controller->parent.state_machine.current_state_id;
1773 remote_device_stopped_handler = scic_sds_controller_state_handler_table[state].remote_device_stopped_handler;
1774
1775 if (remote_device_stopped_handler != NULL)
1776 remote_device_stopped_handler(this_controller, the_device);
1777 else {
1778 dev_warn(scic_to_dev(this_controller),
1779 "%s: SCIC Controller 0x%p remote device stopped event "
1780 "from device 0x%p in unexpected state %d\n",
1781 __func__,
1782 this_controller,
1783 the_device,
1784 sci_base_state_machine_get_state(
1785 scic_sds_controller_get_base_state_machine(
1786 this_controller)));
1787 }
1788}
1789
1790
1791
1792/**
1702 * This method will write to the SCU PCP register the request value. The method 1793 * This method will write to the SCU PCP register the request value. The method
1703 * is used to suspend/resume ports, devices, and phys. 1794 * is used to suspend/resume ports, devices, and phys.
1704 * @this_controller: 1795 * @this_controller:
@@ -3461,23 +3552,22 @@ static enum sci_status scic_sds_controller_stopping_state_complete_io_handler(
3461 * struct scic_sds_controller object. 3552 * struct scic_sds_controller object.
3462 * @remote_device: This is struct sci_base_remote_device which is cast to a 3553 * @remote_device: This is struct sci_base_remote_device which is cast to a
3463 * struct scic_sds_remote_device object. 3554 * struct scic_sds_remote_device object.
3464 * @io_request: This is the struct sci_base_request which is cast to a
3465 * SCIC_SDS_IO_REQUEST object.
3466 * 3555 *
3467 * This method is called when the struct scic_sds_controller is in a stopping state 3556 * This method is called when the struct scic_sds_controller is in a stopping state
3468 * and the complete task handler is called. - This function is not yet 3557 * and the remote device has stopped.
3469 * implemented enum sci_status SCI_FAILURE 3558 **/
3470 */ 3559void scic_sds_controller_stopping_state_device_stopped_handler(
3471 3560 struct scic_sds_controller *controller,
3472/* 3561 struct scic_sds_remote_device *remote_device
3473 * ***************************************************************************** 3562)
3474 * * STOPPED STATE HANDLERS 3563{
3475 * ***************************************************************************** */ 3564 if (!scic_sds_controller_has_remote_devices_stopping(controller)) {
3476 3565 sci_base_state_machine_change_state(
3477/* 3566 &controller->parent.state_machine,
3478 * ***************************************************************************** 3567 SCI_BASE_CONTROLLER_STATE_STOPPED
3479 * * FAILED STATE HANDLERS 3568 );
3480 * ***************************************************************************** */ 3569 }
3570}
3481 3571
3482const struct scic_sds_controller_state_handler scic_sds_controller_state_handler_table[] = { 3572const struct scic_sds_controller_state_handler scic_sds_controller_state_handler_table[] = {
3483 [SCI_BASE_CONTROLLER_STATE_INITIAL] = { 3573 [SCI_BASE_CONTROLLER_STATE_INITIAL] = {
@@ -3537,6 +3627,7 @@ const struct scic_sds_controller_state_handler scic_sds_controller_state_handler
3537 .base.complete_io = scic_sds_controller_stopping_state_complete_io_handler, 3627 .base.complete_io = scic_sds_controller_stopping_state_complete_io_handler,
3538 .base.continue_io = scic_sds_controller_default_request_handler, 3628 .base.continue_io = scic_sds_controller_default_request_handler,
3539 .terminate_request = scic_sds_controller_default_request_handler, 3629 .terminate_request = scic_sds_controller_default_request_handler,
3630 .remote_device_stopped_handler = scic_sds_controller_stopping_state_device_stopped_handler,
3540 }, 3631 },
3541 [SCI_BASE_CONTROLLER_STATE_STOPPED] = { 3632 [SCI_BASE_CONTROLLER_STATE_STOPPED] = {
3542 .base.reset = scic_sds_controller_general_reset_handler, 3633 .base.reset = scic_sds_controller_general_reset_handler,
diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h
index 3e0477d62a5b..9b8e55d62910 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.h
+++ b/drivers/scsi/isci/core/scic_sds_controller.h
@@ -120,6 +120,7 @@ enum SCIC_SDS_CONTROLLER_MEMORY_DESCRIPTORS {
120 SCU_MAX_MDES 120 SCU_MAX_MDES
121}; 121};
122 122
123
123/** 124/**
124 * 125 *
125 * 126 *
@@ -390,6 +391,11 @@ struct scic_sds_controller {
390typedef void (*scic_sds_controller_phy_handler_t)(struct scic_sds_controller *, 391typedef void (*scic_sds_controller_phy_handler_t)(struct scic_sds_controller *,
391 struct scic_sds_port *, 392 struct scic_sds_port *,
392 struct scic_sds_phy *); 393 struct scic_sds_phy *);
394
395typedef void (*scic_sds_controller_device_handler_t)(struct scic_sds_controller *,
396 struct scic_sds_remote_device *);
397
398
393/** 399/**
394 * struct scic_sds_controller_state_handler - 400 * struct scic_sds_controller_state_handler -
395 * 401 *
@@ -402,6 +408,8 @@ struct scic_sds_controller_state_handler {
402 sci_base_controller_request_handler_t terminate_request; 408 sci_base_controller_request_handler_t terminate_request;
403 scic_sds_controller_phy_handler_t link_up; 409 scic_sds_controller_phy_handler_t link_up;
404 scic_sds_controller_phy_handler_t link_down; 410 scic_sds_controller_phy_handler_t link_down;
411 scic_sds_controller_device_handler_t remote_device_started_handler;
412 scic_sds_controller_device_handler_t remote_device_stopped_handler;
405}; 413};
406 414
407extern const struct scic_sds_controller_state_handler 415extern const struct scic_sds_controller_state_handler
@@ -633,6 +641,23 @@ void scic_sds_controller_link_down(
633 641
634/* 642/*
635 * ***************************************************************************** 643 * *****************************************************************************
644 * * CORE CONTROLLER REMOTE DEVICE MESSAGE PROCESSING
645 * ***************************************************************************** */
646
647bool scic_sds_controller_has_remote_devices_stopping(
648 struct scic_sds_controller *this_controller);
649
650void scic_sds_controller_remote_device_started(
651 struct scic_sds_controller *this_controller,
652 struct scic_sds_remote_device *the_device);
653
654void scic_sds_controller_remote_device_stopped(
655 struct scic_sds_controller *this_controller,
656 struct scic_sds_remote_device *the_device);
657
658
659/*
660 * *****************************************************************************
636 * * CORE CONTROLLER PRIVATE METHODS 661 * * CORE CONTROLLER PRIVATE METHODS
637 * ***************************************************************************** */ 662 * ***************************************************************************** */
638 663
@@ -688,8 +713,10 @@ void scic_sds_controller_register_setup(
688void scic_sds_controller_reset_hardware( 713void scic_sds_controller_reset_hardware(
689 struct scic_sds_controller *this_controller); 714 struct scic_sds_controller *this_controller);
690 715
716enum sci_status scic_sds_controller_initialize_phy_startup(
717 struct scic_sds_controller *this_controller);
691 718
692void scic_sds_controller_initialize_phy_startup( 719void scic_sds_controller_build_memory_descriptor_table(
693 struct scic_sds_controller *this_controller); 720 struct scic_sds_controller *this_controller);
694 721
695#endif /* _SCIC_SDS_CONTROLLER_H_ */ 722#endif /* _SCIC_SDS_CONTROLLER_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c
index d4a5e38aef65..ba9e55756f26 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.c
+++ b/drivers/scsi/isci/core/scic_sds_phy.c
@@ -257,7 +257,7 @@ scic_sds_phy_link_layer_initialization(struct scic_sds_phy *sci_phy,
257 * restart the starting substate machine since we dont know what has actually 257 * restart the starting substate machine since we dont know what has actually
258 * happening. 258 * happening.
259 */ 259 */
260static void scic_sds_phy_sata_timeout(void *phy) 260void scic_sds_phy_sata_timeout(void *phy)
261{ 261{
262 struct scic_sds_phy *sci_phy = phy; 262 struct scic_sds_phy *sci_phy = phy;
263 263
@@ -303,6 +303,7 @@ void scic_sds_phy_construct(
303 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; 303 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
304 this_phy->link_layer_registers = NULL; 304 this_phy->link_layer_registers = NULL;
305 this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE; 305 this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
306 this_phy->sata_timeout_timer = NULL;
306 307
307 /* Clear out the identification buffer data */ 308 /* Clear out the identification buffer data */
308 memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type)); 309 memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type));
@@ -365,8 +366,8 @@ void scic_sds_phy_set_port(
365 */ 366 */
366enum sci_status scic_sds_phy_initialize( 367enum sci_status scic_sds_phy_initialize(
367 struct scic_sds_phy *sci_phy, 368 struct scic_sds_phy *sci_phy,
368 struct scu_transport_layer_registers __iomem *transport_layer_registers, 369 struct scu_transport_layer_registers __iomem *transport_layer_registers,
369 struct scu_link_layer_registers __iomem *link_layer_registers) 370 struct scu_link_layer_registers __iomem *link_layer_registers)
370{ 371{
371 /* Create the SIGNATURE FIS Timeout timer for this phy */ 372 /* Create the SIGNATURE FIS Timeout timer for this phy */
372 sci_phy->sata_timeout_timer = isci_event_timer_create( 373 sci_phy->sata_timeout_timer = isci_event_timer_create(
@@ -757,6 +758,23 @@ static void scic_sds_phy_restart_starting_state(
757 ); 758 );
758} 759}
759 760
761/* ****************************************************************************
762 * SCIC SDS PHY general handlers
763 ************************************************************************** */
764static enum sci_status scic_sds_phy_starting_substate_general_stop_handler(
765 struct sci_base_phy *phy)
766{
767 struct scic_sds_phy *this_phy;
768 this_phy = (struct scic_sds_phy *)phy;
769
770 sci_base_state_machine_stop(&this_phy->starting_substate_machine);
771
772 sci_base_state_machine_change_state(&phy->state_machine,
773 SCI_BASE_PHY_STATE_STOPPED);
774
775 return SCI_SUCCESS;
776}
777
760/* 778/*
761 * ***************************************************************************** 779 * *****************************************************************************
762 * * SCIC SDS PHY EVENT_HANDLERS 780 * * SCIC SDS PHY EVENT_HANDLERS
@@ -1436,12 +1454,10 @@ static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_p
1436 return SCI_SUCCESS; 1454 return SCI_SUCCESS;
1437} 1455}
1438 1456
1439/* --------------------------------------------------------------------------- */
1440
1441const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = { 1457const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = {
1442 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = { 1458 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
1443 .parent.start_handler = scic_sds_phy_default_start_handler, 1459 .parent.start_handler = scic_sds_phy_default_start_handler,
1444 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1460 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1445 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1461 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1446 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1462 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1447 .frame_handler = scic_sds_phy_default_frame_handler, 1463 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1450,7 +1466,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1450 }, 1466 },
1451 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = { 1467 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
1452 .parent.start_handler = scic_sds_phy_default_start_handler, 1468 .parent.start_handler = scic_sds_phy_default_start_handler,
1453 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1469 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1454 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1470 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1455 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1471 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1456 .frame_handler = scic_sds_phy_default_frame_handler, 1472 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1459,7 +1475,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1459 }, 1475 },
1460 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = { 1476 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
1461 .parent.start_handler = scic_sds_phy_default_start_handler, 1477 .parent.start_handler = scic_sds_phy_default_start_handler,
1462 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1478 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1463 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1479 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1464 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1480 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1465 .frame_handler = scic_sds_phy_default_frame_handler, 1481 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1477,7 +1493,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1477 }, 1493 },
1478 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = { 1494 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
1479 .parent.start_handler = scic_sds_phy_default_start_handler, 1495 .parent.start_handler = scic_sds_phy_default_start_handler,
1480 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1496 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1481 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1497 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1482 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1498 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1483 .frame_handler = scic_sds_phy_default_frame_handler, 1499 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1486,7 +1502,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1486 }, 1502 },
1487 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = { 1503 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
1488 .parent.start_handler = scic_sds_phy_default_start_handler, 1504 .parent.start_handler = scic_sds_phy_default_start_handler,
1489 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1505 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1490 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1506 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1491 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1507 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1492 .frame_handler = scic_sds_phy_default_frame_handler, 1508 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1495,7 +1511,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1495 }, 1511 },
1496 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = { 1512 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
1497 .parent.start_handler = scic_sds_phy_default_start_handler, 1513 .parent.start_handler = scic_sds_phy_default_start_handler,
1498 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1514 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1499 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1515 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1500 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1516 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1501 .frame_handler = scic_sds_phy_default_frame_handler, 1517 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1504,7 +1520,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1504 }, 1520 },
1505 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = { 1521 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
1506 .parent.start_handler = scic_sds_phy_default_start_handler, 1522 .parent.start_handler = scic_sds_phy_default_start_handler,
1507 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1523 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1508 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1524 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1509 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1525 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1510 .frame_handler = scic_sds_phy_default_frame_handler, 1526 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -1513,7 +1529,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1513 }, 1529 },
1514 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = { 1530 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
1515 .parent.start_handler = scic_sds_phy_default_start_handler, 1531 .parent.start_handler = scic_sds_phy_default_start_handler,
1516 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1532 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1517 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1533 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1518 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1534 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1519 .frame_handler = scic_sds_phy_starting_substate_await_sig_fis_frame_handler, 1535 .frame_handler = scic_sds_phy_starting_substate_await_sig_fis_frame_handler,
@@ -1522,7 +1538,7 @@ const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_t
1522 }, 1538 },
1523 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = { 1539 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
1524 .parent.start_handler = scic_sds_phy_default_start_handler, 1540 .parent.start_handler = scic_sds_phy_default_start_handler,
1525 .parent.stop_handler = scic_sds_phy_default_stop_handler, 1541 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1526 .parent.reset_handler = scic_sds_phy_default_reset_handler, 1542 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1527 .parent.destruct_handler = scic_sds_phy_default_destroy_handler, 1543 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1528 .frame_handler = scic_sds_phy_default_frame_handler, 1544 .frame_handler = scic_sds_phy_default_frame_handler,
@@ -2153,17 +2169,22 @@ enum sci_status scic_sds_phy_default_consume_power_handler(
2153 * start it. - The phy state machine is transitioned to the 2169 * start it. - The phy state machine is transitioned to the
2154 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS 2170 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2155 */ 2171 */
2156static enum sci_status scic_sds_phy_stopped_state_start_handler( 2172static enum sci_status scic_sds_phy_stopped_state_start_handler(struct sci_base_phy *phy)
2157 struct sci_base_phy *phy)
2158{ 2173{
2159 struct scic_sds_phy *this_phy; 2174 struct scic_sds_phy *this_phy;
2160 2175
2161 this_phy = (struct scic_sds_phy *)phy; 2176 this_phy = (struct scic_sds_phy *)phy;
2162 2177
2163 sci_base_state_machine_change_state( 2178 /* Create the SIGNATURE FIS Timeout timer for this phy */
2164 scic_sds_phy_get_base_state_machine(this_phy), 2179 this_phy->sata_timeout_timer = isci_event_timer_create(
2165 SCI_BASE_PHY_STATE_STARTING 2180 scic_sds_phy_get_controller(this_phy),
2166 ); 2181 scic_sds_phy_sata_timeout, this_phy);
2182
2183 if (this_phy->sata_timeout_timer != NULL) {
2184 sci_base_state_machine_change_state(
2185 scic_sds_phy_get_base_state_machine(this_phy),
2186 SCI_BASE_PHY_STATE_STARTING);
2187 }
2167 2188
2168 return SCI_SUCCESS; 2189 return SCI_SUCCESS;
2169} 2190}
@@ -2185,7 +2206,7 @@ static enum sci_status scic_sds_phy_stopped_state_destroy_handler(
2185 2206
2186 this_phy = (struct scic_sds_phy *)phy; 2207 this_phy = (struct scic_sds_phy *)phy;
2187 2208
2188 /* / @todo what do we actually need to do here? */ 2209 /* @todo what do we actually need to do here? */
2189 return SCI_SUCCESS; 2210 return SCI_SUCCESS;
2190} 2211}
2191 2212
@@ -2500,7 +2521,7 @@ static void scic_sds_phy_initial_state_enter(
2500 2521
2501 this_phy = (struct scic_sds_phy *)object; 2522 this_phy = (struct scic_sds_phy *)object;
2502 2523
2503 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED); 2524 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_INITIAL);
2504} 2525}
2505 2526
2506/** 2527/**
@@ -2512,18 +2533,24 @@ static void scic_sds_phy_initial_state_enter(
2512 * handlers for the phy object base state machine initial state. - The SCU 2533 * handlers for the phy object base state machine initial state. - The SCU
2513 * hardware is requested to stop the protocol engine. none 2534 * hardware is requested to stop the protocol engine. none
2514 */ 2535 */
2515static void scic_sds_phy_stopped_state_enter( 2536static void scic_sds_phy_stopped_state_enter(struct sci_base_object *object)
2516 struct sci_base_object *object)
2517{ 2537{
2518 struct scic_sds_phy *this_phy; 2538 struct scic_sds_phy *sci_phy;
2519 2539
2520 this_phy = (struct scic_sds_phy *)object; 2540 sci_phy = (struct scic_sds_phy *)object;
2521 2541
2522 /* / @todo We need to get to the controller to place this PE in a reset state */ 2542 /* / @todo We need to get to the controller to place this PE in a reset state */
2523 2543
2524 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED); 2544 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_STOPPED);
2525 2545
2526 scu_link_layer_stop_protocol_engine(this_phy); 2546 if (sci_phy->sata_timeout_timer != NULL) {
2547 isci_event_timer_destroy(scic_sds_phy_get_controller(sci_phy),
2548 sci_phy->sata_timeout_timer);
2549
2550 sci_phy->sata_timeout_timer = NULL;
2551 }
2552
2553 scu_link_layer_stop_protocol_engine(sci_phy);
2527} 2554}
2528 2555
2529/** 2556/**
diff --git a/drivers/scsi/isci/core/scic_sds_phy.h b/drivers/scsi/isci/core/scic_sds_phy.h
index dc450c361d91..b611e33180b2 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.h
+++ b/drivers/scsi/isci/core/scic_sds_phy.h
@@ -401,6 +401,9 @@ enum sci_status scic_sds_phy_stop(
401enum sci_status scic_sds_phy_reset( 401enum sci_status scic_sds_phy_reset(
402 struct scic_sds_phy *this_phy); 402 struct scic_sds_phy *this_phy);
403 403
404void scic_sds_phy_sata_timeout(
405 void *cookie);
406
404/* --------------------------------------------------------------------------- */ 407/* --------------------------------------------------------------------------- */
405 408
406void scic_sds_phy_suspend( 409void scic_sds_phy_suspend(
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
index 2a193d30c55d..410c9a104bc0 100644
--- a/drivers/scsi/isci/core/scic_sds_port.c
+++ b/drivers/scsi/isci/core/scic_sds_port.c
@@ -625,27 +625,6 @@ enum sci_status scic_sds_port_initialize(
625 this_port->port_pe_configuration_register = port_configuration_regsiter; 625 this_port->port_pe_configuration_register = port_configuration_regsiter;
626 this_port->viit_registers = viit_registers; 626 this_port->viit_registers = viit_registers;
627 627
628 /*
629 * If this is not the dummy port make the assignment of
630 * the timer and start the state machine */
631 if (this_port->physical_port_index != SCI_MAX_PORTS) {
632 /* / @todo should we create the timer at create time? */
633 this_port->timer_handle = isci_event_timer_create(
634 scic_sds_port_get_controller(this_port),
635 scic_sds_port_timeout_handler,
636 this_port
637 );
638
639 } else {
640 /*
641 * Force the dummy port into a condition where it rejects all requests
642 * as its in an invalid state for any operation.
643 * / @todo should we set a set of specical handlers for the dummy port? */
644 scic_sds_port_set_base_state_handlers(
645 this_port, SCI_BASE_PORT_STATE_STOPPED
646 );
647 }
648
649 return SCI_SUCCESS; 628 return SCI_SUCCESS;
650} 629}
651 630
diff --git a/drivers/scsi/isci/core/scic_sds_remote_device.c b/drivers/scsi/isci/core/scic_sds_remote_device.c
index a7cb4bc39a11..0ac6ca0f3291 100644
--- a/drivers/scsi/isci/core/scic_sds_remote_device.c
+++ b/drivers/scsi/isci/core/scic_sds_remote_device.c
@@ -1822,6 +1822,11 @@ static void scic_sds_remote_device_stopped_state_enter(
1822 SCI_SUCCESS 1822 SCI_SUCCESS
1823 ); 1823 );
1824 } 1824 }
1825
1826 scic_sds_controller_remote_device_stopped(
1827 scic_sds_remote_device_get_controller(this_device),
1828 this_device
1829 );
1825} 1830}
1826 1831
1827/** 1832/**
@@ -1875,6 +1880,11 @@ static void scic_sds_remote_device_starting_state_exit(
1875 this_device, 1880 this_device,
1876 SCI_SUCCESS 1881 SCI_SUCCESS
1877 ); 1882 );
1883
1884 scic_sds_controller_remote_device_started(
1885 scic_sds_remote_device_get_controller(this_device),
1886 this_device
1887 );
1878} 1888}
1879 1889
1880/** 1890/**