aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-05-01 19:26:09 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:45 -0400
commite622571f0f05986b23eba566b73b3abeb5d847d3 (patch)
treec5a35b5467baaa5558c1ae5016215afa4f65c42f
parent978edfef46415badd28974a3e85119e2b764d236 (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.c241
-rw-r--r--drivers/scsi/isci/remote_device.h1
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/** 296static 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 */
304enum 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
317enum 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
311static void scic_sds_remote_device_start_request(struct scic_sds_remote_device *sci_dev, 376static 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(
646static void remote_device_resume_done(void *_dev) 711static 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 */
681static 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 */
739static 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 */
835static 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
844static 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
864static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev, 802static 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
946static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { 884static 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 */
388struct scic_sds_remote_device_state_handler { 388struct 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