diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/isci/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 960 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.h | 208 | ||||
-rw-r--r-- | drivers/scsi/isci/smp_remote_device.c | 310 | ||||
-rw-r--r-- | drivers/scsi/isci/stp_remote_device.c | 716 |
5 files changed, 800 insertions, 1396 deletions
diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile index fc50ba34b13d..c27d25999123 100644 --- a/drivers/scsi/isci/Makefile +++ b/drivers/scsi/isci/Makefile | |||
@@ -7,8 +7,6 @@ obj-$(CONFIG_SCSI_ISCI) += isci.o | |||
7 | isci-objs := init.o phy.o request.o sata.o \ | 7 | isci-objs := init.o phy.o request.o sata.o \ |
8 | remote_device.o port.o timers.o \ | 8 | remote_device.o port.o timers.o \ |
9 | host.o task.o probe_roms.o \ | 9 | host.o task.o probe_roms.o \ |
10 | stp_remote_device.o \ | ||
11 | smp_remote_device.o \ | ||
12 | remote_node_context.o \ | 10 | remote_node_context.o \ |
13 | remote_node_table.o \ | 11 | remote_node_table.o \ |
14 | core/scic_sds_controller.o \ | 12 | core/scic_sds_controller.o \ |
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 2bbc7c20c400..f6da85e3f2af 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -53,6 +53,7 @@ | |||
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
54 | */ | 54 | */ |
55 | #include "intel_sas.h" | 55 | #include "intel_sas.h" |
56 | #include "intel_ata.h" | ||
56 | #include "isci.h" | 57 | #include "isci.h" |
57 | #include "port.h" | 58 | #include "port.h" |
58 | #include "remote_device.h" | 59 | #include "remote_device.h" |
@@ -71,6 +72,65 @@ | |||
71 | #include "scu_event_codes.h" | 72 | #include "scu_event_codes.h" |
72 | #include "task.h" | 73 | #include "task.h" |
73 | 74 | ||
75 | /** | ||
76 | * isci_remote_device_change_state() - This function gets the status of the | ||
77 | * remote_device object. | ||
78 | * @isci_device: This parameter points to the isci_remote_device object | ||
79 | * | ||
80 | * status of the object as a isci_status enum. | ||
81 | */ | ||
82 | void isci_remote_device_change_state( | ||
83 | struct isci_remote_device *isci_device, | ||
84 | enum isci_status status) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | |||
88 | spin_lock_irqsave(&isci_device->state_lock, flags); | ||
89 | isci_device->status = status; | ||
90 | spin_unlock_irqrestore(&isci_device->state_lock, flags); | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * isci_remote_device_not_ready() - This function is called by the scic when | ||
95 | * the remote device is not ready. We mark the isci device as ready (not | ||
96 | * "ready_for_io") and signal the waiting proccess. | ||
97 | * @isci_host: This parameter specifies the isci host object. | ||
98 | * @isci_device: This parameter specifies the remote device | ||
99 | * | ||
100 | */ | ||
101 | static void isci_remote_device_not_ready(struct isci_host *ihost, | ||
102 | struct isci_remote_device *idev, u32 reason) | ||
103 | { | ||
104 | dev_dbg(&ihost->pdev->dev, | ||
105 | "%s: isci_device = %p\n", __func__, idev); | ||
106 | |||
107 | if (reason == SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED) | ||
108 | isci_remote_device_change_state(idev, isci_stopping); | ||
109 | else | ||
110 | /* device ready is actually a "not ready for io" state. */ | ||
111 | isci_remote_device_change_state(idev, isci_ready); | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * isci_remote_device_ready() - This function is called by the scic when the | ||
116 | * remote device is ready. We mark the isci device as ready and signal the | ||
117 | * waiting proccess. | ||
118 | * @ihost: our valid isci_host | ||
119 | * @idev: remote device | ||
120 | * | ||
121 | */ | ||
122 | static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote_device *idev) | ||
123 | { | ||
124 | dev_dbg(&ihost->pdev->dev, | ||
125 | "%s: idev = %p\n", __func__, idev); | ||
126 | |||
127 | isci_remote_device_change_state(idev, isci_ready_for_io); | ||
128 | if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags)) | ||
129 | wake_up(&ihost->eventq); | ||
130 | } | ||
131 | |||
132 | |||
133 | |||
74 | enum sci_status scic_remote_device_stop( | 134 | enum sci_status scic_remote_device_stop( |
75 | struct scic_sds_remote_device *sci_dev, | 135 | struct scic_sds_remote_device *sci_dev, |
76 | u32 timeout) | 136 | u32 timeout) |
@@ -228,49 +288,43 @@ void scic_sds_remote_device_post_request( | |||
228 | ); | 288 | ); |
229 | } | 289 | } |
230 | 290 | ||
231 | /** | 291 | /* called once the remote node context is ready to be freed. |
232 | * | ||
233 | * @user_parameter: This is cast to a remote device object. | ||
234 | * | ||
235 | * This method is called once the remote node context is ready to be freed. | ||
236 | * The remote device can now report that its stop operation is complete. none | 292 | * The remote device can now report that its stop operation is complete. none |
237 | */ | 293 | */ |
238 | static void scic_sds_cb_remote_device_rnc_destruct_complete( | 294 | static void scic_sds_cb_remote_device_rnc_destruct_complete(void *_dev) |
239 | void *user_parameter) | ||
240 | { | 295 | { |
241 | struct scic_sds_remote_device *sci_dev; | 296 | struct scic_sds_remote_device *sci_dev = _dev; |
242 | |||
243 | sci_dev = (struct scic_sds_remote_device *)user_parameter; | ||
244 | 297 | ||
245 | BUG_ON(sci_dev->started_request_count != 0); | 298 | BUG_ON(sci_dev->started_request_count != 0); |
246 | |||
247 | sci_base_state_machine_change_state(&sci_dev->state_machine, | 299 | sci_base_state_machine_change_state(&sci_dev->state_machine, |
248 | SCI_BASE_REMOTE_DEVICE_STATE_STOPPED); | 300 | SCI_BASE_REMOTE_DEVICE_STATE_STOPPED); |
249 | } | 301 | } |
250 | 302 | ||
251 | /** | 303 | /* called once the remote node context has transisitioned to a |
252 | * | ||
253 | * @user_parameter: This is cast to a remote device object. | ||
254 | * | ||
255 | * This method is called once the remote node context has transisitioned to a | ||
256 | * ready state. This is the indication that the remote device object can also | 304 | * ready state. This is the indication that the remote device object can also |
257 | * transition to ready. none | 305 | * transition to ready. |
258 | */ | 306 | */ |
259 | static void scic_sds_remote_device_resume_complete_handler( | 307 | static void scic_sds_remote_device_resume_complete_handler(void *_dev) |
260 | void *user_parameter) | 308 | { |
261 | { | 309 | struct scic_sds_remote_device *sci_dev = _dev; |
262 | struct scic_sds_remote_device *sci_dev; | 310 | enum scic_sds_remote_device_states state; |
263 | 311 | ||
264 | sci_dev = (struct scic_sds_remote_device *)user_parameter; | 312 | state = sci_dev->state_machine.current_state_id; |
265 | 313 | switch (state) { | |
266 | if ( | 314 | case SCI_BASE_REMOTE_DEVICE_STATE_READY: |
267 | sci_base_state_machine_get_state(&sci_dev->state_machine) | 315 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE: |
268 | != SCI_BASE_REMOTE_DEVICE_STATE_READY | 316 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD: |
269 | ) { | 317 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ: |
270 | sci_base_state_machine_change_state( | 318 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR: |
271 | &sci_dev->state_machine, | 319 | case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET: |
272 | SCI_BASE_REMOTE_DEVICE_STATE_READY | 320 | case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE: |
273 | ); | 321 | case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD: |
322 | break; | ||
323 | default: | ||
324 | /* go 'ready' if we are not already in a ready state */ | ||
325 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
326 | SCI_BASE_REMOTE_DEVICE_STATE_READY); | ||
327 | break; | ||
274 | } | 328 | } |
275 | } | 329 | } |
276 | 330 | ||
@@ -284,7 +338,7 @@ static void scic_sds_remote_device_resume_complete_handler( | |||
284 | * This method will perform the STP request start processing common to IO | 338 | * This method will perform the STP request start processing common to IO |
285 | * requests and task requests of all types. none | 339 | * requests and task requests of all types. none |
286 | */ | 340 | */ |
287 | void scic_sds_remote_device_start_request( | 341 | static void scic_sds_remote_device_start_request( |
288 | struct scic_sds_remote_device *sci_dev, | 342 | struct scic_sds_remote_device *sci_dev, |
289 | struct scic_sds_request *sci_req, | 343 | struct scic_sds_request *sci_req, |
290 | enum sci_status status) | 344 | enum sci_status status) |
@@ -308,7 +362,7 @@ void scic_sds_remote_device_start_request( | |||
308 | * serves as a callback when RNC gets resumed during a task management | 362 | * serves as a callback when RNC gets resumed during a task management |
309 | * sequence. none | 363 | * sequence. none |
310 | */ | 364 | */ |
311 | void scic_sds_remote_device_continue_request(void *dev) | 365 | static void scic_sds_remote_device_continue_request(void *dev) |
312 | { | 366 | { |
313 | struct scic_sds_remote_device *sci_dev = dev; | 367 | struct scic_sds_remote_device *sci_dev = dev; |
314 | 368 | ||
@@ -368,7 +422,7 @@ default_device_handler(struct scic_sds_remote_device *sci_dev, | |||
368 | return SCI_FAILURE_INVALID_STATE; | 422 | return SCI_FAILURE_INVALID_STATE; |
369 | } | 423 | } |
370 | 424 | ||
371 | enum sci_status scic_sds_remote_device_default_start_handler( | 425 | static enum sci_status scic_sds_remote_device_default_start_handler( |
372 | struct scic_sds_remote_device *sci_dev) | 426 | struct scic_sds_remote_device *sci_dev) |
373 | { | 427 | { |
374 | return default_device_handler(sci_dev, __func__); | 428 | return default_device_handler(sci_dev, __func__); |
@@ -380,37 +434,37 @@ static enum sci_status scic_sds_remote_device_default_stop_handler( | |||
380 | return default_device_handler(sci_dev, __func__); | 434 | return default_device_handler(sci_dev, __func__); |
381 | } | 435 | } |
382 | 436 | ||
383 | enum sci_status scic_sds_remote_device_default_fail_handler( | 437 | static enum sci_status scic_sds_remote_device_default_fail_handler( |
384 | struct scic_sds_remote_device *sci_dev) | 438 | struct scic_sds_remote_device *sci_dev) |
385 | { | 439 | { |
386 | return default_device_handler(sci_dev, __func__); | 440 | return default_device_handler(sci_dev, __func__); |
387 | } | 441 | } |
388 | 442 | ||
389 | enum sci_status scic_sds_remote_device_default_destruct_handler( | 443 | static enum sci_status scic_sds_remote_device_default_destruct_handler( |
390 | struct scic_sds_remote_device *sci_dev) | 444 | struct scic_sds_remote_device *sci_dev) |
391 | { | 445 | { |
392 | return default_device_handler(sci_dev, __func__); | 446 | return default_device_handler(sci_dev, __func__); |
393 | } | 447 | } |
394 | 448 | ||
395 | enum sci_status scic_sds_remote_device_default_reset_handler( | 449 | static enum sci_status scic_sds_remote_device_default_reset_handler( |
396 | struct scic_sds_remote_device *sci_dev) | 450 | struct scic_sds_remote_device *sci_dev) |
397 | { | 451 | { |
398 | return default_device_handler(sci_dev, __func__); | 452 | return default_device_handler(sci_dev, __func__); |
399 | } | 453 | } |
400 | 454 | ||
401 | enum sci_status scic_sds_remote_device_default_reset_complete_handler( | 455 | static enum sci_status scic_sds_remote_device_default_reset_complete_handler( |
402 | struct scic_sds_remote_device *sci_dev) | 456 | struct scic_sds_remote_device *sci_dev) |
403 | { | 457 | { |
404 | return default_device_handler(sci_dev, __func__); | 458 | return default_device_handler(sci_dev, __func__); |
405 | } | 459 | } |
406 | 460 | ||
407 | enum sci_status scic_sds_remote_device_default_suspend_handler( | 461 | static enum sci_status scic_sds_remote_device_default_suspend_handler( |
408 | struct scic_sds_remote_device *sci_dev, u32 suspend_type) | 462 | struct scic_sds_remote_device *sci_dev, u32 suspend_type) |
409 | { | 463 | { |
410 | return default_device_handler(sci_dev, __func__); | 464 | return default_device_handler(sci_dev, __func__); |
411 | } | 465 | } |
412 | 466 | ||
413 | enum sci_status scic_sds_remote_device_default_resume_handler( | 467 | static enum sci_status scic_sds_remote_device_default_resume_handler( |
414 | struct scic_sds_remote_device *sci_dev) | 468 | struct scic_sds_remote_device *sci_dev) |
415 | { | 469 | { |
416 | return default_device_handler(sci_dev, __func__); | 470 | return default_device_handler(sci_dev, __func__); |
@@ -505,7 +559,7 @@ static enum sci_status scic_sds_remote_device_default_event_handler( | |||
505 | * releases the frame and returns a failure. enum sci_status | 559 | * releases the frame and returns a failure. enum sci_status |
506 | * SCI_FAILURE_INVALID_STATE | 560 | * SCI_FAILURE_INVALID_STATE |
507 | */ | 561 | */ |
508 | enum sci_status scic_sds_remote_device_default_frame_handler( | 562 | static enum sci_status scic_sds_remote_device_default_frame_handler( |
509 | struct scic_sds_remote_device *sci_dev, | 563 | struct scic_sds_remote_device *sci_dev, |
510 | u32 frame_index) | 564 | u32 frame_index) |
511 | { | 565 | { |
@@ -525,21 +579,21 @@ enum sci_status scic_sds_remote_device_default_frame_handler( | |||
525 | return SCI_FAILURE_INVALID_STATE; | 579 | return SCI_FAILURE_INVALID_STATE; |
526 | } | 580 | } |
527 | 581 | ||
528 | enum sci_status scic_sds_remote_device_default_start_request_handler( | 582 | static enum sci_status scic_sds_remote_device_default_start_request_handler( |
529 | struct scic_sds_remote_device *sci_dev, | 583 | struct scic_sds_remote_device *sci_dev, |
530 | struct scic_sds_request *request) | 584 | struct scic_sds_request *request) |
531 | { | 585 | { |
532 | return default_device_handler(sci_dev, __func__); | 586 | return default_device_handler(sci_dev, __func__); |
533 | } | 587 | } |
534 | 588 | ||
535 | enum sci_status scic_sds_remote_device_default_complete_request_handler( | 589 | static enum sci_status scic_sds_remote_device_default_complete_request_handler( |
536 | struct scic_sds_remote_device *sci_dev, | 590 | struct scic_sds_remote_device *sci_dev, |
537 | struct scic_sds_request *request) | 591 | struct scic_sds_request *request) |
538 | { | 592 | { |
539 | return default_device_handler(sci_dev, __func__); | 593 | return default_device_handler(sci_dev, __func__); |
540 | } | 594 | } |
541 | 595 | ||
542 | enum sci_status scic_sds_remote_device_default_continue_request_handler( | 596 | static enum sci_status scic_sds_remote_device_default_continue_request_handler( |
543 | struct scic_sds_remote_device *sci_dev, | 597 | struct scic_sds_remote_device *sci_dev, |
544 | struct scic_sds_request *request) | 598 | struct scic_sds_request *request) |
545 | { | 599 | { |
@@ -558,7 +612,7 @@ enum sci_status scic_sds_remote_device_default_continue_request_handler( | |||
558 | * This method decodes the tag for the io request object and routes the | 612 | * This method decodes the tag for the io request object and routes the |
559 | * unsolicited frame to that object. enum sci_status SCI_FAILURE_INVALID_STATE | 613 | * unsolicited frame to that object. enum sci_status SCI_FAILURE_INVALID_STATE |
560 | */ | 614 | */ |
561 | enum sci_status scic_sds_remote_device_general_frame_handler( | 615 | static enum sci_status scic_sds_remote_device_general_frame_handler( |
562 | struct scic_sds_remote_device *sci_dev, | 616 | struct scic_sds_remote_device *sci_dev, |
563 | u32 frame_index) | 617 | u32 frame_index) |
564 | { | 618 | { |
@@ -602,7 +656,7 @@ enum sci_status scic_sds_remote_device_general_frame_handler( | |||
602 | * This is a common method for handling events reported to the remote device | 656 | * This is a common method for handling events reported to the remote device |
603 | * from the controller object. enum sci_status | 657 | * from the controller object. enum sci_status |
604 | */ | 658 | */ |
605 | enum sci_status scic_sds_remote_device_general_event_handler( | 659 | static enum sci_status scic_sds_remote_device_general_event_handler( |
606 | struct scic_sds_remote_device *sci_dev, | 660 | struct scic_sds_remote_device *sci_dev, |
607 | u32 event_code) | 661 | u32 event_code) |
608 | { | 662 | { |
@@ -705,7 +759,7 @@ static enum sci_status scic_sds_remote_device_starting_state_stop_handler( | |||
705 | return SCI_SUCCESS; | 759 | return SCI_SUCCESS; |
706 | } | 760 | } |
707 | 761 | ||
708 | enum sci_status scic_sds_remote_device_ready_state_stop_handler( | 762 | static enum sci_status scic_sds_remote_device_ready_state_stop_handler( |
709 | struct scic_sds_remote_device *sci_dev) | 763 | struct scic_sds_remote_device *sci_dev) |
710 | { | 764 | { |
711 | enum sci_status status = SCI_SUCCESS; | 765 | enum sci_status status = SCI_SUCCESS; |
@@ -731,7 +785,7 @@ enum sci_status scic_sds_remote_device_ready_state_stop_handler( | |||
731 | * | 785 | * |
732 | * This is the ready state device reset handler enum sci_status | 786 | * This is the ready state device reset handler enum sci_status |
733 | */ | 787 | */ |
734 | enum sci_status scic_sds_remote_device_ready_state_reset_handler( | 788 | static enum sci_status scic_sds_remote_device_ready_state_reset_handler( |
735 | struct scic_sds_remote_device *sci_dev) | 789 | struct scic_sds_remote_device *sci_dev) |
736 | { | 790 | { |
737 | /* Request the parent state machine to transition to the stopping state */ | 791 | /* Request the parent state machine to transition to the stopping state */ |
@@ -893,34 +947,15 @@ static enum sci_status scic_sds_remote_device_stopping_state_complete_request_ha | |||
893 | return SCI_SUCCESS; | 947 | return SCI_SUCCESS; |
894 | } | 948 | } |
895 | 949 | ||
896 | /** | ||
897 | * | ||
898 | * @device: The struct scic_sds_remote_device which is to be cast into a | ||
899 | * struct scic_sds_remote_device object. | ||
900 | * | ||
901 | * This method will complete the reset operation when the device is in the | ||
902 | * resetting state. enum sci_status | ||
903 | */ | ||
904 | static enum sci_status scic_sds_remote_device_resetting_state_reset_complete_handler( | 950 | static enum sci_status scic_sds_remote_device_resetting_state_reset_complete_handler( |
905 | struct scic_sds_remote_device *sci_dev) | 951 | struct scic_sds_remote_device *sci_dev) |
906 | { | 952 | { |
907 | 953 | sci_base_state_machine_change_state(&sci_dev->state_machine, | |
908 | sci_base_state_machine_change_state( | 954 | SCI_BASE_REMOTE_DEVICE_STATE_READY); |
909 | &sci_dev->state_machine, | ||
910 | SCI_BASE_REMOTE_DEVICE_STATE_READY | ||
911 | ); | ||
912 | 955 | ||
913 | return SCI_SUCCESS; | 956 | return SCI_SUCCESS; |
914 | } | 957 | } |
915 | 958 | ||
916 | /** | ||
917 | * | ||
918 | * @device: The struct scic_sds_remote_device which is to be cast into a | ||
919 | * struct scic_sds_remote_device object. | ||
920 | * | ||
921 | * This method will stop the remote device while in the resetting state. | ||
922 | * enum sci_status | ||
923 | */ | ||
924 | static enum sci_status scic_sds_remote_device_resetting_state_stop_handler( | 959 | static enum sci_status scic_sds_remote_device_resetting_state_stop_handler( |
925 | struct scic_sds_remote_device *sci_dev) | 960 | struct scic_sds_remote_device *sci_dev) |
926 | { | 961 | { |
@@ -932,12 +967,11 @@ static enum sci_status scic_sds_remote_device_resetting_state_stop_handler( | |||
932 | return SCI_SUCCESS; | 967 | return SCI_SUCCESS; |
933 | } | 968 | } |
934 | 969 | ||
935 | /* | 970 | /* complete requests for this device while it is in the |
936 | * This method completes requests for this struct scic_sds_remote_device while it is | 971 | * SCI_BASE_REMOTE_DEVICE_STATE_RESETTING state. This method calls the complete |
937 | * in the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING state. This method calls the | 972 | * method for the request object and if that is successful the port object is |
938 | * complete method for the request object and if that is successful the port | 973 | * called to complete the task request. Then the device object itself completes |
939 | * object is called to complete the task request. Then the device object itself | 974 | * the task request. enum sci_status |
940 | * completes the task request. enum sci_status | ||
941 | */ | 975 | */ |
942 | static enum sci_status scic_sds_remote_device_resetting_state_complete_request_handler( | 976 | static enum sci_status scic_sds_remote_device_resetting_state_complete_request_handler( |
943 | struct scic_sds_remote_device *sci_dev, | 977 | struct scic_sds_remote_device *sci_dev, |
@@ -960,6 +994,397 @@ static enum sci_status scic_sds_remote_device_resetting_state_complete_request_h | |||
960 | return status; | 994 | return status; |
961 | } | 995 | } |
962 | 996 | ||
997 | static enum sci_status scic_sds_stp_remote_device_complete_request(struct scic_sds_remote_device *sci_dev, | ||
998 | struct scic_sds_request *sci_req) | ||
999 | { | ||
1000 | enum sci_status status; | ||
1001 | |||
1002 | status = scic_sds_io_request_complete(sci_req); | ||
1003 | if (status != SCI_SUCCESS) | ||
1004 | goto out; | ||
1005 | |||
1006 | status = scic_sds_port_complete_io(sci_dev->owning_port, sci_dev, sci_req); | ||
1007 | if (status != SCI_SUCCESS) | ||
1008 | goto out; | ||
1009 | |||
1010 | scic_sds_remote_device_decrement_request_count(sci_dev); | ||
1011 | if (sci_req->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) { | ||
1012 | /* This request causes hardware error, device needs to be Lun Reset. | ||
1013 | * So here we force the state machine to IDLE state so the rest IOs | ||
1014 | * can reach RNC state handler, these IOs will be completed by RNC with | ||
1015 | * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". | ||
1016 | */ | ||
1017 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1018 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET); | ||
1019 | } else if (scic_sds_remote_device_get_request_count(sci_dev) == 0) | ||
1020 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1021 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1022 | |||
1023 | |||
1024 | out: | ||
1025 | if (status != SCI_SUCCESS) | ||
1026 | dev_err(scirdev_to_dev(sci_dev), | ||
1027 | "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x " | ||
1028 | "could not complete\n", __func__, sci_dev->owning_port, | ||
1029 | sci_dev, sci_req, status); | ||
1030 | |||
1031 | return status; | ||
1032 | } | ||
1033 | |||
1034 | /* scic_sds_stp_remote_device_ready_substate_start_request_handler - start stp | ||
1035 | * @device: The target device a task management request towards to. | ||
1036 | * @request: The task request. | ||
1037 | * | ||
1038 | * This is the READY NCQ substate handler to start task management request. In | ||
1039 | * this routine, we suspend and resume the RNC. enum sci_status Always return | ||
1040 | * SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to let | ||
1041 | * controller_start_task_handler know that the controller can't post TC for | ||
1042 | * task request yet, instead, when RNC gets resumed, a controller_continue_task | ||
1043 | * callback will be called. | ||
1044 | */ | ||
1045 | static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler( | ||
1046 | struct scic_sds_remote_device *device, | ||
1047 | struct scic_sds_request *request) | ||
1048 | { | ||
1049 | enum sci_status status; | ||
1050 | |||
1051 | /* Will the port allow the io request to start? */ | ||
1052 | status = device->owning_port->state_handlers->start_io_handler( | ||
1053 | device->owning_port, device, request); | ||
1054 | if (status != SCI_SUCCESS) | ||
1055 | return status; | ||
1056 | |||
1057 | status = scic_sds_remote_node_context_start_task(&device->rnc, request); | ||
1058 | if (status != SCI_SUCCESS) | ||
1059 | goto out; | ||
1060 | |||
1061 | status = request->state_handlers->start_handler(request); | ||
1062 | if (status != SCI_SUCCESS) | ||
1063 | goto out; | ||
1064 | |||
1065 | /* | ||
1066 | * Note: If the remote device state is not IDLE this will replace | ||
1067 | * the request that probably resulted in the task management request. | ||
1068 | */ | ||
1069 | device->working_request = request; | ||
1070 | sci_base_state_machine_change_state(&device->state_machine, | ||
1071 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
1072 | |||
1073 | /* | ||
1074 | * The remote node context must cleanup the TCi to NCQ mapping table. | ||
1075 | * The only way to do this correctly is to either write to the TLCR | ||
1076 | * register or to invalidate and repost the RNC. In either case the | ||
1077 | * remote node context state machine will take the correct action when | ||
1078 | * the remote node context is suspended and later resumed. | ||
1079 | */ | ||
1080 | scic_sds_remote_node_context_suspend(&device->rnc, | ||
1081 | SCI_SOFTWARE_SUSPENSION, NULL, NULL); | ||
1082 | scic_sds_remote_node_context_resume(&device->rnc, | ||
1083 | scic_sds_remote_device_continue_request, | ||
1084 | device); | ||
1085 | |||
1086 | out: | ||
1087 | scic_sds_remote_device_start_request(device, request, status); | ||
1088 | /* | ||
1089 | * We need to let the controller start request handler know that it can't | ||
1090 | * post TC yet. We will provide a callback function to post TC when RNC gets | ||
1091 | * resumed. | ||
1092 | */ | ||
1093 | return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS; | ||
1094 | } | ||
1095 | |||
1096 | /* handle the start io operation for a sata device that is in the command idle | ||
1097 | * state. - Evalute the type of IO request to be started - If its an NCQ | ||
1098 | * request change to NCQ substate - If its any other command change to the CMD | ||
1099 | * substate | ||
1100 | * | ||
1101 | * If this is a softreset we may want to have a different substate. | ||
1102 | */ | ||
1103 | static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler( | ||
1104 | struct scic_sds_remote_device *sci_dev, | ||
1105 | struct scic_sds_request *request) | ||
1106 | { | ||
1107 | enum sci_status status; | ||
1108 | struct isci_request *isci_request = request->ireq; | ||
1109 | enum scic_sds_remote_device_states new_state; | ||
1110 | |||
1111 | /* Will the port allow the io request to start? */ | ||
1112 | status = sci_dev->owning_port->state_handlers->start_io_handler( | ||
1113 | sci_dev->owning_port, sci_dev, request); | ||
1114 | if (status != SCI_SUCCESS) | ||
1115 | return status; | ||
1116 | |||
1117 | status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request); | ||
1118 | if (status != SCI_SUCCESS) | ||
1119 | goto out; | ||
1120 | |||
1121 | status = request->state_handlers->start_handler(request); | ||
1122 | if (status != SCI_SUCCESS) | ||
1123 | goto out; | ||
1124 | |||
1125 | if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) | ||
1126 | new_state = SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ; | ||
1127 | else { | ||
1128 | sci_dev->working_request = request; | ||
1129 | new_state = SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD; | ||
1130 | } | ||
1131 | sci_base_state_machine_change_state(&sci_dev->state_machine, new_state); | ||
1132 | out: | ||
1133 | scic_sds_remote_device_start_request(sci_dev, request, status); | ||
1134 | return status; | ||
1135 | } | ||
1136 | |||
1137 | |||
1138 | static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler( | ||
1139 | struct scic_sds_remote_device *sci_dev, | ||
1140 | u32 event_code) | ||
1141 | { | ||
1142 | enum sci_status status; | ||
1143 | |||
1144 | status = scic_sds_remote_device_general_event_handler(sci_dev, event_code); | ||
1145 | if (status != SCI_SUCCESS) | ||
1146 | return status; | ||
1147 | |||
1148 | /* We pick up suspension events to handle specifically to this state. We | ||
1149 | * resume the RNC right away. enum sci_status | ||
1150 | */ | ||
1151 | if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || | ||
1152 | scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) | ||
1153 | status = scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL); | ||
1154 | |||
1155 | return status; | ||
1156 | } | ||
1157 | |||
1158 | static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler( | ||
1159 | struct scic_sds_remote_device *sci_dev, | ||
1160 | struct scic_sds_request *request) | ||
1161 | { | ||
1162 | enum sci_status status; | ||
1163 | struct isci_request *isci_request = request->ireq; | ||
1164 | scic_sds_port_io_request_handler_t start_io; | ||
1165 | |||
1166 | if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) { | ||
1167 | start_io = sci_dev->owning_port->state_handlers->start_io_handler; | ||
1168 | status = start_io(sci_dev->owning_port, sci_dev, request); | ||
1169 | if (status != SCI_SUCCESS) | ||
1170 | return status; | ||
1171 | |||
1172 | status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request); | ||
1173 | if (status != SCI_SUCCESS) | ||
1174 | return status; | ||
1175 | |||
1176 | status = request->state_handlers->start_handler(request); | ||
1177 | |||
1178 | scic_sds_remote_device_start_request(sci_dev, request, status); | ||
1179 | } else | ||
1180 | status = SCI_FAILURE_INVALID_STATE; | ||
1181 | |||
1182 | return status; | ||
1183 | } | ||
1184 | |||
1185 | static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev, | ||
1186 | u32 frame_index) | ||
1187 | { | ||
1188 | enum sci_status status; | ||
1189 | struct sata_fis_header *frame_header; | ||
1190 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; | ||
1191 | |||
1192 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1193 | frame_index, | ||
1194 | (void **)&frame_header); | ||
1195 | if (status != SCI_SUCCESS) | ||
1196 | return status; | ||
1197 | |||
1198 | if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS && | ||
1199 | (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) { | ||
1200 | sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; | ||
1201 | |||
1202 | /* TODO Check sactive and complete associated IO if any. */ | ||
1203 | |||
1204 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1205 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR); | ||
1206 | } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H && | ||
1207 | (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) { | ||
1208 | /* | ||
1209 | * Some devices return D2H FIS when an NCQ error is detected. | ||
1210 | * Treat this like an SDB error FIS ready reason. | ||
1211 | */ | ||
1212 | sci_dev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; | ||
1213 | |||
1214 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1215 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR); | ||
1216 | } else | ||
1217 | status = SCI_FAILURE; | ||
1218 | |||
1219 | scic_sds_controller_release_frame(scic, frame_index); | ||
1220 | |||
1221 | return status; | ||
1222 | } | ||
1223 | |||
1224 | static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler( | ||
1225 | struct scic_sds_remote_device *device, | ||
1226 | struct scic_sds_request *request) | ||
1227 | { | ||
1228 | /* device is already handling a command it can not accept new commands | ||
1229 | * until this one is complete. | ||
1230 | */ | ||
1231 | return SCI_FAILURE_INVALID_STATE; | ||
1232 | } | ||
1233 | |||
1234 | static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler( | ||
1235 | struct scic_sds_remote_device *sci_dev, | ||
1236 | u32 suspend_type) | ||
1237 | { | ||
1238 | enum sci_status status; | ||
1239 | |||
1240 | status = scic_sds_remote_node_context_suspend(&sci_dev->rnc, | ||
1241 | suspend_type, NULL, NULL); | ||
1242 | |||
1243 | return status; | ||
1244 | } | ||
1245 | |||
1246 | static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler( | ||
1247 | struct scic_sds_remote_device *sci_dev, | ||
1248 | u32 frame_index) | ||
1249 | { | ||
1250 | /* The device doe not process any UF received from the hardware while | ||
1251 | * in this state. All unsolicited frames are forwarded to the io | ||
1252 | * request object. | ||
1253 | */ | ||
1254 | return scic_sds_io_request_frame_handler(sci_dev->working_request, | ||
1255 | frame_index); | ||
1256 | } | ||
1257 | |||
1258 | static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler( | ||
1259 | struct scic_sds_remote_device *device, | ||
1260 | struct scic_sds_request *request) | ||
1261 | { | ||
1262 | return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; | ||
1263 | } | ||
1264 | |||
1265 | static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler( | ||
1266 | struct scic_sds_remote_device *device, | ||
1267 | struct scic_sds_request *request) | ||
1268 | { | ||
1269 | struct scic_sds_request *sci_req = request; | ||
1270 | enum sci_status status; | ||
1271 | |||
1272 | status = scic_sds_io_request_complete(sci_req); | ||
1273 | if (status != SCI_SUCCESS) | ||
1274 | goto out; | ||
1275 | |||
1276 | status = scic_sds_port_complete_io(device->owning_port, device, sci_req); | ||
1277 | if (status != SCI_SUCCESS) | ||
1278 | goto out; | ||
1279 | |||
1280 | scic_sds_remote_device_decrement_request_count(device); | ||
1281 | out: | ||
1282 | if (status != SCI_SUCCESS) | ||
1283 | dev_err(scirdev_to_dev(device), | ||
1284 | "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x " | ||
1285 | "could not complete\n", | ||
1286 | __func__, device->owning_port, device, sci_req, status); | ||
1287 | |||
1288 | return status; | ||
1289 | } | ||
1290 | |||
1291 | static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *_dev) | ||
1292 | { | ||
1293 | struct scic_sds_remote_device *sci_dev = _dev; | ||
1294 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
1295 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; | ||
1296 | |||
1297 | /* For NCQ operation we do not issue a isci_remote_device_not_ready(). | ||
1298 | * As a result, avoid sending the ready notification. | ||
1299 | */ | ||
1300 | if (sci_dev->state_machine.previous_state_id != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) | ||
1301 | isci_remote_device_ready(scic->ihost, idev); | ||
1302 | } | ||
1303 | |||
1304 | static enum sci_status scic_sds_smp_remote_device_ready_idle_substate_start_io_handler( | ||
1305 | struct scic_sds_remote_device *sci_dev, | ||
1306 | struct scic_sds_request *sci_req) | ||
1307 | { | ||
1308 | enum sci_status status; | ||
1309 | |||
1310 | /* Will the port allow the io request to start? */ | ||
1311 | status = sci_dev->owning_port->state_handlers->start_io_handler( | ||
1312 | sci_dev->owning_port, sci_dev, sci_req); | ||
1313 | if (status != SCI_SUCCESS) | ||
1314 | return status; | ||
1315 | |||
1316 | status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, sci_req); | ||
1317 | if (status != SCI_SUCCESS) | ||
1318 | return status; | ||
1319 | |||
1320 | status = scic_sds_request_start(sci_req); | ||
1321 | if (status != SCI_SUCCESS) | ||
1322 | return status; | ||
1323 | |||
1324 | sci_dev->working_request = sci_req; | ||
1325 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1326 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
1327 | |||
1328 | scic_sds_remote_device_start_request(sci_dev, sci_req, status); | ||
1329 | |||
1330 | return status; | ||
1331 | } | ||
1332 | |||
1333 | static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler( | ||
1334 | struct scic_sds_remote_device *device, | ||
1335 | struct scic_sds_request *request) | ||
1336 | { | ||
1337 | /* device is already handling a command it can not accept new commands | ||
1338 | * until this one is complete. | ||
1339 | */ | ||
1340 | return SCI_FAILURE_INVALID_STATE; | ||
1341 | } | ||
1342 | |||
1343 | static enum sci_status | ||
1344 | scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler(struct scic_sds_remote_device *sci_dev, | ||
1345 | struct scic_sds_request *sci_req) | ||
1346 | { | ||
1347 | enum sci_status status; | ||
1348 | |||
1349 | status = scic_sds_io_request_complete(sci_req); | ||
1350 | if (status != SCI_SUCCESS) | ||
1351 | return status; | ||
1352 | |||
1353 | status = scic_sds_port_complete_io(sci_dev->owning_port, sci_dev, sci_req); | ||
1354 | if (status != SCI_SUCCESS) { | ||
1355 | dev_err(scirdev_to_dev(sci_dev), | ||
1356 | "%s: SCIC SDS Remote Device 0x%p io request " | ||
1357 | "0x%p could not be completd on the port 0x%p " | ||
1358 | "failed with status %d.\n", __func__, sci_dev, sci_req, | ||
1359 | sci_dev->owning_port, status); | ||
1360 | return status; | ||
1361 | } | ||
1362 | |||
1363 | scic_sds_remote_device_decrement_request_count(sci_dev); | ||
1364 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1365 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1366 | |||
1367 | return status; | ||
1368 | } | ||
1369 | |||
1370 | static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handler( | ||
1371 | struct scic_sds_remote_device *sci_dev, | ||
1372 | u32 frame_index) | ||
1373 | { | ||
1374 | enum sci_status status; | ||
1375 | |||
1376 | /* The device does not process any UF received from the hardware while | ||
1377 | * in this state. All unsolicited frames are forwarded to the io request | ||
1378 | * object. | ||
1379 | */ | ||
1380 | status = scic_sds_io_request_frame_handler( | ||
1381 | sci_dev->working_request, | ||
1382 | frame_index | ||
1383 | ); | ||
1384 | |||
1385 | return status; | ||
1386 | } | ||
1387 | |||
963 | static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { | 1388 | static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { |
964 | [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { | 1389 | [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { |
965 | .start_handler = scic_sds_remote_device_default_start_handler, | 1390 | .start_handler = scic_sds_remote_device_default_start_handler, |
@@ -1029,6 +1454,125 @@ static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_ | |||
1029 | .event_handler = scic_sds_remote_device_general_event_handler, | 1454 | .event_handler = scic_sds_remote_device_general_event_handler, |
1030 | .frame_handler = scic_sds_remote_device_general_frame_handler, | 1455 | .frame_handler = scic_sds_remote_device_general_frame_handler, |
1031 | }, | 1456 | }, |
1457 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
1458 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1459 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1460 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1461 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1462 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
1463 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1464 | .start_io_handler = scic_sds_stp_remote_device_ready_idle_substate_start_io_handler, | ||
1465 | .complete_io_handler = scic_sds_remote_device_default_complete_request_handler, | ||
1466 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1467 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
1468 | .complete_task_handler = scic_sds_remote_device_default_complete_request_handler, | ||
1469 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
1470 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1471 | .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler, | ||
1472 | .frame_handler = scic_sds_remote_device_default_frame_handler | ||
1473 | }, | ||
1474 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
1475 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1476 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1477 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1478 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1479 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
1480 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1481 | .start_io_handler = scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler, | ||
1482 | .complete_io_handler = scic_sds_stp_remote_device_complete_request, | ||
1483 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1484 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
1485 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
1486 | .suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler, | ||
1487 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1488 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
1489 | .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler | ||
1490 | }, | ||
1491 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { | ||
1492 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1493 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1494 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1495 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1496 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
1497 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1498 | .start_io_handler = scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler, | ||
1499 | .complete_io_handler = scic_sds_stp_remote_device_complete_request, | ||
1500 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1501 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
1502 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
1503 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
1504 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1505 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
1506 | .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler | ||
1507 | }, | ||
1508 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { | ||
1509 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1510 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1511 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1512 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1513 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
1514 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1515 | .start_io_handler = scic_sds_remote_device_default_start_request_handler, | ||
1516 | .complete_io_handler = scic_sds_stp_remote_device_complete_request, | ||
1517 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1518 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
1519 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
1520 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
1521 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1522 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
1523 | .frame_handler = scic_sds_remote_device_general_frame_handler | ||
1524 | }, | ||
1525 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { | ||
1526 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1527 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1528 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1529 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1530 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
1531 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1532 | .start_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler, | ||
1533 | .complete_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler, | ||
1534 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1535 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
1536 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
1537 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
1538 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1539 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
1540 | .frame_handler = scic_sds_remote_device_general_frame_handler | ||
1541 | }, | ||
1542 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
1543 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1544 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1545 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1546 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1547 | .reset_handler = scic_sds_remote_device_default_reset_handler, | ||
1548 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1549 | .start_io_handler = scic_sds_smp_remote_device_ready_idle_substate_start_io_handler, | ||
1550 | .complete_io_handler = scic_sds_remote_device_default_complete_request_handler, | ||
1551 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1552 | .start_task_handler = scic_sds_remote_device_default_start_request_handler, | ||
1553 | .complete_task_handler = scic_sds_remote_device_default_complete_request_handler, | ||
1554 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
1555 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1556 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
1557 | .frame_handler = scic_sds_remote_device_default_frame_handler | ||
1558 | }, | ||
1559 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
1560 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
1561 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
1562 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
1563 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
1564 | .reset_handler = scic_sds_remote_device_default_reset_handler, | ||
1565 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
1566 | .start_io_handler = scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler, | ||
1567 | .complete_io_handler = scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler, | ||
1568 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
1569 | .start_task_handler = scic_sds_remote_device_default_start_request_handler, | ||
1570 | .complete_task_handler = scic_sds_remote_device_default_complete_request_handler, | ||
1571 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
1572 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
1573 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
1574 | .frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler | ||
1575 | }, | ||
1032 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { | 1576 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { |
1033 | .start_handler = scic_sds_remote_device_default_start_handler, | 1577 | .start_handler = scic_sds_remote_device_default_start_handler, |
1034 | .stop_handler = scic_sds_remote_device_stopping_state_stop_handler, | 1578 | .stop_handler = scic_sds_remote_device_stopping_state_stop_handler, |
@@ -1112,24 +1656,6 @@ static void scic_sds_remote_device_initial_state_enter(void *object) | |||
1112 | } | 1656 | } |
1113 | 1657 | ||
1114 | /** | 1658 | /** |
1115 | * isci_remote_device_change_state() - This function gets the status of the | ||
1116 | * remote_device object. | ||
1117 | * @isci_device: This parameter points to the isci_remote_device object | ||
1118 | * | ||
1119 | * status of the object as a isci_status enum. | ||
1120 | */ | ||
1121 | void isci_remote_device_change_state( | ||
1122 | struct isci_remote_device *isci_device, | ||
1123 | enum isci_status status) | ||
1124 | { | ||
1125 | unsigned long flags; | ||
1126 | |||
1127 | spin_lock_irqsave(&isci_device->state_lock, flags); | ||
1128 | isci_device->status = status; | ||
1129 | spin_unlock_irqrestore(&isci_device->state_lock, flags); | ||
1130 | } | ||
1131 | |||
1132 | /** | ||
1133 | * scic_remote_device_destruct() - free remote node context and destruct | 1659 | * scic_remote_device_destruct() - free remote node context and destruct |
1134 | * @remote_device: This parameter specifies the remote device to be destructed. | 1660 | * @remote_device: This parameter specifies the remote device to be destructed. |
1135 | * | 1661 | * |
@@ -1242,9 +1768,8 @@ static void scic_sds_remote_device_starting_state_enter(void *object) | |||
1242 | static void scic_sds_remote_device_ready_state_enter(void *object) | 1768 | static void scic_sds_remote_device_ready_state_enter(void *object) |
1243 | { | 1769 | { |
1244 | struct scic_sds_remote_device *sci_dev = object; | 1770 | struct scic_sds_remote_device *sci_dev = object; |
1245 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | 1771 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; |
1246 | struct isci_host *ihost = scic->ihost; | 1772 | struct domain_device *dev = sci_dev_to_domain(sci_dev); |
1247 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
1248 | 1773 | ||
1249 | SET_STATE_HANDLER(sci_dev, | 1774 | SET_STATE_HANDLER(sci_dev, |
1250 | scic_sds_remote_device_state_handler_table, | 1775 | scic_sds_remote_device_state_handler_table, |
@@ -1252,23 +1777,26 @@ static void scic_sds_remote_device_ready_state_enter(void *object) | |||
1252 | 1777 | ||
1253 | scic->remote_device_sequence[sci_dev->rnc.remote_node_index]++; | 1778 | scic->remote_device_sequence[sci_dev->rnc.remote_node_index]++; |
1254 | 1779 | ||
1255 | if (sci_dev->has_ready_substate_machine) | 1780 | if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) { |
1256 | sci_base_state_machine_start(&sci_dev->ready_substate_machine); | 1781 | sci_base_state_machine_change_state(&sci_dev->state_machine, |
1257 | else | 1782 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); |
1258 | isci_remote_device_ready(ihost, idev); | 1783 | } else if (dev_is_expander(dev)) { |
1784 | sci_base_state_machine_change_state(&sci_dev->state_machine, | ||
1785 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1786 | } else | ||
1787 | isci_remote_device_ready(scic->ihost, sci_dev_to_idev(sci_dev)); | ||
1259 | } | 1788 | } |
1260 | 1789 | ||
1261 | static void scic_sds_remote_device_ready_state_exit(void *object) | 1790 | static void scic_sds_remote_device_ready_state_exit(void *object) |
1262 | { | 1791 | { |
1263 | struct scic_sds_remote_device *sci_dev = object; | 1792 | struct scic_sds_remote_device *sci_dev = object; |
1264 | if (sci_dev->has_ready_substate_machine) | 1793 | struct domain_device *dev = sci_dev_to_domain(sci_dev); |
1265 | sci_base_state_machine_stop(&sci_dev->ready_substate_machine); | 1794 | |
1266 | else { | 1795 | if (dev->dev_type == SAS_END_DEV) { |
1267 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | 1796 | struct scic_sds_controller *scic = sci_dev->owning_port->owning_controller; |
1268 | struct isci_host *ihost = scic->ihost; | ||
1269 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | 1797 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); |
1270 | 1798 | ||
1271 | isci_remote_device_not_ready(ihost, idev, | 1799 | isci_remote_device_not_ready(scic->ihost, idev, |
1272 | SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED); | 1800 | SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED); |
1273 | } | 1801 | } |
1274 | } | 1802 | } |
@@ -1327,6 +1855,101 @@ static void scic_sds_remote_device_final_state_enter(void *object) | |||
1327 | ); | 1855 | ); |
1328 | } | 1856 | } |
1329 | 1857 | ||
1858 | static void scic_sds_stp_remote_device_ready_idle_substate_enter(void *object) | ||
1859 | { | ||
1860 | struct scic_sds_remote_device *sci_dev = object; | ||
1861 | |||
1862 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1863 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1864 | |||
1865 | sci_dev->working_request = NULL; | ||
1866 | if (scic_sds_remote_node_context_is_ready(&sci_dev->rnc)) { | ||
1867 | /* | ||
1868 | * Since the RNC is ready, it's alright to finish completion | ||
1869 | * processing (e.g. signal the remote device is ready). */ | ||
1870 | scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(sci_dev); | ||
1871 | } else { | ||
1872 | scic_sds_remote_node_context_resume(&sci_dev->rnc, | ||
1873 | scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler, | ||
1874 | sci_dev); | ||
1875 | } | ||
1876 | } | ||
1877 | |||
1878 | static void scic_sds_stp_remote_device_ready_cmd_substate_enter(void *object) | ||
1879 | { | ||
1880 | struct scic_sds_remote_device *sci_dev = object; | ||
1881 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
1882 | |||
1883 | BUG_ON(sci_dev->working_request == NULL); | ||
1884 | |||
1885 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1886 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
1887 | |||
1888 | isci_remote_device_not_ready(scic->ihost, sci_dev_to_idev(sci_dev), | ||
1889 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED); | ||
1890 | } | ||
1891 | |||
1892 | static void scic_sds_stp_remote_device_ready_ncq_substate_enter(void *object) | ||
1893 | { | ||
1894 | struct scic_sds_remote_device *sci_dev = object; | ||
1895 | |||
1896 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1897 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ); | ||
1898 | } | ||
1899 | |||
1900 | static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(void *object) | ||
1901 | { | ||
1902 | struct scic_sds_remote_device *sci_dev = object; | ||
1903 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
1904 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
1905 | |||
1906 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1907 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR); | ||
1908 | |||
1909 | if (sci_dev->not_ready_reason == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) | ||
1910 | isci_remote_device_not_ready(scic->ihost, idev, | ||
1911 | sci_dev->not_ready_reason); | ||
1912 | } | ||
1913 | |||
1914 | static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(void *object) | ||
1915 | { | ||
1916 | struct scic_sds_remote_device *sci_dev = object; | ||
1917 | |||
1918 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1919 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET); | ||
1920 | } | ||
1921 | |||
1922 | static void scic_sds_smp_remote_device_ready_idle_substate_enter(void *object) | ||
1923 | { | ||
1924 | struct scic_sds_remote_device *sci_dev = object; | ||
1925 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
1926 | |||
1927 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1928 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1929 | |||
1930 | isci_remote_device_ready(scic->ihost, sci_dev_to_idev(sci_dev)); | ||
1931 | } | ||
1932 | |||
1933 | static void scic_sds_smp_remote_device_ready_cmd_substate_enter(void *object) | ||
1934 | { | ||
1935 | struct scic_sds_remote_device *sci_dev = object; | ||
1936 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
1937 | |||
1938 | BUG_ON(sci_dev->working_request == NULL); | ||
1939 | |||
1940 | SET_STATE_HANDLER(sci_dev, scic_sds_remote_device_state_handler_table, | ||
1941 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
1942 | |||
1943 | isci_remote_device_not_ready(scic->ihost, sci_dev_to_idev(sci_dev), | ||
1944 | SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED); | ||
1945 | } | ||
1946 | |||
1947 | static void scic_sds_smp_remote_device_ready_cmd_substate_exit(void *object) | ||
1948 | { | ||
1949 | struct scic_sds_remote_device *sci_dev = object; | ||
1950 | |||
1951 | sci_dev->working_request = NULL; | ||
1952 | } | ||
1330 | 1953 | ||
1331 | static const struct sci_base_state scic_sds_remote_device_state_table[] = { | 1954 | static const struct sci_base_state scic_sds_remote_device_state_table[] = { |
1332 | [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { | 1955 | [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { |
@@ -1342,6 +1965,28 @@ static const struct sci_base_state scic_sds_remote_device_state_table[] = { | |||
1342 | .enter_state = scic_sds_remote_device_ready_state_enter, | 1965 | .enter_state = scic_sds_remote_device_ready_state_enter, |
1343 | .exit_state = scic_sds_remote_device_ready_state_exit | 1966 | .exit_state = scic_sds_remote_device_ready_state_exit |
1344 | }, | 1967 | }, |
1968 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
1969 | .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter, | ||
1970 | }, | ||
1971 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
1972 | .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter, | ||
1973 | }, | ||
1974 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { | ||
1975 | .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter, | ||
1976 | }, | ||
1977 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { | ||
1978 | .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter, | ||
1979 | }, | ||
1980 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { | ||
1981 | .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter, | ||
1982 | }, | ||
1983 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
1984 | .enter_state = scic_sds_smp_remote_device_ready_idle_substate_enter, | ||
1985 | }, | ||
1986 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
1987 | .enter_state = scic_sds_smp_remote_device_ready_cmd_substate_enter, | ||
1988 | .exit_state = scic_sds_smp_remote_device_ready_cmd_substate_exit, | ||
1989 | }, | ||
1345 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { | 1990 | [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { |
1346 | .enter_state = scic_sds_remote_device_stopping_state_enter, | 1991 | .enter_state = scic_sds_remote_device_stopping_state_enter, |
1347 | }, | 1992 | }, |
@@ -1406,7 +2051,6 @@ static enum sci_status scic_remote_device_da_construct(struct scic_sds_port *sci | |||
1406 | struct scic_sds_remote_device *sci_dev) | 2051 | struct scic_sds_remote_device *sci_dev) |
1407 | { | 2052 | { |
1408 | enum sci_status status; | 2053 | enum sci_status status; |
1409 | u16 remote_node_index; | ||
1410 | struct domain_device *dev = sci_dev_to_domain(sci_dev); | 2054 | struct domain_device *dev = sci_dev_to_domain(sci_dev); |
1411 | 2055 | ||
1412 | scic_remote_device_construct(sci_port, sci_dev); | 2056 | scic_remote_device_construct(sci_port, sci_dev); |
@@ -1418,33 +2062,15 @@ static enum sci_status scic_remote_device_da_construct(struct scic_sds_port *sci | |||
1418 | sci_dev->is_direct_attached = true; | 2062 | sci_dev->is_direct_attached = true; |
1419 | status = scic_sds_controller_allocate_remote_node_context(sci_port->owning_controller, | 2063 | status = scic_sds_controller_allocate_remote_node_context(sci_port->owning_controller, |
1420 | sci_dev, | 2064 | sci_dev, |
1421 | &remote_node_index); | 2065 | &sci_dev->rnc.remote_node_index); |
1422 | 2066 | ||
1423 | if (status != SCI_SUCCESS) | 2067 | if (status != SCI_SUCCESS) |
1424 | return status; | 2068 | return status; |
1425 | 2069 | ||
1426 | sci_dev->rnc.remote_node_index = remote_node_index; | 2070 | if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV || |
1427 | 2071 | (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev)) | |
1428 | if (dev->dev_type == SAS_END_DEV) | 2072 | /* pass */; |
1429 | sci_dev->has_ready_substate_machine = false; | 2073 | else |
1430 | else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { | ||
1431 | sci_dev->has_ready_substate_machine = true; | ||
1432 | |||
1433 | sci_base_state_machine_construct( | ||
1434 | &sci_dev->ready_substate_machine, | ||
1435 | sci_dev, | ||
1436 | scic_sds_stp_remote_device_ready_substate_table, | ||
1437 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1438 | } else if (dev_is_expander(dev)) { | ||
1439 | sci_dev->has_ready_substate_machine = true; | ||
1440 | |||
1441 | /* add the SMP ready substate machine construction here */ | ||
1442 | sci_base_state_machine_construct( | ||
1443 | &sci_dev->ready_substate_machine, | ||
1444 | sci_dev, | ||
1445 | scic_sds_smp_remote_device_ready_substate_table, | ||
1446 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1447 | } else | ||
1448 | return SCI_FAILURE_UNSUPPORTED_PROTOCOL; | 2074 | return SCI_FAILURE_UNSUPPORTED_PROTOCOL; |
1449 | 2075 | ||
1450 | sci_dev->connection_rate = scic_sds_port_get_max_allowed_speed(sci_port); | 2076 | sci_dev->connection_rate = scic_sds_port_get_max_allowed_speed(sci_port); |
@@ -1470,37 +2096,22 @@ static enum sci_status scic_remote_device_da_construct(struct scic_sds_port *sci | |||
1470 | static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci_port, | 2096 | static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci_port, |
1471 | struct scic_sds_remote_device *sci_dev) | 2097 | struct scic_sds_remote_device *sci_dev) |
1472 | { | 2098 | { |
1473 | struct scic_sds_controller *scic = sci_port->owning_controller; | ||
1474 | struct domain_device *dev = sci_dev_to_domain(sci_dev); | 2099 | struct domain_device *dev = sci_dev_to_domain(sci_dev); |
1475 | enum sci_status status; | 2100 | enum sci_status status; |
1476 | 2101 | ||
1477 | scic_remote_device_construct(sci_port, sci_dev); | 2102 | scic_remote_device_construct(sci_port, sci_dev); |
1478 | 2103 | ||
1479 | status = scic_sds_controller_allocate_remote_node_context( | 2104 | status = scic_sds_controller_allocate_remote_node_context(sci_port->owning_controller, |
1480 | scic, sci_dev, &sci_dev->rnc.remote_node_index); | 2105 | sci_dev, |
2106 | &sci_dev->rnc.remote_node_index); | ||
1481 | if (status != SCI_SUCCESS) | 2107 | if (status != SCI_SUCCESS) |
1482 | return status; | 2108 | return status; |
1483 | 2109 | ||
1484 | if (dev->dev_type == SAS_END_DEV) | 2110 | if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV || |
1485 | sci_dev->has_ready_substate_machine = false; | 2111 | (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev)) |
1486 | else if (dev_is_expander(dev)) { | 2112 | /* pass */; |
1487 | sci_dev->has_ready_substate_machine = true; | 2113 | else |
1488 | 2114 | return SCI_FAILURE_UNSUPPORTED_PROTOCOL; | |
1489 | /* add the SMP ready substate machine construction here */ | ||
1490 | sci_base_state_machine_construct( | ||
1491 | &sci_dev->ready_substate_machine, | ||
1492 | sci_dev, | ||
1493 | scic_sds_smp_remote_device_ready_substate_table, | ||
1494 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1495 | } else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { | ||
1496 | sci_dev->has_ready_substate_machine = true; | ||
1497 | |||
1498 | sci_base_state_machine_construct( | ||
1499 | &sci_dev->ready_substate_machine, | ||
1500 | sci_dev, | ||
1501 | scic_sds_stp_remote_device_ready_substate_table, | ||
1502 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
1503 | } | ||
1504 | 2115 | ||
1505 | /* | 2116 | /* |
1506 | * For SAS-2 the physical link rate is actually a logical link | 2117 | * For SAS-2 the physical link rate is actually a logical link |
@@ -1515,7 +2126,7 @@ static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci | |||
1515 | /* / @todo Should I assign the port width by reading all of the phys on the port? */ | 2126 | /* / @todo Should I assign the port width by reading all of the phys on the port? */ |
1516 | sci_dev->device_port_width = 1; | 2127 | sci_dev->device_port_width = 1; |
1517 | 2128 | ||
1518 | return status; | 2129 | return SCI_SUCCESS; |
1519 | } | 2130 | } |
1520 | 2131 | ||
1521 | /** | 2132 | /** |
@@ -1618,45 +2229,6 @@ isci_remote_device_alloc(struct isci_host *ihost, struct isci_port *iport) | |||
1618 | } | 2229 | } |
1619 | 2230 | ||
1620 | /** | 2231 | /** |
1621 | * isci_remote_device_ready() - This function is called by the scic when the | ||
1622 | * remote device is ready. We mark the isci device as ready and signal the | ||
1623 | * waiting proccess. | ||
1624 | * @ihost: our valid isci_host | ||
1625 | * @idev: remote device | ||
1626 | * | ||
1627 | */ | ||
1628 | void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote_device *idev) | ||
1629 | { | ||
1630 | dev_dbg(&ihost->pdev->dev, | ||
1631 | "%s: idev = %p\n", __func__, idev); | ||
1632 | |||
1633 | isci_remote_device_change_state(idev, isci_ready_for_io); | ||
1634 | if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags)) | ||
1635 | wake_up(&ihost->eventq); | ||
1636 | } | ||
1637 | |||
1638 | /** | ||
1639 | * isci_remote_device_not_ready() - This function is called by the scic when | ||
1640 | * the remote device is not ready. We mark the isci device as ready (not | ||
1641 | * "ready_for_io") and signal the waiting proccess. | ||
1642 | * @isci_host: This parameter specifies the isci host object. | ||
1643 | * @isci_device: This parameter specifies the remote device | ||
1644 | * | ||
1645 | */ | ||
1646 | void isci_remote_device_not_ready(struct isci_host *ihost, | ||
1647 | struct isci_remote_device *idev, u32 reason) | ||
1648 | { | ||
1649 | dev_dbg(&ihost->pdev->dev, | ||
1650 | "%s: isci_device = %p\n", __func__, idev); | ||
1651 | |||
1652 | if (reason == SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED) | ||
1653 | isci_remote_device_change_state(idev, isci_stopping); | ||
1654 | else | ||
1655 | /* device ready is actually a "not ready for io" state. */ | ||
1656 | isci_remote_device_change_state(idev, isci_ready); | ||
1657 | } | ||
1658 | |||
1659 | /** | ||
1660 | * isci_remote_device_stop() - This function is called internally to stop the | 2232 | * isci_remote_device_stop() - This function is called internally to stop the |
1661 | * remote device. | 2233 | * remote device. |
1662 | * @isci_host: This parameter specifies the isci host object. | 2234 | * @isci_host: This parameter specifies the isci host object. |
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h index 62623c766388..dda217a6bd3a 100644 --- a/drivers/scsi/isci/remote_device.h +++ b/drivers/scsi/isci/remote_device.h | |||
@@ -68,9 +68,7 @@ enum scic_remote_device_not_ready_reason_code { | |||
68 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED, | 68 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED, |
69 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED, | 69 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED, |
70 | SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED, | 70 | SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED, |
71 | |||
72 | SCIC_REMOTE_DEVICE_NOT_READY_REASON_CODE_MAX | 71 | SCIC_REMOTE_DEVICE_NOT_READY_REASON_CODE_MAX |
73 | |||
74 | }; | 72 | }; |
75 | 73 | ||
76 | struct scic_sds_remote_device { | 74 | struct scic_sds_remote_device { |
@@ -132,19 +130,6 @@ struct scic_sds_remote_device { | |||
132 | u32 not_ready_reason; | 130 | u32 not_ready_reason; |
133 | 131 | ||
134 | /** | 132 | /** |
135 | * This field is true if this remote device has an initialzied ready substate | ||
136 | * machine. SSP devices do not have a ready substate machine and STP devices | ||
137 | * have a ready substate machine. | ||
138 | */ | ||
139 | bool has_ready_substate_machine; | ||
140 | |||
141 | /** | ||
142 | * This field contains the state machine for the ready substate machine for | ||
143 | * this struct scic_sds_remote_device object. | ||
144 | */ | ||
145 | struct sci_base_state_machine ready_substate_machine; | ||
146 | |||
147 | /** | ||
148 | * This field maintains the set of state handlers for the remote device | 133 | * This field maintains the set of state handlers for the remote device |
149 | * object. These are changed each time the remote device enters a new state. | 134 | * object. These are changed each time the remote device enters a new state. |
150 | */ | 135 | */ |
@@ -171,10 +156,6 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, | |||
171 | struct isci_remote_device *idev); | 156 | struct isci_remote_device *idev); |
172 | void isci_remote_device_nuke_requests(struct isci_host *ihost, | 157 | void isci_remote_device_nuke_requests(struct isci_host *ihost, |
173 | struct isci_remote_device *idev); | 158 | struct isci_remote_device *idev); |
174 | void isci_remote_device_ready(struct isci_host *ihost, | ||
175 | struct isci_remote_device *idev); | ||
176 | void isci_remote_device_not_ready(struct isci_host *ihost, | ||
177 | struct isci_remote_device *idev, u32 reason); | ||
178 | void isci_remote_device_gone(struct domain_device *domain_dev); | 159 | void isci_remote_device_gone(struct domain_device *domain_dev); |
179 | int isci_remote_device_found(struct domain_device *domain_dev); | 160 | int isci_remote_device_found(struct domain_device *domain_dev); |
180 | bool isci_device_is_reset_pending(struct isci_host *ihost, | 161 | bool isci_device_is_reset_pending(struct isci_host *ihost, |
@@ -278,77 +259,6 @@ enum scic_sds_remote_device_states { | |||
278 | SCI_BASE_REMOTE_DEVICE_STATE_READY, | 259 | SCI_BASE_REMOTE_DEVICE_STATE_READY, |
279 | 260 | ||
280 | /** | 261 | /** |
281 | * This state indicates that the remote device is in the process of | ||
282 | * stopping. In this state no new IO operations are permitted, but | ||
283 | * existing IO operations are allowed to complete. | ||
284 | * This state is entered from the READY state. | ||
285 | * This state is entered from the FAILED state. | ||
286 | */ | ||
287 | SCI_BASE_REMOTE_DEVICE_STATE_STOPPING, | ||
288 | |||
289 | /** | ||
290 | * This state indicates that the remote device has failed. | ||
291 | * In this state no new IO operations are permitted. | ||
292 | * This state is entered from the INITIALIZING state. | ||
293 | * This state is entered from the READY state. | ||
294 | */ | ||
295 | SCI_BASE_REMOTE_DEVICE_STATE_FAILED, | ||
296 | |||
297 | /** | ||
298 | * This state indicates the device is being reset. | ||
299 | * In this state no new IO operations are permitted. | ||
300 | * This state is entered from the READY state. | ||
301 | */ | ||
302 | SCI_BASE_REMOTE_DEVICE_STATE_RESETTING, | ||
303 | |||
304 | /** | ||
305 | * Simply the final state for the base remote device state machine. | ||
306 | */ | ||
307 | SCI_BASE_REMOTE_DEVICE_STATE_FINAL, | ||
308 | }; | ||
309 | |||
310 | /** | ||
311 | * enum scic_sds_ssp_remote_device_ready_substates - | ||
312 | * | ||
313 | * This is the enumeration of the ready substates for the | ||
314 | * struct scic_sds_remote_device. | ||
315 | */ | ||
316 | enum scic_sds_ssp_remote_device_ready_substates { | ||
317 | /** | ||
318 | * This is the initial state for the remote device ready substate. | ||
319 | */ | ||
320 | SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_INITIAL, | ||
321 | |||
322 | /** | ||
323 | * This is the ready operational substate for the remote device. | ||
324 | * This is the normal operational state for a remote device. | ||
325 | */ | ||
326 | SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL, | ||
327 | |||
328 | /** | ||
329 | * This is the suspended state for the remote device. This is the state | ||
330 | * that the device is placed in when a RNC suspend is received by | ||
331 | * the SCU hardware. | ||
332 | */ | ||
333 | SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED, | ||
334 | |||
335 | /** | ||
336 | * This is the final state that the device is placed in before a change | ||
337 | * to the base state machine. | ||
338 | */ | ||
339 | SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_FINAL, | ||
340 | |||
341 | SCIC_SDS_SSP_REMOTE_DEVICE_READY_MAX_SUBSTATES | ||
342 | }; | ||
343 | |||
344 | /** | ||
345 | * enum scic_sds_stp_remote_device_ready_substates - | ||
346 | * | ||
347 | * This is the enumeration for the struct scic_sds_remote_device ready substates | ||
348 | * for the STP remote device. | ||
349 | */ | ||
350 | enum scic_sds_stp_remote_device_ready_substates { | ||
351 | /** | ||
352 | * This is the idle substate for the stp remote device. When there are no | 262 | * This is the idle substate for the stp remote device. When there are no |
353 | * active IO for the device it is is in this state. | 263 | * active IO for the device it is is in this state. |
354 | */ | 264 | */ |
@@ -381,14 +291,7 @@ enum scic_sds_stp_remote_device_ready_substates { | |||
381 | * coming to be recovered from certain hardware specific error. | 291 | * coming to be recovered from certain hardware specific error. |
382 | */ | 292 | */ |
383 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET, | 293 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET, |
384 | }; | ||
385 | 294 | ||
386 | /** | ||
387 | * enum scic_sds_smp_remote_device_ready_substates - | ||
388 | * | ||
389 | * This is the enumeration of the ready substates for the SMP REMOTE DEVICE. | ||
390 | */ | ||
391 | enum scic_sds_smp_remote_device_ready_substates { | ||
392 | /** | 295 | /** |
393 | * This is the ready operational substate for the remote device. This is the | 296 | * This is the ready operational substate for the remote device. This is the |
394 | * normal operational state for a remote device. | 297 | * normal operational state for a remote device. |
@@ -400,6 +303,35 @@ enum scic_sds_smp_remote_device_ready_substates { | |||
400 | * the device is placed in when a RNC suspend is received by the SCU hardware. | 303 | * the device is placed in when a RNC suspend is received by the SCU hardware. |
401 | */ | 304 | */ |
402 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD, | 305 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD, |
306 | |||
307 | /** | ||
308 | * This state indicates that the remote device is in the process of | ||
309 | * stopping. In this state no new IO operations are permitted, but | ||
310 | * existing IO operations are allowed to complete. | ||
311 | * This state is entered from the READY state. | ||
312 | * This state is entered from the FAILED state. | ||
313 | */ | ||
314 | SCI_BASE_REMOTE_DEVICE_STATE_STOPPING, | ||
315 | |||
316 | /** | ||
317 | * This state indicates that the remote device has failed. | ||
318 | * In this state no new IO operations are permitted. | ||
319 | * This state is entered from the INITIALIZING state. | ||
320 | * This state is entered from the READY state. | ||
321 | */ | ||
322 | SCI_BASE_REMOTE_DEVICE_STATE_FAILED, | ||
323 | |||
324 | /** | ||
325 | * This state indicates the device is being reset. | ||
326 | * In this state no new IO operations are permitted. | ||
327 | * This state is entered from the READY state. | ||
328 | */ | ||
329 | SCI_BASE_REMOTE_DEVICE_STATE_RESETTING, | ||
330 | |||
331 | /** | ||
332 | * Simply the final state for the base remote device state machine. | ||
333 | */ | ||
334 | SCI_BASE_REMOTE_DEVICE_STATE_FINAL, | ||
403 | }; | 335 | }; |
404 | 336 | ||
405 | static inline struct scic_sds_remote_device *rnc_to_dev(struct scic_sds_remote_node_context *rnc) | 337 | static inline struct scic_sds_remote_device *rnc_to_dev(struct scic_sds_remote_node_context *rnc) |
@@ -541,10 +473,6 @@ struct scic_sds_remote_device_state_handler { | |||
541 | scic_sds_remote_device_frame_handler_t frame_handler; | 473 | scic_sds_remote_device_frame_handler_t frame_handler; |
542 | }; | 474 | }; |
543 | 475 | ||
544 | extern const struct sci_base_state scic_sds_ssp_remote_device_ready_substate_table[]; | ||
545 | extern const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[]; | ||
546 | extern const struct sci_base_state scic_sds_smp_remote_device_ready_substate_table[]; | ||
547 | |||
548 | /** | 476 | /** |
549 | * scic_sds_remote_device_increment_request_count() - | 477 | * scic_sds_remote_device_increment_request_count() - |
550 | * | 478 | * |
@@ -672,92 +600,24 @@ enum sci_status scic_sds_remote_device_start_io( | |||
672 | struct scic_sds_remote_device *sci_dev, | 600 | struct scic_sds_remote_device *sci_dev, |
673 | struct scic_sds_request *io_request); | 601 | struct scic_sds_request *io_request); |
674 | 602 | ||
675 | enum sci_status scic_sds_remote_device_complete_io( | 603 | enum sci_status scic_sds_remote_device_start_task( |
676 | struct scic_sds_controller *controller, | 604 | struct scic_sds_controller *controller, |
677 | struct scic_sds_remote_device *sci_dev, | 605 | struct scic_sds_remote_device *sci_dev, |
678 | struct scic_sds_request *io_request); | 606 | struct scic_sds_request *io_request); |
679 | 607 | ||
680 | enum sci_status scic_sds_remote_device_resume( | 608 | enum sci_status scic_sds_remote_device_complete_io( |
681 | struct scic_sds_remote_device *sci_dev); | 609 | struct scic_sds_controller *controller, |
610 | struct scic_sds_remote_device *sci_dev, | ||
611 | struct scic_sds_request *io_request); | ||
682 | 612 | ||
683 | enum sci_status scic_sds_remote_device_suspend( | 613 | enum sci_status scic_sds_remote_device_suspend( |
684 | struct scic_sds_remote_device *sci_dev, | 614 | struct scic_sds_remote_device *sci_dev, |
685 | u32 suspend_type); | 615 | u32 suspend_type); |
686 | 616 | ||
687 | enum sci_status scic_sds_remote_device_start_task( | ||
688 | struct scic_sds_controller *controller, | ||
689 | struct scic_sds_remote_device *sci_dev, | ||
690 | struct scic_sds_request *io_request); | ||
691 | |||
692 | void scic_sds_remote_device_post_request( | 617 | void scic_sds_remote_device_post_request( |
693 | struct scic_sds_remote_device *sci_dev, | 618 | struct scic_sds_remote_device *sci_dev, |
694 | u32 request); | 619 | u32 request); |
695 | 620 | ||
696 | #define scic_sds_remote_device_is_atapi(sci_dev) false | 621 | #define scic_sds_remote_device_is_atapi(sci_dev) false |
697 | 622 | ||
698 | void scic_sds_remote_device_start_request( | ||
699 | struct scic_sds_remote_device *sci_dev, | ||
700 | struct scic_sds_request *sci_req, | ||
701 | enum sci_status status); | ||
702 | |||
703 | void scic_sds_remote_device_continue_request(void *sci_dev); | ||
704 | |||
705 | enum sci_status scic_sds_remote_device_default_start_handler( | ||
706 | struct scic_sds_remote_device *sci_dev); | ||
707 | |||
708 | enum sci_status scic_sds_remote_device_default_fail_handler( | ||
709 | struct scic_sds_remote_device *sci_dev); | ||
710 | |||
711 | enum sci_status scic_sds_remote_device_default_destruct_handler( | ||
712 | struct scic_sds_remote_device *sci_dev); | ||
713 | |||
714 | enum sci_status scic_sds_remote_device_default_reset_handler( | ||
715 | struct scic_sds_remote_device *device); | ||
716 | |||
717 | enum sci_status scic_sds_remote_device_default_reset_complete_handler( | ||
718 | struct scic_sds_remote_device *device); | ||
719 | |||
720 | enum sci_status scic_sds_remote_device_default_start_request_handler( | ||
721 | struct scic_sds_remote_device *device, | ||
722 | struct scic_sds_request *request); | ||
723 | |||
724 | enum sci_status scic_sds_remote_device_default_complete_request_handler( | ||
725 | struct scic_sds_remote_device *device, | ||
726 | struct scic_sds_request *request); | ||
727 | |||
728 | enum sci_status scic_sds_remote_device_default_continue_request_handler( | ||
729 | struct scic_sds_remote_device *device, | ||
730 | struct scic_sds_request *request); | ||
731 | |||
732 | enum sci_status scic_sds_remote_device_default_suspend_handler( | ||
733 | struct scic_sds_remote_device *sci_dev, | ||
734 | u32 suspend_type); | ||
735 | |||
736 | enum sci_status scic_sds_remote_device_default_resume_handler( | ||
737 | struct scic_sds_remote_device *sci_dev); | ||
738 | |||
739 | |||
740 | enum sci_status scic_sds_remote_device_default_frame_handler( | ||
741 | struct scic_sds_remote_device *sci_dev, | ||
742 | u32 frame_index); | ||
743 | |||
744 | enum sci_status scic_sds_remote_device_ready_state_stop_handler( | ||
745 | struct scic_sds_remote_device *device); | ||
746 | |||
747 | enum sci_status scic_sds_remote_device_ready_state_reset_handler( | ||
748 | struct scic_sds_remote_device *device); | ||
749 | |||
750 | enum sci_status scic_sds_remote_device_general_frame_handler( | ||
751 | struct scic_sds_remote_device *sci_dev, | ||
752 | u32 frame_index); | ||
753 | |||
754 | enum sci_status scic_sds_remote_device_general_event_handler( | ||
755 | struct scic_sds_remote_device *sci_dev, | ||
756 | u32 event_code); | ||
757 | |||
758 | enum sci_status scic_sds_ssp_remote_device_ready_suspended_substate_resume_handler( | ||
759 | struct scic_sds_remote_device *sci_dev); | ||
760 | |||
761 | |||
762 | |||
763 | #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ | 623 | #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ |
diff --git a/drivers/scsi/isci/smp_remote_device.c b/drivers/scsi/isci/smp_remote_device.c deleted file mode 100644 index 45340a5c99c7..000000000000 --- a/drivers/scsi/isci/smp_remote_device.c +++ /dev/null | |||
@@ -1,310 +0,0 @@ | |||
1 | /* | ||
2 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
3 | * redistributing this file, you may do so under either license. | ||
4 | * | ||
5 | * GPL LICENSE SUMMARY | ||
6 | * | ||
7 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of version 2 of the GNU General Public License as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * BSD LICENSE | ||
25 | * | ||
26 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
27 | * All rights reserved. | ||
28 | * | ||
29 | * Redistribution and use in source and binary forms, with or without | ||
30 | * modification, are permitted provided that the following conditions | ||
31 | * are met: | ||
32 | * | ||
33 | * * Redistributions of source code must retain the above copyright | ||
34 | * notice, this list of conditions and the following disclaimer. | ||
35 | * * Redistributions in binary form must reproduce the above copyright | ||
36 | * notice, this list of conditions and the following disclaimer in | ||
37 | * the documentation and/or other materials provided with the | ||
38 | * distribution. | ||
39 | * * Neither the name of Intel Corporation nor the names of its | ||
40 | * contributors may be used to endorse or promote products derived | ||
41 | * from this software without specific prior written permission. | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
44 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
45 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
46 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
47 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
48 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
49 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
50 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
51 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
54 | */ | ||
55 | |||
56 | #include "scic_sds_controller.h" | ||
57 | #include "scic_sds_port.h" | ||
58 | #include "remote_device.h" | ||
59 | #include "scic_sds_request.h" | ||
60 | #include "sci_environment.h" | ||
61 | #include "sci_util.h" | ||
62 | #include "scu_event_codes.h" | ||
63 | #include "scu_task_context.h" | ||
64 | |||
65 | /* | ||
66 | * ***************************************************************************** | ||
67 | * * SMP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS | ||
68 | * ***************************************************************************** */ | ||
69 | |||
70 | /** | ||
71 | * | ||
72 | * @[in]: device The device the io is sent to. | ||
73 | * @[in]: request The io to start. | ||
74 | * | ||
75 | * This method will handle the start io operation for a SMP device that is in | ||
76 | * the idle state. enum sci_status | ||
77 | */ | ||
78 | static enum sci_status scic_sds_smp_remote_device_ready_idle_substate_start_io_handler( | ||
79 | struct scic_sds_remote_device *device, | ||
80 | struct scic_sds_request *request) | ||
81 | { | ||
82 | enum sci_status status; | ||
83 | |||
84 | /* Will the port allow the io request to start? */ | ||
85 | status = device->owning_port->state_handlers->start_io_handler( | ||
86 | device->owning_port, device, request); | ||
87 | |||
88 | if (status == SCI_SUCCESS) { | ||
89 | status = scic_sds_remote_node_context_start_io(&device->rnc, request); | ||
90 | |||
91 | if (status == SCI_SUCCESS) | ||
92 | status = scic_sds_request_start(request); | ||
93 | |||
94 | if (status == SCI_SUCCESS) { | ||
95 | device->working_request = request; | ||
96 | |||
97 | sci_base_state_machine_change_state( | ||
98 | &device->ready_substate_machine, | ||
99 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD | ||
100 | ); | ||
101 | } | ||
102 | |||
103 | scic_sds_remote_device_start_request(device, request, status); | ||
104 | } | ||
105 | |||
106 | return status; | ||
107 | } | ||
108 | |||
109 | |||
110 | /* | ||
111 | * ****************************************************************************** | ||
112 | * * SMP REMOTE DEVICE READY SUBSTATE CMD HANDLERS | ||
113 | * ****************************************************************************** */ | ||
114 | /** | ||
115 | * | ||
116 | * @device: This is the device object that is receiving the IO. | ||
117 | * @request: The io to start. | ||
118 | * | ||
119 | * This device is already handling a command it can not accept new commands | ||
120 | * until this one is complete. enum sci_status | ||
121 | */ | ||
122 | static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler( | ||
123 | struct scic_sds_remote_device *device, | ||
124 | struct scic_sds_request *request) | ||
125 | { | ||
126 | return SCI_FAILURE_INVALID_STATE; | ||
127 | } | ||
128 | |||
129 | |||
130 | /** | ||
131 | * this is the complete_io_handler for smp device at ready cmd substate. | ||
132 | * @device: This is the device object that is receiving the IO. | ||
133 | * @request: The io to start. | ||
134 | * | ||
135 | * enum sci_status | ||
136 | */ | ||
137 | static enum sci_status | ||
138 | scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler( | ||
139 | struct scic_sds_remote_device *device, | ||
140 | struct scic_sds_request *request) | ||
141 | { | ||
142 | enum sci_status status; | ||
143 | struct scic_sds_request *sci_req; | ||
144 | |||
145 | sci_req = (struct scic_sds_request *)request; | ||
146 | |||
147 | status = scic_sds_io_request_complete(sci_req); | ||
148 | |||
149 | if (status == SCI_SUCCESS) { | ||
150 | status = scic_sds_port_complete_io( | ||
151 | device->owning_port, device, sci_req); | ||
152 | |||
153 | if (status == SCI_SUCCESS) { | ||
154 | scic_sds_remote_device_decrement_request_count(device); | ||
155 | sci_base_state_machine_change_state( | ||
156 | &device->ready_substate_machine, | ||
157 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE | ||
158 | ); | ||
159 | } else | ||
160 | dev_err(scirdev_to_dev(device), | ||
161 | "%s: SCIC SDS Remote Device 0x%p io request " | ||
162 | "0x%p could not be completd on the port 0x%p " | ||
163 | "failed with status %d.\n", | ||
164 | __func__, | ||
165 | device, | ||
166 | sci_req, | ||
167 | device->owning_port, | ||
168 | status); | ||
169 | } | ||
170 | |||
171 | return status; | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * This is frame handler for smp device ready cmd substate. | ||
176 | * @sci_dev: This is the device object that is receiving the frame. | ||
177 | * @frame_index: The index for the frame received. | ||
178 | * | ||
179 | * enum sci_status | ||
180 | */ | ||
181 | static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handler( | ||
182 | struct scic_sds_remote_device *sci_dev, | ||
183 | u32 frame_index) | ||
184 | { | ||
185 | enum sci_status status; | ||
186 | |||
187 | /* | ||
188 | * / The device does not process any UF received from the hardware while | ||
189 | * / in this state. All unsolicited frames are forwarded to the io request | ||
190 | * / object. */ | ||
191 | status = scic_sds_io_request_frame_handler( | ||
192 | sci_dev->working_request, | ||
193 | frame_index | ||
194 | ); | ||
195 | |||
196 | return status; | ||
197 | } | ||
198 | |||
199 | /* --------------------------------------------------------------------------- */ | ||
200 | |||
201 | static const struct scic_sds_remote_device_state_handler scic_sds_smp_remote_device_ready_substate_handler_table[] = { | ||
202 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
203 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
204 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
205 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
206 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
207 | .reset_handler = scic_sds_remote_device_default_reset_handler, | ||
208 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
209 | .start_io_handler = scic_sds_smp_remote_device_ready_idle_substate_start_io_handler, | ||
210 | .complete_io_handler = scic_sds_remote_device_default_complete_request_handler, | ||
211 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
212 | .start_task_handler = scic_sds_remote_device_default_start_request_handler, | ||
213 | .complete_task_handler = scic_sds_remote_device_default_complete_request_handler, | ||
214 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
215 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
216 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
217 | .frame_handler = scic_sds_remote_device_default_frame_handler | ||
218 | }, | ||
219 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
220 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
221 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
222 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
223 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
224 | .reset_handler = scic_sds_remote_device_default_reset_handler, | ||
225 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
226 | .start_io_handler = scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler, | ||
227 | .complete_io_handler = scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler, | ||
228 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
229 | .start_task_handler = scic_sds_remote_device_default_start_request_handler, | ||
230 | .complete_task_handler = scic_sds_remote_device_default_complete_request_handler, | ||
231 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
232 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
233 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
234 | .frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler | ||
235 | } | ||
236 | }; | ||
237 | |||
238 | /** | ||
239 | * | ||
240 | * @object: This is the object which is cast into a | ||
241 | * struct scic_sds_remote_device. | ||
242 | * | ||
243 | * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method. | ||
244 | * This function sets the ready cmd substate handlers and reports the device as | ||
245 | * ready. none | ||
246 | */ | ||
247 | static void scic_sds_smp_remote_device_ready_idle_substate_enter(void *object) | ||
248 | { | ||
249 | struct scic_sds_remote_device *sci_dev = object; | ||
250 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
251 | struct isci_host *ihost = scic->ihost; | ||
252 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
253 | |||
254 | SET_STATE_HANDLER(sci_dev, | ||
255 | scic_sds_smp_remote_device_ready_substate_handler_table, | ||
256 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE); | ||
257 | |||
258 | isci_remote_device_ready(ihost, idev); | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * | ||
263 | * @object: This is the object which is cast into a | ||
264 | * struct scic_sds_remote_device. | ||
265 | * | ||
266 | * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This | ||
267 | * function sets the remote device objects ready cmd substate handlers, and | ||
268 | * notify core user that the device is not ready. none | ||
269 | */ | ||
270 | static void scic_sds_smp_remote_device_ready_cmd_substate_enter(void *object) | ||
271 | { | ||
272 | struct scic_sds_remote_device *sci_dev = object; | ||
273 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
274 | struct isci_host *ihost = scic->ihost; | ||
275 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
276 | |||
277 | BUG_ON(sci_dev->working_request == NULL); | ||
278 | |||
279 | SET_STATE_HANDLER(sci_dev, | ||
280 | scic_sds_smp_remote_device_ready_substate_handler_table, | ||
281 | SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
282 | |||
283 | isci_remote_device_not_ready(ihost, idev, | ||
284 | SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED); | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * | ||
289 | * @object: This is the object which is cast into a | ||
290 | * struct scic_sds_remote_device. | ||
291 | * | ||
292 | * This is the SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_CMD exit method. none | ||
293 | */ | ||
294 | static void scic_sds_smp_remote_device_ready_cmd_substate_exit(void *object) | ||
295 | { | ||
296 | struct scic_sds_remote_device *sci_dev = object; | ||
297 | sci_dev->working_request = NULL; | ||
298 | } | ||
299 | |||
300 | /* --------------------------------------------------------------------------- */ | ||
301 | |||
302 | const struct sci_base_state scic_sds_smp_remote_device_ready_substate_table[] = { | ||
303 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
304 | .enter_state = scic_sds_smp_remote_device_ready_idle_substate_enter, | ||
305 | }, | ||
306 | [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
307 | .enter_state = scic_sds_smp_remote_device_ready_cmd_substate_enter, | ||
308 | .exit_state = scic_sds_smp_remote_device_ready_cmd_substate_exit, | ||
309 | }, | ||
310 | }; | ||
diff --git a/drivers/scsi/isci/stp_remote_device.c b/drivers/scsi/isci/stp_remote_device.c deleted file mode 100644 index 1853552bc252..000000000000 --- a/drivers/scsi/isci/stp_remote_device.c +++ /dev/null | |||
@@ -1,716 +0,0 @@ | |||
1 | /* | ||
2 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
3 | * redistributing this file, you may do so under either license. | ||
4 | * | ||
5 | * GPL LICENSE SUMMARY | ||
6 | * | ||
7 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of version 2 of the GNU General Public License as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * BSD LICENSE | ||
25 | * | ||
26 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
27 | * All rights reserved. | ||
28 | * | ||
29 | * Redistribution and use in source and binary forms, with or without | ||
30 | * modification, are permitted provided that the following conditions | ||
31 | * are met: | ||
32 | * | ||
33 | * * Redistributions of source code must retain the above copyright | ||
34 | * notice, this list of conditions and the following disclaimer. | ||
35 | * * Redistributions in binary form must reproduce the above copyright | ||
36 | * notice, this list of conditions and the following disclaimer in | ||
37 | * the documentation and/or other materials provided with the | ||
38 | * distribution. | ||
39 | * * Neither the name of Intel Corporation nor the names of its | ||
40 | * contributors may be used to endorse or promote products derived | ||
41 | * from this software without specific prior written permission. | ||
42 | * | ||
43 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
44 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
45 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
46 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
47 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
48 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
49 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
50 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
51 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
54 | */ | ||
55 | |||
56 | #include "intel_ata.h" | ||
57 | #include "intel_sata.h" | ||
58 | #include "intel_sat.h" | ||
59 | #include "sci_base_state.h" | ||
60 | #include "scic_sds_controller.h" | ||
61 | #include "scic_sds_port.h" | ||
62 | #include "remote_device.h" | ||
63 | #include "scic_sds_request.h" | ||
64 | #include "sci_environment.h" | ||
65 | #include "sci_util.h" | ||
66 | #include "scu_event_codes.h" | ||
67 | |||
68 | /** | ||
69 | * This method will perform the STP request completion processing common to IO | ||
70 | * requests and task requests of all types | ||
71 | * @device: This parameter specifies the device for which the request is being | ||
72 | * completed. | ||
73 | * @request: This parameter specifies the request being completed. | ||
74 | * | ||
75 | * This method returns an indication as to whether the request processing | ||
76 | * completed successfully. | ||
77 | */ | ||
78 | static enum sci_status scic_sds_stp_remote_device_complete_request( | ||
79 | struct scic_sds_remote_device *device, | ||
80 | struct scic_sds_request *request) | ||
81 | { | ||
82 | enum sci_status status; | ||
83 | |||
84 | status = scic_sds_io_request_complete(request); | ||
85 | |||
86 | if (status == SCI_SUCCESS) { | ||
87 | status = scic_sds_port_complete_io( | ||
88 | device->owning_port, device, request); | ||
89 | |||
90 | if (status == SCI_SUCCESS) { | ||
91 | scic_sds_remote_device_decrement_request_count(device); | ||
92 | if (request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) { | ||
93 | /* | ||
94 | * This request causes hardware error, device needs to be Lun Reset. | ||
95 | * So here we force the state machine to IDLE state so the rest IOs | ||
96 | * can reach RNC state handler, these IOs will be completed by RNC with | ||
97 | * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */ | ||
98 | sci_base_state_machine_change_state( | ||
99 | &device->ready_substate_machine, | ||
100 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET | ||
101 | ); | ||
102 | } else if (scic_sds_remote_device_get_request_count(device) == 0) { | ||
103 | sci_base_state_machine_change_state( | ||
104 | &device->ready_substate_machine, | ||
105 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE | ||
106 | ); | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | |||
111 | if (status != SCI_SUCCESS) | ||
112 | dev_err(scirdev_to_dev(device), | ||
113 | "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x " | ||
114 | "could not complete\n", | ||
115 | __func__, | ||
116 | device->owning_port, | ||
117 | device, | ||
118 | request, | ||
119 | status); | ||
120 | |||
121 | return status; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * ***************************************************************************** | ||
126 | * * STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS | ||
127 | * ***************************************************************************** */ | ||
128 | |||
129 | /** | ||
130 | * This is the READY NCQ substate handler to start task management request. In | ||
131 | * this routine, we suspend and resume the RNC. | ||
132 | * @device: The target device a task management request towards to. | ||
133 | * @request: The task request. | ||
134 | * | ||
135 | * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to | ||
136 | * let controller_start_task_handler know that the controller can't post TC for | ||
137 | * task request yet, instead, when RNC gets resumed, a controller_continue_task | ||
138 | * callback will be called. | ||
139 | */ | ||
140 | static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler( | ||
141 | struct scic_sds_remote_device *device, | ||
142 | struct scic_sds_request *request) | ||
143 | { | ||
144 | enum sci_status status; | ||
145 | |||
146 | /* Will the port allow the io request to start? */ | ||
147 | status = device->owning_port->state_handlers->start_io_handler( | ||
148 | device->owning_port, device, request); | ||
149 | if (status != SCI_SUCCESS) | ||
150 | return status; | ||
151 | |||
152 | status = scic_sds_remote_node_context_start_task(&device->rnc, request); | ||
153 | if (status != SCI_SUCCESS) | ||
154 | goto out; | ||
155 | |||
156 | status = request->state_handlers->start_handler(request); | ||
157 | if (status != SCI_SUCCESS) | ||
158 | goto out; | ||
159 | |||
160 | /* | ||
161 | * Note: If the remote device state is not IDLE this will replace | ||
162 | * the request that probably resulted in the task management request. | ||
163 | */ | ||
164 | device->working_request = request; | ||
165 | sci_base_state_machine_change_state(&device->ready_substate_machine, | ||
166 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
167 | |||
168 | /* | ||
169 | * The remote node context must cleanup the TCi to NCQ mapping table. | ||
170 | * The only way to do this correctly is to either write to the TLCR | ||
171 | * register or to invalidate and repost the RNC. In either case the | ||
172 | * remote node context state machine will take the correct action when | ||
173 | * the remote node context is suspended and later resumed. | ||
174 | */ | ||
175 | scic_sds_remote_node_context_suspend(&device->rnc, | ||
176 | SCI_SOFTWARE_SUSPENSION, NULL, NULL); | ||
177 | scic_sds_remote_node_context_resume(&device->rnc, | ||
178 | scic_sds_remote_device_continue_request, | ||
179 | device); | ||
180 | |||
181 | out: | ||
182 | scic_sds_remote_device_start_request(device, request, status); | ||
183 | /* | ||
184 | * We need to let the controller start request handler know that it can't | ||
185 | * post TC yet. We will provide a callback function to post TC when RNC gets | ||
186 | * resumed. | ||
187 | */ | ||
188 | return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * ***************************************************************************** | ||
193 | * * STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS | ||
194 | * ***************************************************************************** */ | ||
195 | |||
196 | /** | ||
197 | * This method will handle the start io operation for a sata device that is in | ||
198 | * the command idle state. - Evalute the type of IO request to be started - | ||
199 | * If its an NCQ request change to NCQ substate - If its any other command | ||
200 | * change to the CMD substate | ||
201 | * @device: | ||
202 | * @request: | ||
203 | * | ||
204 | * If this is a softreset we may want to have a different substate. | ||
205 | * enum sci_status | ||
206 | */ | ||
207 | static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler( | ||
208 | struct scic_sds_remote_device *sci_dev, | ||
209 | struct scic_sds_request *request) | ||
210 | { | ||
211 | enum sci_status status; | ||
212 | struct isci_request *isci_request = request->ireq; | ||
213 | |||
214 | |||
215 | /* Will the port allow the io request to start? */ | ||
216 | status = sci_dev->owning_port->state_handlers->start_io_handler( | ||
217 | sci_dev->owning_port, sci_dev, request); | ||
218 | if (status != SCI_SUCCESS) | ||
219 | return status; | ||
220 | |||
221 | status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request); | ||
222 | if (status != SCI_SUCCESS) | ||
223 | goto out; | ||
224 | |||
225 | status = request->state_handlers->start_handler(request); | ||
226 | if (status != SCI_SUCCESS) | ||
227 | goto out; | ||
228 | |||
229 | if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) { | ||
230 | sci_base_state_machine_change_state(&sci_dev->ready_substate_machine, | ||
231 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ); | ||
232 | } else { | ||
233 | sci_dev->working_request = request; | ||
234 | sci_base_state_machine_change_state(&sci_dev->ready_substate_machine, | ||
235 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
236 | } | ||
237 | out: | ||
238 | scic_sds_remote_device_start_request(sci_dev, request, status); | ||
239 | return status; | ||
240 | } | ||
241 | |||
242 | |||
243 | /** | ||
244 | * | ||
245 | * @[in]: device The device received event. | ||
246 | * @[in]: event_code The event code. | ||
247 | * | ||
248 | * This method will handle the event for a sata device that is in the idle | ||
249 | * state. We pick up suspension events to handle specifically to this state. We | ||
250 | * resume the RNC right away. enum sci_status | ||
251 | */ | ||
252 | static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler( | ||
253 | struct scic_sds_remote_device *sci_dev, | ||
254 | u32 event_code) | ||
255 | { | ||
256 | enum sci_status status; | ||
257 | |||
258 | status = scic_sds_remote_device_general_event_handler(sci_dev, event_code); | ||
259 | |||
260 | if (status == SCI_SUCCESS) { | ||
261 | if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX | ||
262 | || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) { | ||
263 | status = scic_sds_remote_node_context_resume( | ||
264 | &sci_dev->rnc, NULL, NULL); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | return status; | ||
269 | } | ||
270 | |||
271 | |||
272 | /* | ||
273 | * ***************************************************************************** | ||
274 | * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS | ||
275 | * ***************************************************************************** */ | ||
276 | |||
277 | static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler( | ||
278 | struct scic_sds_remote_device *sci_dev, | ||
279 | struct scic_sds_request *request) | ||
280 | { | ||
281 | enum sci_status status; | ||
282 | struct isci_request *isci_request = request->ireq; | ||
283 | |||
284 | if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) { | ||
285 | status = sci_dev->owning_port->state_handlers->start_io_handler( | ||
286 | sci_dev->owning_port, | ||
287 | sci_dev, | ||
288 | request); | ||
289 | if (status != SCI_SUCCESS) | ||
290 | return status; | ||
291 | |||
292 | status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request); | ||
293 | if (status != SCI_SUCCESS) | ||
294 | return status; | ||
295 | |||
296 | status = request->state_handlers->start_handler(request); | ||
297 | |||
298 | scic_sds_remote_device_start_request(sci_dev, request, status); | ||
299 | } else | ||
300 | status = SCI_FAILURE_INVALID_STATE; | ||
301 | |||
302 | return status; | ||
303 | } | ||
304 | |||
305 | |||
306 | /** | ||
307 | * This method will handle events received while the STP device is in the ready | ||
308 | * command substate. | ||
309 | * @sci_dev: This is the device object that is receiving the event. | ||
310 | * @event_code: The event code to process. | ||
311 | * | ||
312 | * enum sci_status | ||
313 | */ | ||
314 | |||
315 | static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler( | ||
316 | struct scic_sds_remote_device *sci_dev, | ||
317 | u32 frame_index) | ||
318 | { | ||
319 | enum sci_status status; | ||
320 | struct sata_fis_header *frame_header; | ||
321 | |||
322 | status = scic_sds_unsolicited_frame_control_get_header( | ||
323 | &(scic_sds_remote_device_get_controller(sci_dev)->uf_control), | ||
324 | frame_index, | ||
325 | (void **)&frame_header | ||
326 | ); | ||
327 | |||
328 | if (status == SCI_SUCCESS) { | ||
329 | if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS && | ||
330 | (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) { | ||
331 | sci_dev->not_ready_reason = | ||
332 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; | ||
333 | |||
334 | /* | ||
335 | * / @todo Check sactive and complete associated IO | ||
336 | * if any. | ||
337 | */ | ||
338 | |||
339 | sci_base_state_machine_change_state( | ||
340 | &sci_dev->ready_substate_machine, | ||
341 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR | ||
342 | ); | ||
343 | } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H && | ||
344 | (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) { | ||
345 | |||
346 | /* | ||
347 | * Some devices return D2H FIS when an NCQ error is detected. | ||
348 | * Treat this like an SDB error FIS ready reason. | ||
349 | */ | ||
350 | sci_dev->not_ready_reason = | ||
351 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED; | ||
352 | |||
353 | sci_base_state_machine_change_state( | ||
354 | &sci_dev->ready_substate_machine, | ||
355 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR | ||
356 | ); | ||
357 | } else { | ||
358 | status = SCI_FAILURE; | ||
359 | } | ||
360 | |||
361 | scic_sds_controller_release_frame( | ||
362 | scic_sds_remote_device_get_controller(sci_dev), frame_index | ||
363 | ); | ||
364 | } | ||
365 | |||
366 | return status; | ||
367 | } | ||
368 | |||
369 | /* | ||
370 | * ***************************************************************************** | ||
371 | * * STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS | ||
372 | * ***************************************************************************** */ | ||
373 | |||
374 | /** | ||
375 | * This device is already handling a command it can not accept new commands | ||
376 | * until this one is complete. | ||
377 | * @device: | ||
378 | * @request: | ||
379 | * | ||
380 | * enum sci_status | ||
381 | */ | ||
382 | static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler( | ||
383 | struct scic_sds_remote_device *device, | ||
384 | struct scic_sds_request *request) | ||
385 | { | ||
386 | return SCI_FAILURE_INVALID_STATE; | ||
387 | } | ||
388 | |||
389 | static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler( | ||
390 | struct scic_sds_remote_device *sci_dev, | ||
391 | u32 suspend_type) | ||
392 | { | ||
393 | enum sci_status status; | ||
394 | |||
395 | status = scic_sds_remote_node_context_suspend(&sci_dev->rnc, | ||
396 | suspend_type, NULL, NULL); | ||
397 | |||
398 | return status; | ||
399 | } | ||
400 | |||
401 | static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler( | ||
402 | struct scic_sds_remote_device *sci_dev, | ||
403 | u32 frame_index) | ||
404 | { | ||
405 | enum sci_status status; | ||
406 | |||
407 | /* | ||
408 | * / The device doe not process any UF received from the hardware while | ||
409 | * / in this state. All unsolicited frames are forwarded to the io request | ||
410 | * / object. */ | ||
411 | status = scic_sds_io_request_frame_handler( | ||
412 | sci_dev->working_request, | ||
413 | frame_index | ||
414 | ); | ||
415 | |||
416 | return status; | ||
417 | } | ||
418 | |||
419 | |||
420 | /* | ||
421 | * ***************************************************************************** | ||
422 | * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS | ||
423 | * ***************************************************************************** */ | ||
424 | |||
425 | /* | ||
426 | * ***************************************************************************** | ||
427 | * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS | ||
428 | * ***************************************************************************** */ | ||
429 | |||
430 | /* | ||
431 | * ***************************************************************************** | ||
432 | * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS | ||
433 | * ***************************************************************************** */ | ||
434 | static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler( | ||
435 | struct scic_sds_remote_device *device, | ||
436 | struct scic_sds_request *request) | ||
437 | { | ||
438 | return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; | ||
439 | } | ||
440 | |||
441 | |||
442 | |||
443 | /** | ||
444 | * This method will perform the STP request (both io or task) completion | ||
445 | * processing for await reset state. | ||
446 | * @device: This parameter specifies the device for which the request is being | ||
447 | * completed. | ||
448 | * @request: This parameter specifies the request being completed. | ||
449 | * | ||
450 | * This method returns an indication as to whether the request processing | ||
451 | * completed successfully. | ||
452 | */ | ||
453 | static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler( | ||
454 | struct scic_sds_remote_device *device, | ||
455 | struct scic_sds_request *request) | ||
456 | { | ||
457 | struct scic_sds_request *sci_req = (struct scic_sds_request *)request; | ||
458 | enum sci_status status; | ||
459 | |||
460 | status = scic_sds_io_request_complete(sci_req); | ||
461 | |||
462 | if (status == SCI_SUCCESS) { | ||
463 | status = scic_sds_port_complete_io( | ||
464 | device->owning_port, device, sci_req | ||
465 | ); | ||
466 | |||
467 | if (status == SCI_SUCCESS) | ||
468 | scic_sds_remote_device_decrement_request_count(device); | ||
469 | } | ||
470 | |||
471 | if (status != SCI_SUCCESS) | ||
472 | dev_err(scirdev_to_dev(device), | ||
473 | "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x " | ||
474 | "could not complete\n", | ||
475 | __func__, | ||
476 | device->owning_port, | ||
477 | device, | ||
478 | sci_req, | ||
479 | status); | ||
480 | |||
481 | return status; | ||
482 | } | ||
483 | |||
484 | static const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = { | ||
485 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
486 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
487 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
488 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
489 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
490 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
491 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
492 | .start_io_handler = scic_sds_stp_remote_device_ready_idle_substate_start_io_handler, | ||
493 | .complete_io_handler = scic_sds_remote_device_default_complete_request_handler, | ||
494 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
495 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
496 | .complete_task_handler = scic_sds_remote_device_default_complete_request_handler, | ||
497 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
498 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
499 | .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler, | ||
500 | .frame_handler = scic_sds_remote_device_default_frame_handler | ||
501 | }, | ||
502 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
503 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
504 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
505 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
506 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
507 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
508 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
509 | .start_io_handler = scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler, | ||
510 | .complete_io_handler = scic_sds_stp_remote_device_complete_request, | ||
511 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
512 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
513 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
514 | .suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler, | ||
515 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
516 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
517 | .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler | ||
518 | }, | ||
519 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { | ||
520 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
521 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
522 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
523 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
524 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
525 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
526 | .start_io_handler = scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler, | ||
527 | .complete_io_handler = scic_sds_stp_remote_device_complete_request, | ||
528 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
529 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
530 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
531 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
532 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
533 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
534 | .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler | ||
535 | }, | ||
536 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { | ||
537 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
538 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
539 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
540 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
541 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
542 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
543 | .start_io_handler = scic_sds_remote_device_default_start_request_handler, | ||
544 | .complete_io_handler = scic_sds_stp_remote_device_complete_request, | ||
545 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
546 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
547 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
548 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
549 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
550 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
551 | .frame_handler = scic_sds_remote_device_general_frame_handler | ||
552 | }, | ||
553 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { | ||
554 | .start_handler = scic_sds_remote_device_default_start_handler, | ||
555 | .stop_handler = scic_sds_remote_device_ready_state_stop_handler, | ||
556 | .fail_handler = scic_sds_remote_device_default_fail_handler, | ||
557 | .destruct_handler = scic_sds_remote_device_default_destruct_handler, | ||
558 | .reset_handler = scic_sds_remote_device_ready_state_reset_handler, | ||
559 | .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler, | ||
560 | .start_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler, | ||
561 | .complete_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler, | ||
562 | .continue_io_handler = scic_sds_remote_device_default_continue_request_handler, | ||
563 | .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler, | ||
564 | .complete_task_handler = scic_sds_stp_remote_device_complete_request, | ||
565 | .suspend_handler = scic_sds_remote_device_default_suspend_handler, | ||
566 | .resume_handler = scic_sds_remote_device_default_resume_handler, | ||
567 | .event_handler = scic_sds_remote_device_general_event_handler, | ||
568 | .frame_handler = scic_sds_remote_device_general_frame_handler | ||
569 | } | ||
570 | }; | ||
571 | |||
572 | /* | ||
573 | * ***************************************************************************** | ||
574 | * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS | ||
575 | * ***************************************************************************** */ | ||
576 | |||
577 | static void | ||
578 | scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *user_cookie) | ||
579 | { | ||
580 | struct scic_sds_remote_device *sci_dev = user_cookie; | ||
581 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
582 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
583 | struct isci_host *ihost = scic->ihost; | ||
584 | |||
585 | /* | ||
586 | * For NCQ operation we do not issue a | ||
587 | * scic_cb_remote_device_not_ready(). As a result, avoid sending | ||
588 | * the ready notification. | ||
589 | */ | ||
590 | if (sci_dev->ready_substate_machine.previous_state_id != | ||
591 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) | ||
592 | isci_remote_device_ready(ihost, idev); | ||
593 | } | ||
594 | |||
595 | /* | ||
596 | * ***************************************************************************** | ||
597 | * * STP REMOTE DEVICE READY IDLE SUBSTATE | ||
598 | * ***************************************************************************** */ | ||
599 | |||
600 | /** | ||
601 | * | ||
602 | * @device: This is the object which is cast into a | ||
603 | * struct scic_sds_remote_device object. | ||
604 | * | ||
605 | */ | ||
606 | static void scic_sds_stp_remote_device_ready_idle_substate_enter(void *device) | ||
607 | { | ||
608 | struct scic_sds_remote_device *sci_dev = device; | ||
609 | |||
610 | SET_STATE_HANDLER( | ||
611 | sci_dev, | ||
612 | scic_sds_stp_remote_device_ready_substate_handler_table, | ||
613 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE | ||
614 | ); | ||
615 | |||
616 | sci_dev->working_request = NULL; | ||
617 | |||
618 | if (scic_sds_remote_node_context_is_ready(&sci_dev->rnc)) { | ||
619 | /* | ||
620 | * Since the RNC is ready, it's alright to finish completion | ||
621 | * processing (e.g. signal the remote device is ready). */ | ||
622 | scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler( | ||
623 | sci_dev | ||
624 | ); | ||
625 | } else { | ||
626 | scic_sds_remote_node_context_resume( | ||
627 | &sci_dev->rnc, | ||
628 | scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler, | ||
629 | sci_dev); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | static void scic_sds_stp_remote_device_ready_cmd_substate_enter(void *object) | ||
634 | { | ||
635 | struct scic_sds_remote_device *sci_dev = object; | ||
636 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
637 | struct isci_host *ihost = scic->ihost; | ||
638 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
639 | |||
640 | BUG_ON(sci_dev->working_request == NULL); | ||
641 | |||
642 | SET_STATE_HANDLER(sci_dev, | ||
643 | scic_sds_stp_remote_device_ready_substate_handler_table, | ||
644 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD); | ||
645 | |||
646 | isci_remote_device_not_ready(ihost, idev, | ||
647 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED); | ||
648 | } | ||
649 | |||
650 | static void scic_sds_stp_remote_device_ready_ncq_substate_enter(void *object) | ||
651 | { | ||
652 | struct scic_sds_remote_device *sci_dev = object; | ||
653 | SET_STATE_HANDLER(sci_dev, | ||
654 | scic_sds_stp_remote_device_ready_substate_handler_table, | ||
655 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ); | ||
656 | } | ||
657 | |||
658 | static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter( | ||
659 | void *object) | ||
660 | { | ||
661 | struct scic_sds_remote_device *sci_dev = object; | ||
662 | struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev); | ||
663 | struct isci_host *ihost = scic->ihost; | ||
664 | struct isci_remote_device *idev = sci_dev_to_idev(sci_dev); | ||
665 | |||
666 | SET_STATE_HANDLER(sci_dev, | ||
667 | scic_sds_stp_remote_device_ready_substate_handler_table, | ||
668 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR); | ||
669 | |||
670 | if (sci_dev->not_ready_reason == | ||
671 | SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) | ||
672 | isci_remote_device_not_ready(ihost, idev, sci_dev->not_ready_reason); | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | * ***************************************************************************** | ||
677 | * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE | ||
678 | * ***************************************************************************** */ | ||
679 | |||
680 | /** | ||
681 | * The enter routine to READY AWAIT RESET substate. | ||
682 | * @device: This is the object which is cast into a | ||
683 | * struct scic_sds_remote_device object. | ||
684 | * | ||
685 | */ | ||
686 | static void scic_sds_stp_remote_device_ready_await_reset_substate_enter( | ||
687 | void *device) | ||
688 | { | ||
689 | struct scic_sds_remote_device *sci_dev; | ||
690 | |||
691 | sci_dev = (struct scic_sds_remote_device *)device; | ||
692 | |||
693 | SET_STATE_HANDLER( | ||
694 | sci_dev, | ||
695 | scic_sds_stp_remote_device_ready_substate_handler_table, | ||
696 | SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET | ||
697 | ); | ||
698 | } | ||
699 | |||
700 | const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = { | ||
701 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { | ||
702 | .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter, | ||
703 | }, | ||
704 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { | ||
705 | .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter, | ||
706 | }, | ||
707 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { | ||
708 | .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter, | ||
709 | }, | ||
710 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { | ||
711 | .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter, | ||
712 | }, | ||
713 | [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { | ||
714 | .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter, | ||
715 | }, | ||
716 | }; | ||