diff options
author | Pawel Marek <pawel.marek@intel.com> | 2011-03-01 15:31:06 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:29 -0400 |
commit | c658b109d3a9444293700471a278a741a1e5033d (patch) | |
tree | 2c218e8758eabb496f9bd4c2f3ceef477bc6aa43 | |
parent | 3ff0121a704172aa4bca9c4026b419ddfe1921c8 (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.c | 129 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.h | 29 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_phy.c | 83 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_phy.h | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_port.c | 21 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_remote_device.c | 10 |
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 | */ |
255 | void scic_sds_controller_initialize_phy_startup( | 255 | enum 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 | */ |
308 | static void scic_sds_controller_build_memory_descriptor_table( | 314 | void 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 | |||
1713 | void 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 | */ | ||
1743 | bool 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 | |||
1764 | void 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 | */ | 3559 | void 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 | ||
3482 | const struct scic_sds_controller_state_handler scic_sds_controller_state_handler_table[] = { | 3572 | const 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 { | |||
390 | typedef void (*scic_sds_controller_phy_handler_t)(struct scic_sds_controller *, | 391 | typedef 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 | |||
395 | typedef 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 | ||
407 | extern const struct scic_sds_controller_state_handler | 415 | extern 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 | |||
647 | bool scic_sds_controller_has_remote_devices_stopping( | ||
648 | struct scic_sds_controller *this_controller); | ||
649 | |||
650 | void scic_sds_controller_remote_device_started( | ||
651 | struct scic_sds_controller *this_controller, | ||
652 | struct scic_sds_remote_device *the_device); | ||
653 | |||
654 | void 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( | |||
688 | void scic_sds_controller_reset_hardware( | 713 | void scic_sds_controller_reset_hardware( |
689 | struct scic_sds_controller *this_controller); | 714 | struct scic_sds_controller *this_controller); |
690 | 715 | ||
716 | enum sci_status scic_sds_controller_initialize_phy_startup( | ||
717 | struct scic_sds_controller *this_controller); | ||
691 | 718 | ||
692 | void scic_sds_controller_initialize_phy_startup( | 719 | void 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 | */ |
260 | static void scic_sds_phy_sata_timeout(void *phy) | 260 | void 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 | */ |
366 | enum sci_status scic_sds_phy_initialize( | 367 | enum 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 | ************************************************************************** */ | ||
764 | static 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 | |||
1441 | const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = { | 1457 | const 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 | */ |
2156 | static enum sci_status scic_sds_phy_stopped_state_start_handler( | 2172 | static 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 | */ |
2515 | static void scic_sds_phy_stopped_state_enter( | 2536 | static 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( | |||
401 | enum sci_status scic_sds_phy_reset( | 401 | enum sci_status scic_sds_phy_reset( |
402 | struct scic_sds_phy *this_phy); | 402 | struct scic_sds_phy *this_phy); |
403 | 403 | ||
404 | void scic_sds_phy_sata_timeout( | ||
405 | void *cookie); | ||
406 | |||
404 | /* --------------------------------------------------------------------------- */ | 407 | /* --------------------------------------------------------------------------- */ |
405 | 408 | ||
406 | void scic_sds_phy_suspend( | 409 | void 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 | /** |