diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-05-07 18:59:09 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:47 -0400 |
commit | 827a84d4e036b342b31abc2bcc3893505c2c7daa (patch) | |
tree | 205cfd22e8e6c652aa9f6f3bc9a70820a8201241 /drivers | |
parent | e531381e2f8a68b8737c63c7bb890ad80b2470bd (diff) |
isci: move stp request info to scic_sds_request
In preparation for unifying allocation of all request information make stp
data available in all requests. Incidentally collapse indentation.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_request.c | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_request.h | 19 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_stp_request.c | 711 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_stp_request.h | 10 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 5 |
5 files changed, 313 insertions, 435 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c index 52692a16449d..fd7bd334fa4b 100644 --- a/drivers/scsi/isci/core/scic_sds_request.c +++ b/drivers/scsi/isci/core/scic_sds_request.c | |||
@@ -710,8 +710,7 @@ enum sci_status scic_io_request_construct_basic_sata( | |||
710 | struct isci_request *isci_request = sci_req->ireq; | 710 | struct isci_request *isci_request = sci_req->ireq; |
711 | struct sas_task *task = isci_request_access_task(isci_request); | 711 | struct sas_task *task = isci_request_access_task(isci_request); |
712 | 712 | ||
713 | stp_req = container_of(sci_req, typeof(*stp_req), parent); | 713 | stp_req = &sci_req->stp.req; |
714 | |||
715 | sci_req->protocol = SCIC_STP_PROTOCOL; | 714 | sci_req->protocol = SCIC_STP_PROTOCOL; |
716 | 715 | ||
717 | copy = (task->data_dir == DMA_NONE) ? false : true; | 716 | copy = (task->data_dir == DMA_NONE) ? false : true; |
diff --git a/drivers/scsi/isci/core/scic_sds_request.h b/drivers/scsi/isci/core/scic_sds_request.h index b83d89362909..c93f3ed8946d 100644 --- a/drivers/scsi/isci/core/scic_sds_request.h +++ b/drivers/scsi/isci/core/scic_sds_request.h | |||
@@ -56,16 +56,10 @@ | |||
56 | #ifndef _SCIC_SDS_IO_REQUEST_H_ | 56 | #ifndef _SCIC_SDS_IO_REQUEST_H_ |
57 | #define _SCIC_SDS_IO_REQUEST_H_ | 57 | #define _SCIC_SDS_IO_REQUEST_H_ |
58 | 58 | ||
59 | /** | ||
60 | * This file contains the structures, constants and prototypes for the | ||
61 | * SCIC_SDS_IO_REQUEST object. | ||
62 | * | ||
63 | * | ||
64 | */ | ||
65 | |||
66 | #include "scic_io_request.h" | 59 | #include "scic_io_request.h" |
67 | #include "sci_base_state_machine.h" | 60 | #include "sci_base_state_machine.h" |
68 | #include "scu_task_context.h" | 61 | #include "scu_task_context.h" |
62 | #include "scic_sds_stp_request.h" | ||
69 | 63 | ||
70 | struct scic_sds_controller; | 64 | struct scic_sds_controller; |
71 | struct scic_sds_remote_device; | 65 | struct scic_sds_remote_device; |
@@ -233,8 +227,19 @@ struct scic_sds_request { | |||
233 | */ | 227 | */ |
234 | u8 device_sequence; | 228 | u8 device_sequence; |
235 | 229 | ||
230 | struct { | ||
231 | struct scic_sds_stp_request req; | ||
232 | } stp; | ||
236 | }; | 233 | }; |
237 | 234 | ||
235 | static inline struct scic_sds_request *to_sci_req(struct scic_sds_stp_request *stp_req) | ||
236 | { | ||
237 | struct scic_sds_request *sci_req; | ||
238 | |||
239 | sci_req = container_of(stp_req, typeof(*sci_req), stp.req); | ||
240 | return sci_req; | ||
241 | } | ||
242 | |||
238 | /** | 243 | /** |
239 | * enum sci_base_request_states - This enumeration depicts all the states for | 244 | * enum sci_base_request_states - This enumeration depicts all the states for |
240 | * the common request state machine. | 245 | * the common request state machine. |
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.c b/drivers/scsi/isci/core/scic_sds_stp_request.c index 8569dba6c68b..7dba40fc2585 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.c +++ b/drivers/scsi/isci/core/scic_sds_stp_request.c | |||
@@ -134,8 +134,7 @@ u32 scic_sds_stp_request_get_object_size(void) | |||
134 | 134 | ||
135 | void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req) | 135 | void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req) |
136 | { | 136 | { |
137 | struct scic_sds_stp_request *stp_req = | 137 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
138 | container_of(sci_req, typeof(*stp_req), parent); | ||
139 | 138 | ||
140 | sci_req->command_buffer = scic_sds_stp_request_get_h2d_reg_buffer(stp_req); | 139 | sci_req->command_buffer = scic_sds_stp_request_get_h2d_reg_buffer(stp_req); |
141 | sci_req->response_buffer = scic_sds_stp_request_get_response_buffer(stp_req); | 140 | sci_req->response_buffer = scic_sds_stp_request_get_response_buffer(stp_req); |
@@ -344,17 +343,18 @@ enum sci_status scic_sds_stp_ncq_request_construct(struct scic_sds_request *sci_ | |||
344 | * utilizing the raw frame method. none | 343 | * utilizing the raw frame method. none |
345 | */ | 344 | */ |
346 | static void scu_stp_raw_request_construct_task_context( | 345 | static void scu_stp_raw_request_construct_task_context( |
347 | struct scic_sds_stp_request *sci_req, | 346 | struct scic_sds_stp_request *stp_req, |
348 | struct scu_task_context *task_context) | 347 | struct scu_task_context *task_context) |
349 | { | 348 | { |
350 | scu_sata_reqeust_construct_task_context(&sci_req->parent, task_context); | 349 | struct scic_sds_request *sci_req = to_sci_req(stp_req); |
350 | |||
351 | scu_sata_reqeust_construct_task_context(sci_req, task_context); | ||
351 | 352 | ||
352 | task_context->control_frame = 0; | 353 | task_context->control_frame = 0; |
353 | task_context->priority = SCU_TASK_PRIORITY_NORMAL; | 354 | task_context->priority = SCU_TASK_PRIORITY_NORMAL; |
354 | task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME; | 355 | task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME; |
355 | task_context->type.stp.fis_type = FIS_REGH2D; | 356 | task_context->type.stp.fis_type = FIS_REGH2D; |
356 | task_context->transfer_length_bytes = | 357 | task_context->transfer_length_bytes = sizeof(struct host_to_dev_fis) - sizeof(u32); |
357 | sizeof(struct host_to_dev_fis) - sizeof(u32); | ||
358 | } | 358 | } |
359 | 359 | ||
360 | void scic_stp_io_request_set_ncq_tag( | 360 | void scic_stp_io_request_set_ncq_tag( |
@@ -376,10 +376,11 @@ void *scic_stp_io_request_get_h2d_reg_address( | |||
376 | } | 376 | } |
377 | 377 | ||
378 | 378 | ||
379 | void *scic_stp_io_request_get_d2h_reg_address( | 379 | void *scic_stp_io_request_get_d2h_reg_address(struct scic_sds_request *sci_req) |
380 | struct scic_sds_request *req) | ||
381 | { | 380 | { |
382 | return &((struct scic_sds_stp_request *)req)->d2h_reg_fis; | 381 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
382 | |||
383 | return &stp_req->d2h_reg_fis; | ||
383 | } | 384 | } |
384 | 385 | ||
385 | /** | 386 | /** |
@@ -395,7 +396,7 @@ void *scic_stp_io_request_get_d2h_reg_address( | |||
395 | static struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(struct scic_sds_stp_request *stp_req) | 396 | static struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(struct scic_sds_stp_request *stp_req) |
396 | { | 397 | { |
397 | struct scu_sgl_element *current_sgl; | 398 | struct scu_sgl_element *current_sgl; |
398 | struct scic_sds_request *sci_req = &stp_req->parent; | 399 | struct scic_sds_request *sci_req = to_sci_req(stp_req); |
399 | struct scic_sds_request_pio_sgl *pio_sgl = &stp_req->type.pio.request_current; | 400 | struct scic_sds_request_pio_sgl *pio_sgl = &stp_req->type.pio.request_current; |
400 | 401 | ||
401 | if (pio_sgl->sgl_set == SCU_SGL_ELEMENT_PAIR_A) { | 402 | if (pio_sgl->sgl_set == SCU_SGL_ELEMENT_PAIR_A) { |
@@ -489,60 +490,54 @@ static enum sci_status scic_sds_stp_request_non_data_await_d2h_frame_handler( | |||
489 | enum sci_status status; | 490 | enum sci_status status; |
490 | struct dev_to_host_fis *frame_header; | 491 | struct dev_to_host_fis *frame_header; |
491 | u32 *frame_buffer; | 492 | u32 *frame_buffer; |
492 | struct scic_sds_stp_request *stp_req = | 493 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
493 | container_of(sci_req, typeof(*stp_req), parent); | 494 | struct scic_sds_controller *scic = sci_req->owning_controller; |
494 | |||
495 | status = scic_sds_unsolicited_frame_control_get_header( | ||
496 | &stp_req->parent.owning_controller->uf_control, | ||
497 | frame_index, | ||
498 | (void **)&frame_header); | ||
499 | |||
500 | if (status == SCI_SUCCESS) { | ||
501 | switch (frame_header->fis_type) { | ||
502 | case FIS_REGD2H: | ||
503 | scic_sds_unsolicited_frame_control_get_buffer( | ||
504 | &stp_req->parent.owning_controller->uf_control, | ||
505 | frame_index, | ||
506 | (void **)&frame_buffer); | ||
507 | |||
508 | scic_sds_controller_copy_sata_response( | ||
509 | &stp_req->d2h_reg_fis, | ||
510 | (u32 *)frame_header, | ||
511 | frame_buffer); | ||
512 | |||
513 | /* The command has completed with error */ | ||
514 | scic_sds_request_set_status( | ||
515 | &stp_req->parent, | ||
516 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
517 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
518 | break; | ||
519 | |||
520 | default: | ||
521 | dev_warn(scic_to_dev(sci_req->owning_controller), | ||
522 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
523 | "violation occurred\n", | ||
524 | __func__, stp_req, frame_index); | ||
525 | |||
526 | scic_sds_request_set_status( | ||
527 | &stp_req->parent, | ||
528 | SCU_TASK_DONE_UNEXP_FIS, | ||
529 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
530 | break; | ||
531 | } | ||
532 | 495 | ||
533 | sci_base_state_machine_change_state( | 496 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, |
534 | &stp_req->parent.state_machine, | 497 | frame_index, |
535 | SCI_BASE_REQUEST_STATE_COMPLETED); | 498 | (void **)&frame_header); |
536 | 499 | ||
537 | /* Frame has been decoded return it to the controller */ | 500 | if (status != SCI_SUCCESS) { |
538 | scic_sds_controller_release_frame( | ||
539 | stp_req->parent.owning_controller, frame_index); | ||
540 | } else | ||
541 | dev_err(scic_to_dev(sci_req->owning_controller), | 501 | dev_err(scic_to_dev(sci_req->owning_controller), |
542 | "%s: SCIC IO Request 0x%p could not get frame header " | 502 | "%s: SCIC IO Request 0x%p could not get frame header " |
543 | "for frame index %d, status %x\n", | 503 | "for frame index %d, status %x\n", |
544 | __func__, stp_req, frame_index, status); | 504 | __func__, stp_req, frame_index, status); |
545 | 505 | ||
506 | return status; | ||
507 | } | ||
508 | |||
509 | switch (frame_header->fis_type) { | ||
510 | case FIS_REGD2H: | ||
511 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
512 | frame_index, | ||
513 | (void **)&frame_buffer); | ||
514 | |||
515 | scic_sds_controller_copy_sata_response(&stp_req->d2h_reg_fis, | ||
516 | frame_header, | ||
517 | frame_buffer); | ||
518 | |||
519 | /* The command has completed with error */ | ||
520 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_CHECK_RESPONSE, | ||
521 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
522 | break; | ||
523 | |||
524 | default: | ||
525 | dev_warn(scic_to_dev(scic), | ||
526 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
527 | "violation occurred\n", __func__, stp_req, | ||
528 | frame_index); | ||
529 | |||
530 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_UNEXP_FIS, | ||
531 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
532 | break; | ||
533 | } | ||
534 | |||
535 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
536 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
537 | |||
538 | /* Frame has been decoded return it to the controller */ | ||
539 | scic_sds_controller_release_frame(scic, frame_index); | ||
540 | |||
546 | return status; | 541 | return status; |
547 | } | 542 | } |
548 | 543 | ||
@@ -599,8 +594,7 @@ static const struct sci_base_state scic_sds_stp_request_started_non_data_substat | |||
599 | 594 | ||
600 | enum sci_status scic_sds_stp_non_data_request_construct(struct scic_sds_request *sci_req) | 595 | enum sci_status scic_sds_stp_non_data_request_construct(struct scic_sds_request *sci_req) |
601 | { | 596 | { |
602 | struct scic_sds_stp_request *stp_req = | 597 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
603 | container_of(sci_req, typeof(*stp_req), parent); | ||
604 | 598 | ||
605 | scic_sds_stp_non_ncq_request_construct(sci_req); | 599 | scic_sds_stp_non_ncq_request_construct(sci_req); |
606 | 600 | ||
@@ -617,36 +611,28 @@ enum sci_status scic_sds_stp_non_data_request_construct(struct scic_sds_request | |||
617 | 611 | ||
618 | #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */ | 612 | #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */ |
619 | 613 | ||
620 | /** | 614 | /* transmit DATA_FIS from (current sgl + offset) for input |
621 | * | ||
622 | * @sci_req: | ||
623 | * @length: | ||
624 | * | ||
625 | * This function will transmit DATA_FIS from (current sgl + offset) for input | ||
626 | * parameter length. current sgl and offset is alreay stored in the IO request | 615 | * parameter length. current sgl and offset is alreay stored in the IO request |
627 | * enum sci_status | ||
628 | */ | 616 | */ |
629 | |||
630 | static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame( | 617 | static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame( |
631 | struct scic_sds_request *sci_req, | 618 | struct scic_sds_request *sci_req, |
632 | u32 length) | 619 | u32 length) |
633 | { | 620 | { |
634 | struct scic_sds_stp_request *stp_req = | 621 | struct scic_sds_controller *scic = sci_req->owning_controller; |
635 | container_of(sci_req, typeof(*stp_req), parent); | 622 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
623 | struct scu_task_context *task_context; | ||
636 | struct scu_sgl_element *current_sgl; | 624 | struct scu_sgl_element *current_sgl; |
637 | 625 | ||
638 | /* | 626 | /* Recycle the TC and reconstruct it for sending out DATA FIS containing |
639 | * Recycle the TC and reconstruct it for sending out DATA FIS containing | 627 | * for the data from current_sgl+offset for the input length |
640 | * for the data from current_sgl+offset for the input length */ | 628 | */ |
641 | struct scu_task_context *task_context = scic_sds_controller_get_task_context_buffer( | 629 | task_context = scic_sds_controller_get_task_context_buffer(scic, |
642 | sci_req->owning_controller, | 630 | sci_req->io_tag); |
643 | sci_req->io_tag | ||
644 | ); | ||
645 | 631 | ||
646 | if (stp_req->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) | 632 | if (stp_req->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) |
647 | current_sgl = &(stp_req->type.pio.request_current.sgl_pair->A); | 633 | current_sgl = &stp_req->type.pio.request_current.sgl_pair->A; |
648 | else | 634 | else |
649 | current_sgl = &(stp_req->type.pio.request_current.sgl_pair->B); | 635 | current_sgl = &stp_req->type.pio.request_current.sgl_pair->B; |
650 | 636 | ||
651 | /* update the TC */ | 637 | /* update the TC */ |
652 | task_context->command_iu_upper = current_sgl->address_upper; | 638 | task_context->command_iu_upper = current_sgl->address_upper; |
@@ -658,23 +644,14 @@ static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame( | |||
658 | return scic_controller_continue_io(sci_req); | 644 | return scic_controller_continue_io(sci_req); |
659 | } | 645 | } |
660 | 646 | ||
661 | /** | 647 | static enum sci_status scic_sds_stp_request_pio_data_out_transmit_data(struct scic_sds_request *sci_req) |
662 | * | ||
663 | * @sci_req: | ||
664 | * | ||
665 | * enum sci_status | ||
666 | */ | ||
667 | static enum sci_status scic_sds_stp_request_pio_data_out_transmit_data( | ||
668 | struct scic_sds_request *sci_req) | ||
669 | { | 648 | { |
670 | 649 | ||
671 | struct scu_sgl_element *current_sgl; | 650 | struct scu_sgl_element *current_sgl; |
672 | u32 sgl_offset; | 651 | u32 sgl_offset; |
673 | u32 remaining_bytes_in_current_sgl = 0; | 652 | u32 remaining_bytes_in_current_sgl = 0; |
674 | enum sci_status status = SCI_SUCCESS; | 653 | enum sci_status status = SCI_SUCCESS; |
675 | 654 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | |
676 | struct scic_sds_stp_request *stp_req = | ||
677 | container_of(sci_req, typeof(*stp_req), parent); | ||
678 | 655 | ||
679 | sgl_offset = stp_req->type.pio.request_current.sgl_offset; | 656 | sgl_offset = stp_req->type.pio.request_current.sgl_offset; |
680 | 657 | ||
@@ -740,7 +717,7 @@ scic_sds_stp_request_pio_data_in_copy_data_buffer(struct scic_sds_stp_request *s | |||
740 | void *kaddr; | 717 | void *kaddr; |
741 | int total_len = len; | 718 | int total_len = len; |
742 | 719 | ||
743 | sci_req = &stp_req->parent; | 720 | sci_req = to_sci_req(stp_req); |
744 | ireq = scic_sds_request_get_user_request(sci_req); | 721 | ireq = scic_sds_request_get_user_request(sci_req); |
745 | task = isci_request_access_task(ireq); | 722 | task = isci_request_access_task(ireq); |
746 | src_addr = data_buf; | 723 | src_addr = data_buf; |
@@ -846,234 +823,184 @@ static enum sci_status scic_sds_stp_request_pio_await_h2d_completion_tc_completi | |||
846 | return status; | 823 | return status; |
847 | } | 824 | } |
848 | 825 | ||
849 | /** | 826 | static enum sci_status scic_sds_stp_request_pio_await_frame_frame_handler(struct scic_sds_request *sci_req, |
850 | * | 827 | u32 frame_index) |
851 | * @sci_req: | ||
852 | * @frame_index: | ||
853 | * | ||
854 | * enum sci_status | ||
855 | */ | ||
856 | static enum sci_status scic_sds_stp_request_pio_await_frame_frame_handler( | ||
857 | struct scic_sds_request *sci_req, | ||
858 | u32 frame_index) | ||
859 | { | 828 | { |
860 | enum sci_status status; | 829 | struct scic_sds_controller *scic = sci_req->owning_controller; |
861 | struct dev_to_host_fis *frame_header; | 830 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
862 | u32 *frame_buffer; | ||
863 | struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent); | ||
864 | struct isci_request *ireq = sci_req->ireq; | 831 | struct isci_request *ireq = sci_req->ireq; |
865 | struct sas_task *task = isci_request_access_task(ireq); | 832 | struct sas_task *task = isci_request_access_task(ireq); |
833 | struct dev_to_host_fis *frame_header; | ||
834 | enum sci_status status; | ||
835 | u32 *frame_buffer; | ||
866 | 836 | ||
867 | status = scic_sds_unsolicited_frame_control_get_header( | 837 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, |
868 | &(stp_req->parent.owning_controller->uf_control), | 838 | frame_index, |
869 | frame_index, | 839 | (void **)&frame_header); |
870 | (void **)&frame_header); | ||
871 | 840 | ||
872 | if (status == SCI_SUCCESS) { | 841 | if (status != SCI_SUCCESS) { |
873 | switch (frame_header->fis_type) { | 842 | dev_err(scic_to_dev(scic), |
874 | case FIS_PIO_SETUP: | 843 | "%s: SCIC IO Request 0x%p could not get frame header " |
875 | /* Get from the frame buffer the PIO Setup Data */ | 844 | "for frame index %d, status %x\n", |
876 | scic_sds_unsolicited_frame_control_get_buffer( | 845 | __func__, stp_req, frame_index, status); |
877 | &(stp_req->parent.owning_controller->uf_control), | 846 | return status; |
878 | frame_index, | 847 | } |
879 | (void **)&frame_buffer); | 848 | |
880 | 849 | switch (frame_header->fis_type) { | |
881 | /* Get the data from the PIO Setup The SCU Hardware | 850 | case FIS_PIO_SETUP: |
882 | * returns first word in the frame_header and the rest | 851 | /* Get from the frame buffer the PIO Setup Data */ |
883 | * of the data is in the frame buffer so we need to back | 852 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, |
884 | * up one dword | 853 | frame_index, |
885 | */ | 854 | (void **)&frame_buffer); |
855 | |||
856 | /* Get the data from the PIO Setup The SCU Hardware returns | ||
857 | * first word in the frame_header and the rest of the data is in | ||
858 | * the frame buffer so we need to back up one dword | ||
859 | */ | ||
886 | 860 | ||
887 | /* transfer_count: first 16bits in the 4th dword */ | 861 | /* transfer_count: first 16bits in the 4th dword */ |
888 | stp_req->type.pio.pio_transfer_bytes = | 862 | stp_req->type.pio.pio_transfer_bytes = frame_buffer[3] & 0xffff; |
889 | frame_buffer[3] & 0xffff; | ||
890 | 863 | ||
891 | /* ending_status: 4th byte in the 3rd dword */ | 864 | /* ending_status: 4th byte in the 3rd dword */ |
892 | stp_req->type.pio.ending_status = | 865 | stp_req->type.pio.ending_status = (frame_buffer[2] >> 24) & 0xff; |
893 | (frame_buffer[2] >> 24) & 0xff; | ||
894 | 866 | ||
895 | scic_sds_controller_copy_sata_response( | 867 | scic_sds_controller_copy_sata_response(&stp_req->d2h_reg_fis, |
896 | &stp_req->d2h_reg_fis, | 868 | frame_header, |
897 | (u32 *)frame_header, | 869 | frame_buffer); |
898 | frame_buffer); | ||
899 | 870 | ||
900 | stp_req->d2h_reg_fis.status = | 871 | stp_req->d2h_reg_fis.status = stp_req->type.pio.ending_status; |
901 | stp_req->type.pio.ending_status; | ||
902 | 872 | ||
903 | /* The next state is dependent on whether the | 873 | /* The next state is dependent on whether the |
904 | * request was PIO Data-in or Data out | 874 | * request was PIO Data-in or Data out |
875 | */ | ||
876 | if (task->data_dir == DMA_FROM_DEVICE) { | ||
877 | sci_base_state_machine_change_state(&sci_req->started_substate_machine, | ||
878 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE); | ||
879 | } else if (task->data_dir == DMA_TO_DEVICE) { | ||
880 | /* Transmit data */ | ||
881 | status = scic_sds_stp_request_pio_data_out_transmit_data(sci_req); | ||
882 | if (status != SCI_SUCCESS) | ||
883 | break; | ||
884 | sci_base_state_machine_change_state(&sci_req->started_substate_machine, | ||
885 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE); | ||
886 | } | ||
887 | break; | ||
888 | case FIS_SETDEVBITS: | ||
889 | sci_base_state_machine_change_state(&sci_req->started_substate_machine, | ||
890 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
891 | break; | ||
892 | case FIS_REGD2H: | ||
893 | if (frame_header->status & ATA_BUSY) { | ||
894 | /* Now why is the drive sending a D2H Register FIS when | ||
895 | * it is still busy? Do nothing since we are still in | ||
896 | * the right state. | ||
905 | */ | 897 | */ |
906 | if (task->data_dir == DMA_FROM_DEVICE) { | 898 | dev_dbg(scic_to_dev(scic), |
907 | sci_base_state_machine_change_state( | 899 | "%s: SCIC PIO Request 0x%p received " |
908 | &stp_req->parent.started_substate_machine, | 900 | "D2H Register FIS with BSY status " |
909 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE); | 901 | "0x%x\n", __func__, stp_req, |
910 | } else if (task->data_dir == DMA_TO_DEVICE) { | 902 | frame_header->status); |
911 | /* Transmit data */ | ||
912 | status = scic_sds_stp_request_pio_data_out_transmit_data(sci_req); | ||
913 | if (status == SCI_SUCCESS) { | ||
914 | sci_base_state_machine_change_state( | ||
915 | &stp_req->parent.started_substate_machine, | ||
916 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE); | ||
917 | } | ||
918 | } | ||
919 | break; | 903 | break; |
904 | } | ||
920 | 905 | ||
921 | case FIS_SETDEVBITS: | 906 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, |
922 | sci_base_state_machine_change_state( | 907 | frame_index, |
923 | &stp_req->parent.started_substate_machine, | 908 | (void **)&frame_buffer); |
924 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
925 | break; | ||
926 | 909 | ||
927 | case FIS_REGD2H: | 910 | scic_sds_controller_copy_sata_response(&stp_req->d2h_reg_fis, |
928 | if ((frame_header->status & ATA_BUSY) == 0) { | 911 | frame_header, |
929 | scic_sds_unsolicited_frame_control_get_buffer( | 912 | frame_buffer); |
930 | &(stp_req->parent.owning_controller->uf_control), | ||
931 | frame_index, | ||
932 | (void **)&frame_buffer); | ||
933 | |||
934 | scic_sds_controller_copy_sata_response( | ||
935 | &stp_req->d2h_reg_fis, | ||
936 | (u32 *)frame_header, | ||
937 | frame_buffer); | ||
938 | |||
939 | scic_sds_request_set_status( | ||
940 | &stp_req->parent, | ||
941 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
942 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
943 | |||
944 | sci_base_state_machine_change_state( | ||
945 | &stp_req->parent.state_machine, | ||
946 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
947 | } else { | ||
948 | /* Now why is the drive sending a D2H Register | ||
949 | * FIS when it is still busy? | ||
950 | * Do nothing since we are still in the right | ||
951 | * state. | ||
952 | */ | ||
953 | dev_dbg(scic_to_dev(sci_req->owning_controller), | ||
954 | "%s: SCIC PIO Request 0x%p received " | ||
955 | "D2H Register FIS with BSY status " | ||
956 | "0x%x\n", | ||
957 | __func__, | ||
958 | stp_req, | ||
959 | frame_header->status); | ||
960 | } | ||
961 | break; | ||
962 | 913 | ||
963 | default: | 914 | scic_sds_request_set_status(sci_req, |
964 | /* FIXME: what do we do here? */ | 915 | SCU_TASK_DONE_CHECK_RESPONSE, |
965 | break; | 916 | SCI_FAILURE_IO_RESPONSE_VALID); |
966 | } | ||
967 | 917 | ||
968 | /* Frame is decoded return it to the controller */ | 918 | sci_base_state_machine_change_state(&sci_req->state_machine, |
969 | scic_sds_controller_release_frame( | 919 | SCI_BASE_REQUEST_STATE_COMPLETED); |
970 | stp_req->parent.owning_controller, | 920 | break; |
971 | frame_index); | 921 | default: |
972 | } else | 922 | /* FIXME: what do we do here? */ |
973 | dev_err(scic_to_dev(sci_req->owning_controller), | 923 | break; |
974 | "%s: SCIC IO Request 0x%p could not get frame header " | 924 | } |
975 | "for frame index %d, status %x\n", | 925 | |
976 | __func__, stp_req, frame_index, status); | 926 | /* Frame is decoded return it to the controller */ |
927 | scic_sds_controller_release_frame(scic, frame_index); | ||
977 | 928 | ||
978 | return status; | 929 | return status; |
979 | } | 930 | } |
980 | 931 | ||
981 | /** | 932 | static enum sci_status scic_sds_stp_request_pio_data_in_await_data_frame_handler(struct scic_sds_request *sci_req, |
982 | * | 933 | u32 frame_index) |
983 | * @sci_req: | ||
984 | * @frame_index: | ||
985 | * | ||
986 | * enum sci_status | ||
987 | */ | ||
988 | static enum sci_status scic_sds_stp_request_pio_data_in_await_data_frame_handler( | ||
989 | struct scic_sds_request *sci_req, | ||
990 | u32 frame_index) | ||
991 | { | 934 | { |
992 | enum sci_status status; | 935 | enum sci_status status; |
993 | struct dev_to_host_fis *frame_header; | 936 | struct dev_to_host_fis *frame_header; |
994 | struct sata_fis_data *frame_buffer; | 937 | struct sata_fis_data *frame_buffer; |
995 | struct scic_sds_stp_request *stp_req = | 938 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
996 | container_of(sci_req, typeof(*stp_req), parent); | 939 | struct scic_sds_controller *scic = sci_req->owning_controller; |
997 | 940 | ||
998 | status = scic_sds_unsolicited_frame_control_get_header( | 941 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, |
999 | &(stp_req->parent.owning_controller->uf_control), | 942 | frame_index, |
1000 | frame_index, | 943 | (void **)&frame_header); |
1001 | (void **)&frame_header); | ||
1002 | 944 | ||
1003 | if (status == SCI_SUCCESS) { | 945 | if (status != SCI_SUCCESS) { |
1004 | if (frame_header->fis_type == FIS_DATA) { | 946 | dev_err(scic_to_dev(scic), |
1005 | if (stp_req->type.pio.request_current.sgl_pair == | 947 | "%s: SCIC IO Request 0x%p could not get frame header " |
1006 | NULL) { | 948 | "for frame index %d, status %x\n", |
1007 | stp_req->parent.saved_rx_frame_index = | 949 | __func__, stp_req, frame_index, status); |
1008 | frame_index; | 950 | return status; |
1009 | stp_req->type.pio.pio_transfer_bytes = 0; | 951 | } |
1010 | } else { | ||
1011 | status = scic_sds_unsolicited_frame_control_get_buffer( | ||
1012 | &(stp_req->parent.owning_controller->uf_control), | ||
1013 | frame_index, | ||
1014 | (void **)&frame_buffer); | ||
1015 | |||
1016 | status = scic_sds_stp_request_pio_data_in_copy_data( | ||
1017 | stp_req, | ||
1018 | (u8 *)frame_buffer); | ||
1019 | |||
1020 | /* Frame is decoded return it to the controller */ | ||
1021 | scic_sds_controller_release_frame( | ||
1022 | stp_req->parent.owning_controller, | ||
1023 | frame_index); | ||
1024 | } | ||
1025 | 952 | ||
1026 | /* | 953 | if (frame_header->fis_type == FIS_DATA) { |
1027 | * Check for the end of the transfer, are there more | 954 | if (stp_req->type.pio.request_current.sgl_pair == NULL) { |
1028 | * bytes remaining for this data transfer | 955 | sci_req->saved_rx_frame_index = frame_index; |
1029 | */ | 956 | stp_req->type.pio.pio_transfer_bytes = 0; |
1030 | if ((status == SCI_SUCCESS) && | ||
1031 | (stp_req->type.pio.pio_transfer_bytes == 0)) { | ||
1032 | if ((stp_req->type.pio.ending_status & | ||
1033 | ATA_BUSY) == 0) { | ||
1034 | scic_sds_request_set_status( | ||
1035 | &stp_req->parent, | ||
1036 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
1037 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
1038 | |||
1039 | sci_base_state_machine_change_state( | ||
1040 | &stp_req->parent.state_machine, | ||
1041 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1042 | } else { | ||
1043 | sci_base_state_machine_change_state( | ||
1044 | &sci_req->started_substate_machine, | ||
1045 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
1046 | } | ||
1047 | } | ||
1048 | } else { | 957 | } else { |
1049 | dev_err(scic_to_dev(sci_req->owning_controller), | 958 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, |
1050 | "%s: SCIC PIO Request 0x%p received frame %d " | 959 | frame_index, |
1051 | "with fis type 0x%02x when expecting a data " | 960 | (void **)&frame_buffer); |
1052 | "fis.\n", | ||
1053 | __func__, | ||
1054 | stp_req, | ||
1055 | frame_index, | ||
1056 | frame_header->fis_type); | ||
1057 | |||
1058 | scic_sds_request_set_status( | ||
1059 | &stp_req->parent, | ||
1060 | SCU_TASK_DONE_GOOD, | ||
1061 | SCI_FAILURE_IO_REQUIRES_SCSI_ABORT); | ||
1062 | 961 | ||
1063 | sci_base_state_machine_change_state( | 962 | status = scic_sds_stp_request_pio_data_in_copy_data(stp_req, |
1064 | &stp_req->parent.state_machine, | 963 | (u8 *)frame_buffer); |
1065 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1066 | 964 | ||
1067 | /* Frame is decoded return it to the controller */ | 965 | /* Frame is decoded return it to the controller */ |
1068 | scic_sds_controller_release_frame( | 966 | scic_sds_controller_release_frame(scic, frame_index); |
1069 | stp_req->parent.owning_controller, | ||
1070 | frame_index); | ||
1071 | } | 967 | } |
1072 | } else | 968 | |
1073 | dev_err(scic_to_dev(sci_req->owning_controller), | 969 | /* Check for the end of the transfer, are there more |
1074 | "%s: SCIC IO Request 0x%p could not get frame header " | 970 | * bytes remaining for this data transfer |
1075 | "for frame index %d, status %x\n", | 971 | */ |
1076 | __func__, stp_req, frame_index, status); | 972 | if (status != SCI_SUCCESS || |
973 | stp_req->type.pio.pio_transfer_bytes != 0) | ||
974 | return status; | ||
975 | |||
976 | if ((stp_req->type.pio.ending_status & ATA_BUSY) == 0) { | ||
977 | scic_sds_request_set_status(sci_req, | ||
978 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
979 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
980 | |||
981 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
982 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
983 | } else { | ||
984 | sci_base_state_machine_change_state(&sci_req->started_substate_machine, | ||
985 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
986 | } | ||
987 | } else { | ||
988 | dev_err(scic_to_dev(scic), | ||
989 | "%s: SCIC PIO Request 0x%p received frame %d " | ||
990 | "with fis type 0x%02x when expecting a data " | ||
991 | "fis.\n", __func__, stp_req, frame_index, | ||
992 | frame_header->fis_type); | ||
993 | |||
994 | scic_sds_request_set_status(sci_req, | ||
995 | SCU_TASK_DONE_GOOD, | ||
996 | SCI_FAILURE_IO_REQUIRES_SCSI_ABORT); | ||
997 | |||
998 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
999 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1000 | |||
1001 | /* Frame is decoded return it to the controller */ | ||
1002 | scic_sds_controller_release_frame(scic, frame_index); | ||
1003 | } | ||
1077 | 1004 | ||
1078 | return status; | 1005 | return status; |
1079 | } | 1006 | } |
@@ -1093,8 +1020,7 @@ static enum sci_status scic_sds_stp_request_pio_data_out_await_data_transmit_com | |||
1093 | { | 1020 | { |
1094 | enum sci_status status = SCI_SUCCESS; | 1021 | enum sci_status status = SCI_SUCCESS; |
1095 | bool all_frames_transferred = false; | 1022 | bool all_frames_transferred = false; |
1096 | struct scic_sds_stp_request *stp_req = | 1023 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
1097 | container_of(sci_req, typeof(*stp_req), parent); | ||
1098 | 1024 | ||
1099 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { | 1025 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { |
1100 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): | 1026 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): |
@@ -1280,8 +1206,7 @@ enum sci_status | |||
1280 | scic_sds_stp_pio_request_construct(struct scic_sds_request *sci_req, | 1206 | scic_sds_stp_pio_request_construct(struct scic_sds_request *sci_req, |
1281 | bool copy_rx_frame) | 1207 | bool copy_rx_frame) |
1282 | { | 1208 | { |
1283 | struct scic_sds_stp_request *stp_req = | 1209 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
1284 | container_of(sci_req, typeof(*stp_req), parent); | ||
1285 | struct scic_sds_stp_pio_request *pio = &stp_req->type.pio; | 1210 | struct scic_sds_stp_pio_request *pio = &stp_req->type.pio; |
1286 | 1211 | ||
1287 | scic_sds_stp_non_ncq_request_construct(sci_req); | 1212 | scic_sds_stp_non_ncq_request_construct(sci_req); |
@@ -1325,91 +1250,66 @@ static void scic_sds_stp_request_udma_complete_request( | |||
1325 | SCI_BASE_REQUEST_STATE_COMPLETED); | 1250 | SCI_BASE_REQUEST_STATE_COMPLETED); |
1326 | } | 1251 | } |
1327 | 1252 | ||
1328 | /** | 1253 | static enum sci_status scic_sds_stp_request_udma_general_frame_handler(struct scic_sds_request *sci_req, |
1329 | * | 1254 | u32 frame_index) |
1330 | * @sci_req: | ||
1331 | * @frame_index: | ||
1332 | * | ||
1333 | * enum sci_status | ||
1334 | */ | ||
1335 | static enum sci_status scic_sds_stp_request_udma_general_frame_handler( | ||
1336 | struct scic_sds_request *sci_req, | ||
1337 | u32 frame_index) | ||
1338 | { | 1255 | { |
1339 | enum sci_status status; | 1256 | struct scic_sds_controller *scic = sci_req->owning_controller; |
1257 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
1340 | struct dev_to_host_fis *frame_header; | 1258 | struct dev_to_host_fis *frame_header; |
1259 | enum sci_status status; | ||
1341 | u32 *frame_buffer; | 1260 | u32 *frame_buffer; |
1342 | 1261 | ||
1343 | status = scic_sds_unsolicited_frame_control_get_header( | 1262 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, |
1344 | &sci_req->owning_controller->uf_control, | 1263 | frame_index, |
1345 | frame_index, | 1264 | (void **)&frame_header); |
1346 | (void **)&frame_header); | ||
1347 | 1265 | ||
1348 | if ((status == SCI_SUCCESS) && | 1266 | if ((status == SCI_SUCCESS) && |
1349 | (frame_header->fis_type == FIS_REGD2H)) { | 1267 | (frame_header->fis_type == FIS_REGD2H)) { |
1350 | scic_sds_unsolicited_frame_control_get_buffer( | 1268 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, |
1351 | &sci_req->owning_controller->uf_control, | 1269 | frame_index, |
1352 | frame_index, | 1270 | (void **)&frame_buffer); |
1353 | (void **)&frame_buffer); | 1271 | |
1354 | 1272 | scic_sds_controller_copy_sata_response(&stp_req->d2h_reg_fis, | |
1355 | scic_sds_controller_copy_sata_response( | 1273 | frame_header, |
1356 | &((struct scic_sds_stp_request *)sci_req)->d2h_reg_fis, | 1274 | frame_buffer); |
1357 | (u32 *)frame_header, | ||
1358 | frame_buffer); | ||
1359 | } | 1275 | } |
1360 | 1276 | ||
1361 | scic_sds_controller_release_frame( | 1277 | scic_sds_controller_release_frame(scic, frame_index); |
1362 | sci_req->owning_controller, frame_index); | ||
1363 | 1278 | ||
1364 | return status; | 1279 | return status; |
1365 | } | 1280 | } |
1366 | 1281 | ||
1367 | /** | ||
1368 | * This method process TC completions while in the state where we are waiting | ||
1369 | * for TC completions. | ||
1370 | * @sci_req: | ||
1371 | * @completion_code: | ||
1372 | * | ||
1373 | * enum sci_status | ||
1374 | */ | ||
1375 | static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler( | 1282 | static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler( |
1376 | struct scic_sds_request *request, | 1283 | struct scic_sds_request *sci_req, |
1377 | u32 completion_code) | 1284 | u32 completion_code) |
1378 | { | 1285 | { |
1286 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
1379 | enum sci_status status = SCI_SUCCESS; | 1287 | enum sci_status status = SCI_SUCCESS; |
1380 | struct scic_sds_stp_request *sci_req = (struct scic_sds_stp_request *)request; | ||
1381 | 1288 | ||
1382 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { | 1289 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { |
1383 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): | 1290 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): |
1384 | scic_sds_stp_request_udma_complete_request( | 1291 | scic_sds_stp_request_udma_complete_request(sci_req, |
1385 | &sci_req->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS | 1292 | SCU_TASK_DONE_GOOD, |
1386 | ); | 1293 | SCI_SUCCESS); |
1387 | break; | 1294 | break; |
1388 | |||
1389 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS): | 1295 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS): |
1390 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR): | 1296 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR): |
1391 | /* | 1297 | /* |
1392 | * We must check ther response buffer to see if the D2H Register FIS was | 1298 | * We must check ther response buffer to see if the D2H Register FIS was |
1393 | * received before we got the TC completion. */ | 1299 | * received before we got the TC completion. */ |
1394 | if (sci_req->d2h_reg_fis.fis_type == FIS_REGD2H) { | 1300 | if (stp_req->d2h_reg_fis.fis_type == FIS_REGD2H) { |
1395 | scic_sds_remote_device_suspend( | 1301 | scic_sds_remote_device_suspend(sci_req->target_device, |
1396 | sci_req->parent.target_device, | 1302 | SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))); |
1397 | SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)) | ||
1398 | ); | ||
1399 | 1303 | ||
1400 | scic_sds_stp_request_udma_complete_request( | 1304 | scic_sds_stp_request_udma_complete_request(sci_req, |
1401 | &sci_req->parent, | 1305 | SCU_TASK_DONE_CHECK_RESPONSE, |
1402 | SCU_TASK_DONE_CHECK_RESPONSE, | 1306 | SCI_FAILURE_IO_RESPONSE_VALID); |
1403 | SCI_FAILURE_IO_RESPONSE_VALID | ||
1404 | ); | ||
1405 | } else { | 1307 | } else { |
1406 | /* | 1308 | /* |
1407 | * If we have an error completion status for the TC then we can expect a | 1309 | * If we have an error completion status for the TC then we can expect a |
1408 | * D2H register FIS from the device so we must change state to wait for it */ | 1310 | * D2H register FIS from the device so we must change state to wait for it */ |
1409 | sci_base_state_machine_change_state( | 1311 | sci_base_state_machine_change_state(&sci_req->started_substate_machine, |
1410 | &sci_req->parent.started_substate_machine, | 1312 | SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE); |
1411 | SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE | ||
1412 | ); | ||
1413 | } | 1313 | } |
1414 | break; | 1314 | break; |
1415 | 1315 | ||
@@ -1422,18 +1322,14 @@ static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completi | |||
1422 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR): | 1322 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR): |
1423 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR): | 1323 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR): |
1424 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR): | 1324 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR): |
1425 | scic_sds_remote_device_suspend( | 1325 | scic_sds_remote_device_suspend(sci_req->target_device, |
1426 | sci_req->parent.target_device, | 1326 | SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))); |
1427 | SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)) | ||
1428 | ); | ||
1429 | /* Fall through to the default case */ | 1327 | /* Fall through to the default case */ |
1430 | default: | 1328 | default: |
1431 | /* All other completion status cause the IO to be complete. */ | 1329 | /* All other completion status cause the IO to be complete. */ |
1432 | scic_sds_stp_request_udma_complete_request( | 1330 | scic_sds_stp_request_udma_complete_request(sci_req, |
1433 | &sci_req->parent, | 1331 | SCU_NORMALIZE_COMPLETION_STATUS(completion_code), |
1434 | SCU_NORMALIZE_COMPLETION_STATUS(completion_code), | 1332 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); |
1435 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR | ||
1436 | ); | ||
1437 | break; | 1333 | break; |
1438 | } | 1334 | } |
1439 | 1335 | ||
@@ -1449,13 +1345,12 @@ static enum sci_status scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler | |||
1449 | /* Use the general frame handler to copy the resposne data */ | 1345 | /* Use the general frame handler to copy the resposne data */ |
1450 | status = scic_sds_stp_request_udma_general_frame_handler(sci_req, frame_index); | 1346 | status = scic_sds_stp_request_udma_general_frame_handler(sci_req, frame_index); |
1451 | 1347 | ||
1452 | if (status == SCI_SUCCESS) { | 1348 | if (status != SCI_SUCCESS) |
1453 | scic_sds_stp_request_udma_complete_request( | 1349 | return status; |
1454 | sci_req, | 1350 | |
1455 | SCU_TASK_DONE_CHECK_RESPONSE, | 1351 | scic_sds_stp_request_udma_complete_request(sci_req, |
1456 | SCI_FAILURE_IO_RESPONSE_VALID | 1352 | SCU_TASK_DONE_CHECK_RESPONSE, |
1457 | ); | 1353 | SCI_FAILURE_IO_RESPONSE_VALID); |
1458 | } | ||
1459 | 1354 | ||
1460 | return status; | 1355 | return status; |
1461 | } | 1356 | } |
@@ -1636,67 +1531,58 @@ static enum sci_status scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_c | |||
1636 | * if the received frame was processed successfully. | 1531 | * if the received frame was processed successfully. |
1637 | */ | 1532 | */ |
1638 | static enum sci_status scic_sds_stp_request_soft_reset_await_d2h_frame_handler( | 1533 | static enum sci_status scic_sds_stp_request_soft_reset_await_d2h_frame_handler( |
1639 | struct scic_sds_request *request, | 1534 | struct scic_sds_request *sci_req, |
1640 | u32 frame_index) | 1535 | u32 frame_index) |
1641 | { | 1536 | { |
1642 | enum sci_status status; | 1537 | enum sci_status status; |
1643 | struct dev_to_host_fis *frame_header; | 1538 | struct dev_to_host_fis *frame_header; |
1644 | u32 *frame_buffer; | 1539 | u32 *frame_buffer; |
1645 | struct scic_sds_stp_request *stp_req = | 1540 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
1646 | (struct scic_sds_stp_request *)request; | 1541 | struct scic_sds_controller *scic = sci_req->owning_controller; |
1542 | |||
1543 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1544 | frame_index, | ||
1545 | (void **)&frame_header); | ||
1546 | if (status != SCI_SUCCESS) { | ||
1547 | dev_err(scic_to_dev(scic), | ||
1548 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
1549 | "for frame index %d, status %x\n", | ||
1550 | __func__, stp_req, frame_index, status); | ||
1551 | return status; | ||
1552 | } | ||
1647 | 1553 | ||
1648 | status = scic_sds_unsolicited_frame_control_get_header( | 1554 | switch (frame_header->fis_type) { |
1649 | &(stp_req->parent.owning_controller->uf_control), | 1555 | case FIS_REGD2H: |
1650 | frame_index, | 1556 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, |
1651 | (void **)&frame_header); | 1557 | frame_index, |
1558 | (void **)&frame_buffer); | ||
1652 | 1559 | ||
1653 | if (status == SCI_SUCCESS) { | 1560 | scic_sds_controller_copy_sata_response(&stp_req->d2h_reg_fis, |
1654 | switch (frame_header->fis_type) { | 1561 | frame_header, |
1655 | case FIS_REGD2H: | 1562 | frame_buffer); |
1656 | scic_sds_unsolicited_frame_control_get_buffer( | ||
1657 | &(stp_req->parent.owning_controller->uf_control), | ||
1658 | frame_index, | ||
1659 | (void **)&frame_buffer); | ||
1660 | |||
1661 | scic_sds_controller_copy_sata_response( | ||
1662 | &stp_req->d2h_reg_fis, | ||
1663 | (u32 *)frame_header, | ||
1664 | frame_buffer); | ||
1665 | |||
1666 | /* The command has completed with error */ | ||
1667 | scic_sds_request_set_status( | ||
1668 | &stp_req->parent, | ||
1669 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
1670 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
1671 | break; | ||
1672 | 1563 | ||
1673 | default: | 1564 | /* The command has completed with error */ |
1674 | dev_warn(scic_to_dev(request->owning_controller), | 1565 | scic_sds_request_set_status(sci_req, |
1675 | "%s: IO Request:0x%p Frame Id:%d protocol " | 1566 | SCU_TASK_DONE_CHECK_RESPONSE, |
1676 | "violation occurred\n", | 1567 | SCI_FAILURE_IO_RESPONSE_VALID); |
1677 | __func__, | 1568 | break; |
1678 | stp_req, | ||
1679 | frame_index); | ||
1680 | |||
1681 | scic_sds_request_set_status( | ||
1682 | &stp_req->parent, | ||
1683 | SCU_TASK_DONE_UNEXP_FIS, | ||
1684 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
1685 | break; | ||
1686 | } | ||
1687 | 1569 | ||
1688 | sci_base_state_machine_change_state( | 1570 | default: |
1689 | &stp_req->parent.state_machine, | 1571 | dev_warn(scic_to_dev(scic), |
1690 | SCI_BASE_REQUEST_STATE_COMPLETED); | 1572 | "%s: IO Request:0x%p Frame Id:%d protocol " |
1573 | "violation occurred\n", __func__, stp_req, | ||
1574 | frame_index); | ||
1691 | 1575 | ||
1692 | /* Frame has been decoded return it to the controller */ | 1576 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_UNEXP_FIS, |
1693 | scic_sds_controller_release_frame( | 1577 | SCI_FAILURE_PROTOCOL_VIOLATION); |
1694 | stp_req->parent.owning_controller, frame_index); | 1578 | break; |
1695 | } else | 1579 | } |
1696 | dev_err(scic_to_dev(request->owning_controller), | 1580 | |
1697 | "%s: SCIC IO Request 0x%p could not get frame header " | 1581 | sci_base_state_machine_change_state(&sci_req->state_machine, |
1698 | "for frame index %d, status %x\n", | 1582 | SCI_BASE_REQUEST_STATE_COMPLETED); |
1699 | __func__, stp_req, frame_index, status); | 1583 | |
1584 | /* Frame has been decoded return it to the controller */ | ||
1585 | scic_sds_controller_release_frame(scic, frame_index); | ||
1700 | 1586 | ||
1701 | return status; | 1587 | return status; |
1702 | } | 1588 | } |
@@ -1787,8 +1673,7 @@ static const struct sci_base_state scic_sds_stp_request_started_soft_reset_subst | |||
1787 | 1673 | ||
1788 | enum sci_status scic_sds_stp_soft_reset_request_construct(struct scic_sds_request *sci_req) | 1674 | enum sci_status scic_sds_stp_soft_reset_request_construct(struct scic_sds_request *sci_req) |
1789 | { | 1675 | { |
1790 | struct scic_sds_stp_request *stp_req = | 1676 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
1791 | container_of(sci_req, typeof(*stp_req), parent); | ||
1792 | 1677 | ||
1793 | scic_sds_stp_non_ncq_request_construct(sci_req); | 1678 | scic_sds_stp_non_ncq_request_construct(sci_req); |
1794 | 1679 | ||
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.h b/drivers/scsi/isci/core/scic_sds_stp_request.h index 50cb48ef554e..6d02030b6cd6 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.h +++ b/drivers/scsi/isci/core/scic_sds_stp_request.h | |||
@@ -58,17 +58,8 @@ | |||
58 | 58 | ||
59 | #include <linux/dma-mapping.h> | 59 | #include <linux/dma-mapping.h> |
60 | #include <scsi/sas.h> | 60 | #include <scsi/sas.h> |
61 | #include "scic_sds_request.h" | ||
62 | 61 | ||
63 | /** | ||
64 | * This structure represents the additional information that is required to | ||
65 | * handle SATA PIO requests. | ||
66 | * | ||
67 | * | ||
68 | */ | ||
69 | struct scic_sds_stp_request { | 62 | struct scic_sds_stp_request { |
70 | struct scic_sds_request parent; | ||
71 | |||
72 | struct dev_to_host_fis d2h_reg_fis; | 63 | struct dev_to_host_fis d2h_reg_fis; |
73 | 64 | ||
74 | union { | 65 | union { |
@@ -125,7 +116,6 @@ struct scic_sds_stp_request { | |||
125 | u32 device_preferred_cdb_length; | 116 | u32 device_preferred_cdb_length; |
126 | } packet; | 117 | } packet; |
127 | } type; | 118 | } type; |
128 | |||
129 | }; | 119 | }; |
130 | 120 | ||
131 | /** | 121 | /** |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index cabad0b03ee5..12f2df947362 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -64,7 +64,7 @@ | |||
64 | #include "request.h" | 64 | #include "request.h" |
65 | #include "sata.h" | 65 | #include "sata.h" |
66 | #include "task.h" | 66 | #include "task.h" |
67 | #include "scic_sds_stp_request.h" | 67 | #include "scic_sds_request.h" |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * isci_task_refuse() - complete the request to the upper layer driver in | 70 | * isci_task_refuse() - complete the request to the upper layer driver in |
@@ -1435,8 +1435,7 @@ isci_task_request_complete(struct isci_host *ihost, | |||
1435 | struct isci_tmf *tmf = isci_request_access_tmf(ireq); | 1435 | struct isci_tmf *tmf = isci_request_access_tmf(ireq); |
1436 | struct completion *tmf_complete; | 1436 | struct completion *tmf_complete; |
1437 | struct scic_sds_request *sci_req = ireq->sci_request_handle; | 1437 | struct scic_sds_request *sci_req = ireq->sci_request_handle; |
1438 | struct scic_sds_stp_request *stp_req = | 1438 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; |
1439 | container_of(sci_req, typeof(*stp_req), parent); | ||
1440 | 1439 | ||
1441 | dev_dbg(&ihost->pdev->dev, | 1440 | dev_dbg(&ihost->pdev->dev, |
1442 | "%s: request = %p, status=%d\n", | 1441 | "%s: request = %p, status=%d\n", |