diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-04-27 19:32:45 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:00:39 -0400 |
commit | ab2e8f7d07f577ee39228fb3454b9f29eab0f312 (patch) | |
tree | 9f3fc14b955f689a29d6777349db0f49c8dcf3e0 /drivers/scsi/isci/remote_device.c | |
parent | be2f41c611b65353fa3ae0c155cf906b348dc864 (diff) |
isci: merge remote_device substates into a single state machine
A substate is just a state, so uplevel the smp and stp device substates.
Three tricks at work here:
1/ scic_sds_remote_device_ready_state_enter: needs to know the the device type
so it can immediately transition to a stp or smp ready substate.
2/ scic_sds_remote_device_ready_state_exit: needs to know the device type. In
the ssp case the device is no longer ready, in the stp, and smp case we have
simply exited to a ready "substate".
3/ scic_sds_remote_device_resume_complete_handler: The one location
where we directly check the current state against
SCI_BASE_REMOTE_DEVICE_STATE_READY needed to comprehend the possible ready
substates.
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/remote_device.c')
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 960 |
1 files changed, 766 insertions, 194 deletions
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. |