diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-05-01 19:26:09 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:45 -0400 |
commit | e622571f0f05986b23eba566b73b3abeb5d847d3 (patch) | |
tree | c5a35b5467baaa5558c1ae5016215afa4f65c42f | |
parent | 978edfef46415badd28974a3e85119e2b764d236 (diff) |
isci: unify remote_device event_handlers
Implement all states in scic_sds_remote_device_event() and delete
the state handler.
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 241 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.h | 1 |
2 files changed, 82 insertions, 160 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 26c5253530ea..53f4ecfddce4 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -293,19 +293,84 @@ enum sci_status scic_sds_remote_device_frame_handler( | |||
293 | return sci_dev->state_handlers->frame_handler(sci_dev, frame_index); | 293 | return sci_dev->state_handlers->frame_handler(sci_dev, frame_index); |
294 | } | 294 | } |
295 | 295 | ||
296 | /** | 296 | static bool is_remote_device_ready(struct scic_sds_remote_device *sci_dev) |
297 | * | ||
298 | * @sci_dev: The remote device for which the event handling is being | ||
299 | * requested. | ||
300 | * @event_code: This is the event code that is to be processed. | ||
301 | * | ||
302 | * This method invokes the remote device event handler. enum sci_status | ||
303 | */ | ||
304 | enum sci_status scic_sds_remote_device_event_handler( | ||
305 | struct scic_sds_remote_device *sci_dev, | ||
306 | u32 event_code) | ||
307 | { | 297 | { |
308 | return sci_dev->state_handlers->event_handler(sci_dev, event_code); | 298 | |
299 | struct sci_base_state_machine *sm = &sci_dev->state_machine; | ||
300 | enum scic_sds_remote_device_states state = sm->current_state_id; | ||
301 | |||
302 | switch (state) { | ||
303 | case SCI_BASE_REMOTE_DEVICE_STATE_READY: | ||
304 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE: | ||
305 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD: | ||
306 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ: | ||
307 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR: | ||
308 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET: | ||
309 | case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE: | ||
310 | case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD: | ||
311 | return true; | ||
312 | default: | ||
313 | return false; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | enum sci_status scic_sds_remote_device_event_handler(struct scic_sds_remote_device *sci_dev, | ||
318 | u32 event_code) | ||
319 | { | ||
320 | struct sci_base_state_machine *sm = &sci_dev->state_machine; | ||
321 | enum scic_sds_remote_device_states state = sm->current_state_id; | ||
322 | enum sci_status status; | ||
323 | |||
324 | switch (scu_get_event_type(event_code)) { | ||
325 | case SCU_EVENT_TYPE_RNC_OPS_MISC: | ||
326 | case SCU_EVENT_TYPE_RNC_SUSPEND_TX: | ||
327 | case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: | ||
328 | status = scic_sds_remote_node_context_event_handler(&sci_dev->rnc, event_code); | ||
329 | break; | ||
330 | case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT: | ||
331 | if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) { | ||
332 | status = SCI_SUCCESS; | ||
333 | |||
334 | /* Suspend the associated RNC */ | ||
335 | scic_sds_remote_node_context_suspend(&sci_dev->rnc, | ||
336 | SCI_SOFTWARE_SUSPENSION, | ||
337 | NULL, NULL); | ||
338 | |||
339 | dev_dbg(scirdev_to_dev(sci_dev), | ||
340 | "%s: device: %p event code: %x: %s\n", | ||
341 | __func__, sci_dev, event_code, | ||
342 | is_remote_device_ready(sci_dev) | ||
343 | ? "I_T_Nexus_Timeout event" | ||
344 | : "I_T_Nexus_Timeout event in wrong state"); | ||
345 | |||
346 | break; | ||
347 | } | ||
348 | /* Else, fall through and treat as unhandled... */ | ||
349 | default: | ||
350 | dev_dbg(scirdev_to_dev(sci_dev), | ||
351 | "%s: device: %p event code: %x: %s\n", | ||
352 | __func__, sci_dev, event_code, | ||
353 | is_remote_device_ready(sci_dev) | ||
354 | ? "unexpected event" | ||
355 | : "unexpected event in wrong state"); | ||
356 | status = SCI_FAILURE_INVALID_STATE; | ||
357 | break; | ||
358 | } | ||
359 | |||
360 | if (status != SCI_SUCCESS) | ||
361 | return status; | ||
362 | |||
363 | if (state == SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE) { | ||
364 | |||
365 | /* We pick up suspension events to handle specifically to this | ||
366 | * state. We resume the RNC right away. | ||
367 | */ | ||
368 | if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || | ||
369 | scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) | ||
370 | status = scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL); | ||
371 | } | ||
372 | |||
373 | return status; | ||
309 | } | 374 | } |
310 | 375 | ||
311 | static void scic_sds_remote_device_start_request(struct scic_sds_remote_device *sci_dev, | 376 | static void scic_sds_remote_device_start_request(struct scic_sds_remote_device *sci_dev, |
@@ -646,103 +711,13 @@ void scic_sds_remote_device_post_request( | |||
646 | static void remote_device_resume_done(void *_dev) | 711 | static void remote_device_resume_done(void *_dev) |
647 | { | 712 | { |
648 | struct scic_sds_remote_device *sci_dev = _dev; | 713 | struct scic_sds_remote_device *sci_dev = _dev; |
649 | enum scic_sds_remote_device_states state; | ||
650 | 714 | ||
651 | state = sci_dev->state_machine.current_state_id; | 715 | if (is_remote_device_ready(sci_dev)) |
652 | switch (state) { | 716 | return; |
653 | case SCI_BASE_REMOTE_DEVICE_STATE_READY: | ||
654 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE: | ||
655 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD: | ||
656 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ: | ||
657 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR: | ||
658 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET: | ||
659 | case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE: | ||
660 | case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD: | ||
661 | break; | ||
662 | default: | ||
663 | /* go 'ready' if we are not already in a ready state */ | ||
664 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
665 | SCI_BASE_REMOTE_DEVICE_STATE_READY); | ||
666 | break; | ||
667 | } | ||
668 | } | ||
669 | 717 | ||
670 | /** | 718 | /* go 'ready' if we are not already in a ready state */ |
671 | * | 719 | sci_base_state_machine_change_state(&sci_dev->state_machine, |
672 | * @device: The struct scic_sds_remote_device which is then cast into a | 720 | SCI_BASE_REMOTE_DEVICE_STATE_READY); |
673 | * struct scic_sds_remote_device. | ||
674 | * @event_code: The event code that the struct scic_sds_controller wants the device | ||
675 | * object to process. | ||
676 | * | ||
677 | * This method is the default event handler. It will call the RNC state | ||
678 | * machine handler for any RNC events otherwise it will log a warning and | ||
679 | * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE | ||
680 | */ | ||
681 | static enum sci_status scic_sds_remote_device_core_event_handler( | ||
682 | struct scic_sds_remote_device *sci_dev, | ||
683 | u32 event_code, | ||
684 | bool is_ready_state) | ||
685 | { | ||
686 | enum sci_status status; | ||
687 | |||
688 | switch (scu_get_event_type(event_code)) { | ||
689 | case SCU_EVENT_TYPE_RNC_OPS_MISC: | ||
690 | case SCU_EVENT_TYPE_RNC_SUSPEND_TX: | ||
691 | case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: | ||
692 | status = scic_sds_remote_node_context_event_handler(&sci_dev->rnc, event_code); | ||
693 | break; | ||
694 | case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT: | ||
695 | |||
696 | if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) { | ||
697 | status = SCI_SUCCESS; | ||
698 | |||
699 | /* Suspend the associated RNC */ | ||
700 | scic_sds_remote_node_context_suspend(&sci_dev->rnc, | ||
701 | SCI_SOFTWARE_SUSPENSION, | ||
702 | NULL, NULL); | ||
703 | |||
704 | dev_dbg(scirdev_to_dev(sci_dev), | ||
705 | "%s: device: %p event code: %x: %s\n", | ||
706 | __func__, sci_dev, event_code, | ||
707 | (is_ready_state) | ||
708 | ? "I_T_Nexus_Timeout event" | ||
709 | : "I_T_Nexus_Timeout event in wrong state"); | ||
710 | |||
711 | break; | ||
712 | } | ||
713 | /* Else, fall through and treat as unhandled... */ | ||
714 | |||
715 | default: | ||
716 | dev_dbg(scirdev_to_dev(sci_dev), | ||
717 | "%s: device: %p event code: %x: %s\n", | ||
718 | __func__, sci_dev, event_code, | ||
719 | (is_ready_state) | ||
720 | ? "unexpected event" | ||
721 | : "unexpected event in wrong state"); | ||
722 | status = SCI_FAILURE_INVALID_STATE; | ||
723 | break; | ||
724 | } | ||
725 | |||
726 | return status; | ||
727 | } | ||
728 | /** | ||
729 | * | ||
730 | * @device: The struct scic_sds_remote_device which is then cast into a | ||
731 | * struct scic_sds_remote_device. | ||
732 | * @event_code: The event code that the struct scic_sds_controller wants the device | ||
733 | * object to process. | ||
734 | * | ||
735 | * This method is the default event handler. It will call the RNC state | ||
736 | * machine handler for any RNC events otherwise it will log a warning and | ||
737 | * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE | ||
738 | */ | ||
739 | static enum sci_status scic_sds_remote_device_default_event_handler( | ||
740 | struct scic_sds_remote_device *sci_dev, | ||
741 | u32 event_code) | ||
742 | { | ||
743 | return scic_sds_remote_device_core_event_handler(sci_dev, | ||
744 | event_code, | ||
745 | false); | ||
746 | } | 721 | } |
747 | 722 | ||
748 | /** | 723 | /** |
@@ -824,43 +799,6 @@ static enum sci_status scic_sds_remote_device_general_frame_handler( | |||
824 | return result; | 799 | return result; |
825 | } | 800 | } |
826 | 801 | ||
827 | /** | ||
828 | * | ||
829 | * @[in]: sci_dev This is the device object that is receiving the event. | ||
830 | * @[in]: event_code The event code to process. | ||
831 | * | ||
832 | * This is a common method for handling events reported to the remote device | ||
833 | * from the controller object. enum sci_status | ||
834 | */ | ||
835 | static enum sci_status scic_sds_remote_device_general_event_handler( | ||
836 | struct scic_sds_remote_device *sci_dev, | ||
837 | u32 event_code) | ||
838 | { | ||
839 | return scic_sds_remote_device_core_event_handler(sci_dev, | ||
840 | event_code, | ||
841 | true); | ||
842 | } | ||
843 | |||
844 | static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler( | ||
845 | struct scic_sds_remote_device *sci_dev, | ||
846 | u32 event_code) | ||
847 | { | ||
848 | enum sci_status status; | ||
849 | |||
850 | status = scic_sds_remote_device_general_event_handler(sci_dev, event_code); | ||
851 | if (status != SCI_SUCCESS) | ||
852 | return status; | ||
853 | |||
854 | /* We pick up suspension events to handle specifically to this state. We | ||
855 | * resume the RNC right away. enum sci_status | ||
856 | */ | ||
857 | if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || | ||
858 | scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) | ||
859 | status = scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL); | ||
860 | |||
861 | return status; | ||
862 | } | ||
863 | |||
864 | static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev, | 802 | static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev, |
865 | u32 frame_index) | 803 | u32 frame_index) |
866 | { | 804 | { |
@@ -945,63 +883,48 @@ static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handl | |||
945 | 883 | ||
946 | static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { | 884 | static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { |
947 | [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { | 885 | [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { |
948 | .event_handler = scic_sds_remote_device_default_event_handler, | ||
949 | .frame_handler = scic_sds_remote_device_default_frame_handler | 886 | .frame_handler = scic_sds_remote_device_default_frame_handler |
950 | }, | 887 | }, |
951 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = { | 888 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = { |
952 | .event_handler = scic_sds_remote_device_default_event_handler, | ||
953 | .frame_handler = scic_sds_remote_device_default_frame_handler | 889 | .frame_handler = scic_sds_remote_device_default_frame_handler |
954 | }, | 890 | }, |
955 | [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = { | 891 | [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = { |
956 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
957 | .frame_handler = scic_sds_remote_device_default_frame_handler | 892 | .frame_handler = scic_sds_remote_device_default_frame_handler |
958 | }, | 893 | }, |
959 | [SCI_BASE_REMOTE_DEVICE_STATE_READY] = { | 894 | [SCI_BASE_REMOTE_DEVICE_STATE_READY] = { |
960 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
961 | .frame_handler = scic_sds_remote_device_general_frame_handler, | 895 | .frame_handler = scic_sds_remote_device_general_frame_handler, |
962 | }, | 896 | }, |
963 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | 897 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { |
964 | .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler, | ||
965 | .frame_handler = scic_sds_remote_device_default_frame_handler | 898 | .frame_handler = scic_sds_remote_device_default_frame_handler |
966 | }, | 899 | }, |
967 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | 900 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { |
968 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
969 | .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler | 901 | .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler |
970 | }, | 902 | }, |
971 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { | 903 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { |
972 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
973 | .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler | 904 | .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler |
974 | }, | 905 | }, |
975 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { | 906 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { |
976 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
977 | .frame_handler = scic_sds_remote_device_general_frame_handler | 907 | .frame_handler = scic_sds_remote_device_general_frame_handler |
978 | }, | 908 | }, |
979 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { | 909 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { |
980 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
981 | .frame_handler = scic_sds_remote_device_general_frame_handler | 910 | .frame_handler = scic_sds_remote_device_general_frame_handler |
982 | }, | 911 | }, |
983 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | 912 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { |
984 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
985 | .frame_handler = scic_sds_remote_device_default_frame_handler | 913 | .frame_handler = scic_sds_remote_device_default_frame_handler |
986 | }, | 914 | }, |
987 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | 915 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { |
988 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
989 | .frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler | 916 | .frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler |
990 | }, | 917 | }, |
991 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { | 918 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { |
992 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
993 | .frame_handler = scic_sds_remote_device_general_frame_handler | 919 | .frame_handler = scic_sds_remote_device_general_frame_handler |
994 | }, | 920 | }, |
995 | [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = { | 921 | [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = { |
996 | .event_handler = scic_sds_remote_device_default_event_handler, | ||
997 | .frame_handler = scic_sds_remote_device_general_frame_handler | 922 | .frame_handler = scic_sds_remote_device_general_frame_handler |
998 | }, | 923 | }, |
999 | [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = { | 924 | [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = { |
1000 | .event_handler = scic_sds_remote_device_default_event_handler, | ||
1001 | .frame_handler = scic_sds_remote_device_general_frame_handler | 925 | .frame_handler = scic_sds_remote_device_general_frame_handler |
1002 | }, | 926 | }, |
1003 | [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = { | 927 | [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = { |
1004 | .event_handler = scic_sds_remote_device_default_event_handler, | ||
1005 | .frame_handler = scic_sds_remote_device_default_frame_handler | 928 | .frame_handler = scic_sds_remote_device_default_frame_handler |
1006 | } | 929 | } |
1007 | }; | 930 | }; |
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h index bb8d17391c95..e376ec2ff369 100644 --- a/drivers/scsi/isci/remote_device.h +++ b/drivers/scsi/isci/remote_device.h | |||
@@ -386,7 +386,6 @@ typedef void (*scic_sds_remote_device_ready_not_ready_handler_t)( | |||
386 | * | 386 | * |
387 | */ | 387 | */ |
388 | struct scic_sds_remote_device_state_handler { | 388 | struct scic_sds_remote_device_state_handler { |
389 | scic_sds_remote_device_event_handler_t event_handler; | ||
390 | scic_sds_remote_device_frame_handler_t frame_handler; | 389 | scic_sds_remote_device_frame_handler_t frame_handler; |
391 | }; | 390 | }; |
392 | 391 | ||