diff options
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r-- | drivers/scsi/isci/request.c | 509 |
1 files changed, 146 insertions, 363 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 1f314d0d71d5..f4e80f31423c 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -2491,9 +2491,6 @@ static void isci_request_process_response_iu( | |||
2491 | * @request: This parameter is the completed isci_request object. | 2491 | * @request: This parameter is the completed isci_request object. |
2492 | * @response_ptr: This parameter specifies the service response for the I/O. | 2492 | * @response_ptr: This parameter specifies the service response for the I/O. |
2493 | * @status_ptr: This parameter specifies the exec status for the I/O. | 2493 | * @status_ptr: This parameter specifies the exec status for the I/O. |
2494 | * @complete_to_host_ptr: This parameter specifies the action to be taken by | ||
2495 | * the LLDD with respect to completing this request or forcing an abort | ||
2496 | * condition on the I/O. | ||
2497 | * @open_rej_reason: This parameter specifies the encoded reason for the | 2494 | * @open_rej_reason: This parameter specifies the encoded reason for the |
2498 | * abandon-class reject. | 2495 | * abandon-class reject. |
2499 | * | 2496 | * |
@@ -2504,14 +2501,12 @@ static void isci_request_set_open_reject_status( | |||
2504 | struct sas_task *task, | 2501 | struct sas_task *task, |
2505 | enum service_response *response_ptr, | 2502 | enum service_response *response_ptr, |
2506 | enum exec_status *status_ptr, | 2503 | enum exec_status *status_ptr, |
2507 | enum isci_completion_selection *complete_to_host_ptr, | ||
2508 | enum sas_open_rej_reason open_rej_reason) | 2504 | enum sas_open_rej_reason open_rej_reason) |
2509 | { | 2505 | { |
2510 | /* Task in the target is done. */ | 2506 | /* Task in the target is done. */ |
2511 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2507 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2512 | *response_ptr = SAS_TASK_UNDELIVERED; | 2508 | *response_ptr = SAS_TASK_UNDELIVERED; |
2513 | *status_ptr = SAS_OPEN_REJECT; | 2509 | *status_ptr = SAS_OPEN_REJECT; |
2514 | *complete_to_host_ptr = isci_perform_normal_io_completion; | ||
2515 | task->task_status.open_rej_reason = open_rej_reason; | 2510 | task->task_status.open_rej_reason = open_rej_reason; |
2516 | } | 2511 | } |
2517 | 2512 | ||
@@ -2521,9 +2516,6 @@ static void isci_request_set_open_reject_status( | |||
2521 | * @request: This parameter is the completed isci_request object. | 2516 | * @request: This parameter is the completed isci_request object. |
2522 | * @response_ptr: This parameter specifies the service response for the I/O. | 2517 | * @response_ptr: This parameter specifies the service response for the I/O. |
2523 | * @status_ptr: This parameter specifies the exec status for the I/O. | 2518 | * @status_ptr: This parameter specifies the exec status for the I/O. |
2524 | * @complete_to_host_ptr: This parameter specifies the action to be taken by | ||
2525 | * the LLDD with respect to completing this request or forcing an abort | ||
2526 | * condition on the I/O. | ||
2527 | * | 2519 | * |
2528 | * none. | 2520 | * none. |
2529 | */ | 2521 | */ |
@@ -2532,8 +2524,7 @@ static void isci_request_handle_controller_specific_errors( | |||
2532 | struct isci_request *request, | 2524 | struct isci_request *request, |
2533 | struct sas_task *task, | 2525 | struct sas_task *task, |
2534 | enum service_response *response_ptr, | 2526 | enum service_response *response_ptr, |
2535 | enum exec_status *status_ptr, | 2527 | enum exec_status *status_ptr) |
2536 | enum isci_completion_selection *complete_to_host_ptr) | ||
2537 | { | 2528 | { |
2538 | unsigned int cstatus; | 2529 | unsigned int cstatus; |
2539 | 2530 | ||
@@ -2574,9 +2565,6 @@ static void isci_request_handle_controller_specific_errors( | |||
2574 | *status_ptr = SAS_ABORTED_TASK; | 2565 | *status_ptr = SAS_ABORTED_TASK; |
2575 | 2566 | ||
2576 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2567 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2577 | |||
2578 | *complete_to_host_ptr = | ||
2579 | isci_perform_normal_io_completion; | ||
2580 | } else { | 2568 | } else { |
2581 | /* Task in the target is not done. */ | 2569 | /* Task in the target is not done. */ |
2582 | *response_ptr = SAS_TASK_UNDELIVERED; | 2570 | *response_ptr = SAS_TASK_UNDELIVERED; |
@@ -2587,9 +2575,6 @@ static void isci_request_handle_controller_specific_errors( | |||
2587 | *status_ptr = SAM_STAT_TASK_ABORTED; | 2575 | *status_ptr = SAM_STAT_TASK_ABORTED; |
2588 | 2576 | ||
2589 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2577 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2590 | |||
2591 | *complete_to_host_ptr = | ||
2592 | isci_perform_error_io_completion; | ||
2593 | } | 2578 | } |
2594 | 2579 | ||
2595 | break; | 2580 | break; |
@@ -2618,8 +2603,6 @@ static void isci_request_handle_controller_specific_errors( | |||
2618 | *status_ptr = SAS_ABORTED_TASK; | 2603 | *status_ptr = SAS_ABORTED_TASK; |
2619 | 2604 | ||
2620 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2605 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2621 | |||
2622 | *complete_to_host_ptr = isci_perform_normal_io_completion; | ||
2623 | break; | 2606 | break; |
2624 | 2607 | ||
2625 | 2608 | ||
@@ -2630,7 +2613,7 @@ static void isci_request_handle_controller_specific_errors( | |||
2630 | 2613 | ||
2631 | isci_request_set_open_reject_status( | 2614 | isci_request_set_open_reject_status( |
2632 | request, task, response_ptr, status_ptr, | 2615 | request, task, response_ptr, status_ptr, |
2633 | complete_to_host_ptr, SAS_OREJ_WRONG_DEST); | 2616 | SAS_OREJ_WRONG_DEST); |
2634 | break; | 2617 | break; |
2635 | 2618 | ||
2636 | case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION: | 2619 | case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION: |
@@ -2640,56 +2623,56 @@ static void isci_request_handle_controller_specific_errors( | |||
2640 | */ | 2623 | */ |
2641 | isci_request_set_open_reject_status( | 2624 | isci_request_set_open_reject_status( |
2642 | request, task, response_ptr, status_ptr, | 2625 | request, task, response_ptr, status_ptr, |
2643 | complete_to_host_ptr, SAS_OREJ_RESV_AB0); | 2626 | SAS_OREJ_RESV_AB0); |
2644 | break; | 2627 | break; |
2645 | 2628 | ||
2646 | case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1: | 2629 | case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1: |
2647 | 2630 | ||
2648 | isci_request_set_open_reject_status( | 2631 | isci_request_set_open_reject_status( |
2649 | request, task, response_ptr, status_ptr, | 2632 | request, task, response_ptr, status_ptr, |
2650 | complete_to_host_ptr, SAS_OREJ_RESV_AB1); | 2633 | SAS_OREJ_RESV_AB1); |
2651 | break; | 2634 | break; |
2652 | 2635 | ||
2653 | case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2: | 2636 | case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2: |
2654 | 2637 | ||
2655 | isci_request_set_open_reject_status( | 2638 | isci_request_set_open_reject_status( |
2656 | request, task, response_ptr, status_ptr, | 2639 | request, task, response_ptr, status_ptr, |
2657 | complete_to_host_ptr, SAS_OREJ_RESV_AB2); | 2640 | SAS_OREJ_RESV_AB2); |
2658 | break; | 2641 | break; |
2659 | 2642 | ||
2660 | case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3: | 2643 | case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3: |
2661 | 2644 | ||
2662 | isci_request_set_open_reject_status( | 2645 | isci_request_set_open_reject_status( |
2663 | request, task, response_ptr, status_ptr, | 2646 | request, task, response_ptr, status_ptr, |
2664 | complete_to_host_ptr, SAS_OREJ_RESV_AB3); | 2647 | SAS_OREJ_RESV_AB3); |
2665 | break; | 2648 | break; |
2666 | 2649 | ||
2667 | case SCU_TASK_OPEN_REJECT_BAD_DESTINATION: | 2650 | case SCU_TASK_OPEN_REJECT_BAD_DESTINATION: |
2668 | 2651 | ||
2669 | isci_request_set_open_reject_status( | 2652 | isci_request_set_open_reject_status( |
2670 | request, task, response_ptr, status_ptr, | 2653 | request, task, response_ptr, status_ptr, |
2671 | complete_to_host_ptr, SAS_OREJ_BAD_DEST); | 2654 | SAS_OREJ_BAD_DEST); |
2672 | break; | 2655 | break; |
2673 | 2656 | ||
2674 | case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY: | 2657 | case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY: |
2675 | 2658 | ||
2676 | isci_request_set_open_reject_status( | 2659 | isci_request_set_open_reject_status( |
2677 | request, task, response_ptr, status_ptr, | 2660 | request, task, response_ptr, status_ptr, |
2678 | complete_to_host_ptr, SAS_OREJ_STP_NORES); | 2661 | SAS_OREJ_STP_NORES); |
2679 | break; | 2662 | break; |
2680 | 2663 | ||
2681 | case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED: | 2664 | case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED: |
2682 | 2665 | ||
2683 | isci_request_set_open_reject_status( | 2666 | isci_request_set_open_reject_status( |
2684 | request, task, response_ptr, status_ptr, | 2667 | request, task, response_ptr, status_ptr, |
2685 | complete_to_host_ptr, SAS_OREJ_EPROTO); | 2668 | SAS_OREJ_EPROTO); |
2686 | break; | 2669 | break; |
2687 | 2670 | ||
2688 | case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED: | 2671 | case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED: |
2689 | 2672 | ||
2690 | isci_request_set_open_reject_status( | 2673 | isci_request_set_open_reject_status( |
2691 | request, task, response_ptr, status_ptr, | 2674 | request, task, response_ptr, status_ptr, |
2692 | complete_to_host_ptr, SAS_OREJ_CONN_RATE); | 2675 | SAS_OREJ_CONN_RATE); |
2693 | break; | 2676 | break; |
2694 | 2677 | ||
2695 | case SCU_TASK_DONE_LL_R_ERR: | 2678 | case SCU_TASK_DONE_LL_R_ERR: |
@@ -2721,95 +2704,12 @@ static void isci_request_handle_controller_specific_errors( | |||
2721 | *response_ptr = SAS_TASK_UNDELIVERED; | 2704 | *response_ptr = SAS_TASK_UNDELIVERED; |
2722 | *status_ptr = SAM_STAT_TASK_ABORTED; | 2705 | *status_ptr = SAM_STAT_TASK_ABORTED; |
2723 | 2706 | ||
2724 | if (task->task_proto == SAS_PROTOCOL_SMP) { | 2707 | if (task->task_proto == SAS_PROTOCOL_SMP) |
2725 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2708 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2726 | 2709 | else | |
2727 | *complete_to_host_ptr = isci_perform_normal_io_completion; | ||
2728 | } else { | ||
2729 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2710 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2730 | |||
2731 | *complete_to_host_ptr = isci_perform_error_io_completion; | ||
2732 | } | ||
2733 | break; | ||
2734 | } | ||
2735 | } | ||
2736 | |||
2737 | /** | ||
2738 | * isci_task_save_for_upper_layer_completion() - This function saves the | ||
2739 | * request for later completion to the upper layer driver. | ||
2740 | * @host: This parameter is a pointer to the host on which the the request | ||
2741 | * should be queued (either as an error or success). | ||
2742 | * @request: This parameter is the completed request. | ||
2743 | * @response: This parameter is the response code for the completed task. | ||
2744 | * @status: This parameter is the status code for the completed task. | ||
2745 | * | ||
2746 | * none. | ||
2747 | */ | ||
2748 | static void isci_task_save_for_upper_layer_completion( | ||
2749 | struct isci_host *host, | ||
2750 | struct isci_request *request, | ||
2751 | enum service_response response, | ||
2752 | enum exec_status status, | ||
2753 | enum isci_completion_selection task_notification_selection) | ||
2754 | { | ||
2755 | struct sas_task *task = isci_request_access_task(request); | ||
2756 | |||
2757 | task_notification_selection | ||
2758 | = isci_task_set_completion_status(task, response, status, | ||
2759 | task_notification_selection); | ||
2760 | |||
2761 | /* Tasks aborted specifically by a call to the lldd_abort_task | ||
2762 | * function should not be completed to the host in the regular path. | ||
2763 | */ | ||
2764 | switch (task_notification_selection) { | ||
2765 | |||
2766 | case isci_perform_normal_io_completion: | ||
2767 | /* Normal notification (task_done) */ | ||
2768 | |||
2769 | /* Add to the completed list. */ | ||
2770 | list_add(&request->completed_node, | ||
2771 | &host->requests_to_complete); | ||
2772 | |||
2773 | /* Take the request off the device's pending request list. */ | ||
2774 | list_del_init(&request->dev_node); | ||
2775 | break; | ||
2776 | |||
2777 | case isci_perform_aborted_io_completion: | ||
2778 | /* No notification to libsas because this request is | ||
2779 | * already in the abort path. | ||
2780 | */ | ||
2781 | /* Wake up whatever process was waiting for this | ||
2782 | * request to complete. | ||
2783 | */ | ||
2784 | WARN_ON(request->io_request_completion == NULL); | ||
2785 | |||
2786 | if (request->io_request_completion != NULL) { | ||
2787 | |||
2788 | /* Signal whoever is waiting that this | ||
2789 | * request is complete. | ||
2790 | */ | ||
2791 | complete(request->io_request_completion); | ||
2792 | } | ||
2793 | break; | ||
2794 | |||
2795 | case isci_perform_error_io_completion: | ||
2796 | /* Use sas_task_abort */ | ||
2797 | /* Add to the aborted list. */ | ||
2798 | list_add(&request->completed_node, | ||
2799 | &host->requests_to_errorback); | ||
2800 | break; | ||
2801 | |||
2802 | default: | ||
2803 | /* Add to the error to libsas list. */ | ||
2804 | list_add(&request->completed_node, | ||
2805 | &host->requests_to_errorback); | ||
2806 | break; | 2711 | break; |
2807 | } | 2712 | } |
2808 | dev_dbg(&host->pdev->dev, | ||
2809 | "%s: %d - task = %p, response=%d (%d), status=%d (%d)\n", | ||
2810 | __func__, task_notification_selection, task, | ||
2811 | (task) ? task->task_status.resp : 0, response, | ||
2812 | (task) ? task->task_status.stat : 0, status); | ||
2813 | } | 2713 | } |
2814 | 2714 | ||
2815 | static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) | 2715 | static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) |
@@ -2844,9 +2744,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2844 | struct isci_remote_device *idev = request->target_device; | 2744 | struct isci_remote_device *idev = request->target_device; |
2845 | enum service_response response = SAS_TASK_UNDELIVERED; | 2745 | enum service_response response = SAS_TASK_UNDELIVERED; |
2846 | enum exec_status status = SAS_ABORTED_TASK; | 2746 | enum exec_status status = SAS_ABORTED_TASK; |
2847 | enum isci_request_status request_status; | ||
2848 | enum isci_completion_selection complete_to_host | ||
2849 | = isci_perform_normal_io_completion; | ||
2850 | 2747 | ||
2851 | dev_dbg(&ihost->pdev->dev, | 2748 | dev_dbg(&ihost->pdev->dev, |
2852 | "%s: request = %p, task = %p,\n" | 2749 | "%s: request = %p, task = %p,\n" |
@@ -2857,282 +2754,158 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2857 | task->data_dir, | 2754 | task->data_dir, |
2858 | completion_status); | 2755 | completion_status); |
2859 | 2756 | ||
2860 | spin_lock(&request->state_lock); | 2757 | /* The request is done from an SCU HW perspective. */ |
2861 | request_status = request->status; | ||
2862 | |||
2863 | /* Decode the request status. Note that if the request has been | ||
2864 | * aborted by a task management function, we don't care | ||
2865 | * what the status is. | ||
2866 | */ | ||
2867 | switch (request_status) { | ||
2868 | |||
2869 | case aborted: | ||
2870 | /* "aborted" indicates that the request was aborted by a task | ||
2871 | * management function, since once a task management request is | ||
2872 | * perfomed by the device, the request only completes because | ||
2873 | * of the subsequent driver terminate. | ||
2874 | * | ||
2875 | * Aborted also means an external thread is explicitly managing | ||
2876 | * this request, so that we do not complete it up the stack. | ||
2877 | * | ||
2878 | * The target is still there (since the TMF was successful). | ||
2879 | */ | ||
2880 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
2881 | response = SAS_TASK_COMPLETE; | ||
2882 | 2758 | ||
2883 | /* See if the device has been/is being stopped. Note | 2759 | /* This is an active request being completed from the core. */ |
2884 | * that we ignore the quiesce state, since we are | 2760 | switch (completion_status) { |
2885 | * concerned about the actual device state. | ||
2886 | */ | ||
2887 | if (!idev) | ||
2888 | status = SAS_DEVICE_UNKNOWN; | ||
2889 | else | ||
2890 | status = SAS_ABORTED_TASK; | ||
2891 | 2761 | ||
2892 | complete_to_host = isci_perform_aborted_io_completion; | 2762 | case SCI_IO_FAILURE_RESPONSE_VALID: |
2893 | /* This was an aborted request. */ | 2763 | dev_dbg(&ihost->pdev->dev, |
2764 | "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n", | ||
2765 | __func__, request, task); | ||
2894 | 2766 | ||
2895 | spin_unlock(&request->state_lock); | 2767 | if (sas_protocol_ata(task->task_proto)) { |
2896 | break; | 2768 | isci_process_stp_response(task, &request->stp.rsp); |
2769 | } else if (SAS_PROTOCOL_SSP == task->task_proto) { | ||
2897 | 2770 | ||
2898 | case aborting: | 2771 | /* crack the iu response buffer. */ |
2899 | /* aborting means that the task management function tried and | 2772 | resp_iu = &request->ssp.rsp; |
2900 | * failed to abort the request. We need to note the request | 2773 | isci_request_process_response_iu(task, resp_iu, |
2901 | * as SAS_TASK_UNDELIVERED, so that the scsi mid layer marks the | 2774 | &ihost->pdev->dev); |
2902 | * target as down. | ||
2903 | * | ||
2904 | * Aborting also means an external thread is explicitly managing | ||
2905 | * this request, so that we do not complete it up the stack. | ||
2906 | */ | ||
2907 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
2908 | response = SAS_TASK_UNDELIVERED; | ||
2909 | 2775 | ||
2910 | if (!idev) | 2776 | } else if (SAS_PROTOCOL_SMP == task->task_proto) { |
2911 | /* The device has been /is being stopped. Note that | ||
2912 | * we ignore the quiesce state, since we are | ||
2913 | * concerned about the actual device state. | ||
2914 | */ | ||
2915 | status = SAS_DEVICE_UNKNOWN; | ||
2916 | else | ||
2917 | status = SAS_PHY_DOWN; | ||
2918 | 2777 | ||
2919 | complete_to_host = isci_perform_aborted_io_completion; | 2778 | dev_err(&ihost->pdev->dev, |
2779 | "%s: SCI_IO_FAILURE_RESPONSE_VALID: " | ||
2780 | "SAS_PROTOCOL_SMP protocol\n", | ||
2781 | __func__); | ||
2920 | 2782 | ||
2921 | /* This was an aborted request. */ | 2783 | } else |
2784 | dev_err(&ihost->pdev->dev, | ||
2785 | "%s: unknown protocol\n", __func__); | ||
2922 | 2786 | ||
2923 | spin_unlock(&request->state_lock); | 2787 | /* use the task status set in the task struct by the |
2788 | * isci_request_process_response_iu call. | ||
2789 | */ | ||
2790 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
2791 | response = task->task_status.resp; | ||
2792 | status = task->task_status.stat; | ||
2924 | break; | 2793 | break; |
2925 | 2794 | ||
2926 | case terminating: | 2795 | case SCI_IO_SUCCESS: |
2796 | case SCI_IO_SUCCESS_IO_DONE_EARLY: | ||
2927 | 2797 | ||
2928 | /* This was an terminated request. This happens when | 2798 | response = SAS_TASK_COMPLETE; |
2929 | * the I/O is being terminated because of an action on | 2799 | status = SAM_STAT_GOOD; |
2930 | * the device (reset, tear down, etc.), and the I/O needs | ||
2931 | * to be completed up the stack. | ||
2932 | */ | ||
2933 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2800 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2934 | response = SAS_TASK_UNDELIVERED; | ||
2935 | 2801 | ||
2936 | /* See if the device has been/is being stopped. Note | 2802 | if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { |
2937 | * that we ignore the quiesce state, since we are | ||
2938 | * concerned about the actual device state. | ||
2939 | */ | ||
2940 | if (!idev) | ||
2941 | status = SAS_DEVICE_UNKNOWN; | ||
2942 | else | ||
2943 | status = SAS_ABORTED_TASK; | ||
2944 | |||
2945 | complete_to_host = isci_perform_aborted_io_completion; | ||
2946 | |||
2947 | /* This was a terminated request. */ | ||
2948 | |||
2949 | spin_unlock(&request->state_lock); | ||
2950 | break; | ||
2951 | 2803 | ||
2952 | case dead: | 2804 | /* This was an SSP / STP / SATA transfer. |
2953 | /* This was a terminated request that timed-out during the | 2805 | * There is a possibility that less data than |
2954 | * termination process. There is no task to complete to | 2806 | * the maximum was transferred. |
2955 | * libsas. | 2807 | */ |
2956 | */ | 2808 | u32 transferred_length = sci_req_tx_bytes(request); |
2957 | complete_to_host = isci_perform_normal_io_completion; | ||
2958 | spin_unlock(&request->state_lock); | ||
2959 | break; | ||
2960 | |||
2961 | default: | ||
2962 | |||
2963 | /* The request is done from an SCU HW perspective. */ | ||
2964 | request->status = completed; | ||
2965 | 2809 | ||
2966 | spin_unlock(&request->state_lock); | 2810 | task->task_status.residual |
2811 | = task->total_xfer_len - transferred_length; | ||
2967 | 2812 | ||
2968 | /* This is an active request being completed from the core. */ | 2813 | /* If there were residual bytes, call this an |
2969 | switch (completion_status) { | 2814 | * underrun. |
2815 | */ | ||
2816 | if (task->task_status.residual != 0) | ||
2817 | status = SAS_DATA_UNDERRUN; | ||
2970 | 2818 | ||
2971 | case SCI_IO_FAILURE_RESPONSE_VALID: | ||
2972 | dev_dbg(&ihost->pdev->dev, | 2819 | dev_dbg(&ihost->pdev->dev, |
2973 | "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n", | 2820 | "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n", |
2974 | __func__, | 2821 | __func__, status); |
2975 | request, | ||
2976 | task); | ||
2977 | |||
2978 | if (sas_protocol_ata(task->task_proto)) { | ||
2979 | isci_process_stp_response(task, &request->stp.rsp); | ||
2980 | } else if (SAS_PROTOCOL_SSP == task->task_proto) { | ||
2981 | |||
2982 | /* crack the iu response buffer. */ | ||
2983 | resp_iu = &request->ssp.rsp; | ||
2984 | isci_request_process_response_iu(task, resp_iu, | ||
2985 | &ihost->pdev->dev); | ||
2986 | |||
2987 | } else if (SAS_PROTOCOL_SMP == task->task_proto) { | ||
2988 | 2822 | ||
2989 | dev_err(&ihost->pdev->dev, | 2823 | } else |
2990 | "%s: SCI_IO_FAILURE_RESPONSE_VALID: " | 2824 | dev_dbg(&ihost->pdev->dev, "%s: SCI_IO_SUCCESS\n", |
2991 | "SAS_PROTOCOL_SMP protocol\n", | 2825 | __func__); |
2992 | __func__); | 2826 | break; |
2993 | |||
2994 | } else | ||
2995 | dev_err(&ihost->pdev->dev, | ||
2996 | "%s: unknown protocol\n", __func__); | ||
2997 | |||
2998 | /* use the task status set in the task struct by the | ||
2999 | * isci_request_process_response_iu call. | ||
3000 | */ | ||
3001 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
3002 | response = task->task_status.resp; | ||
3003 | status = task->task_status.stat; | ||
3004 | break; | ||
3005 | |||
3006 | case SCI_IO_SUCCESS: | ||
3007 | case SCI_IO_SUCCESS_IO_DONE_EARLY: | ||
3008 | |||
3009 | response = SAS_TASK_COMPLETE; | ||
3010 | status = SAM_STAT_GOOD; | ||
3011 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
3012 | |||
3013 | if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { | ||
3014 | |||
3015 | /* This was an SSP / STP / SATA transfer. | ||
3016 | * There is a possibility that less data than | ||
3017 | * the maximum was transferred. | ||
3018 | */ | ||
3019 | u32 transferred_length = sci_req_tx_bytes(request); | ||
3020 | |||
3021 | task->task_status.residual | ||
3022 | = task->total_xfer_len - transferred_length; | ||
3023 | 2827 | ||
3024 | /* If there were residual bytes, call this an | 2828 | case SCI_IO_FAILURE_TERMINATED: |
3025 | * underrun. | ||
3026 | */ | ||
3027 | if (task->task_status.residual != 0) | ||
3028 | status = SAS_DATA_UNDERRUN; | ||
3029 | 2829 | ||
3030 | dev_dbg(&ihost->pdev->dev, | 2830 | dev_dbg(&ihost->pdev->dev, |
3031 | "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n", | 2831 | "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n", |
3032 | __func__, | 2832 | __func__, request, task); |
3033 | status); | ||
3034 | 2833 | ||
3035 | } else | 2834 | /* The request was terminated explicitly. */ |
3036 | dev_dbg(&ihost->pdev->dev, | 2835 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
3037 | "%s: SCI_IO_SUCCESS\n", | 2836 | response = SAS_TASK_UNDELIVERED; |
3038 | __func__); | ||
3039 | 2837 | ||
3040 | break; | 2838 | /* See if the device has been/is being stopped. Note |
2839 | * that we ignore the quiesce state, since we are | ||
2840 | * concerned about the actual device state. | ||
2841 | */ | ||
2842 | if (!idev) | ||
2843 | status = SAS_DEVICE_UNKNOWN; | ||
2844 | else | ||
2845 | status = SAS_ABORTED_TASK; | ||
2846 | break; | ||
3041 | 2847 | ||
3042 | case SCI_IO_FAILURE_TERMINATED: | 2848 | case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR: |
3043 | dev_dbg(&ihost->pdev->dev, | ||
3044 | "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n", | ||
3045 | __func__, | ||
3046 | request, | ||
3047 | task); | ||
3048 | 2849 | ||
3049 | /* The request was terminated explicitly. No handling | 2850 | isci_request_handle_controller_specific_errors(idev, request, |
3050 | * is needed in the SCSI error handler path. | 2851 | task, &response, |
3051 | */ | 2852 | &status); |
3052 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2853 | break; |
3053 | response = SAS_TASK_UNDELIVERED; | ||
3054 | 2854 | ||
3055 | /* See if the device has been/is being stopped. Note | 2855 | case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED: |
3056 | * that we ignore the quiesce state, since we are | 2856 | /* This is a special case, in that the I/O completion |
3057 | * concerned about the actual device state. | 2857 | * is telling us that the device needs a reset. |
3058 | */ | 2858 | * In order for the device reset condition to be |
3059 | if (!idev) | 2859 | * noticed, the I/O has to be handled in the error |
3060 | status = SAS_DEVICE_UNKNOWN; | 2860 | * handler. Set the reset flag and cause the |
3061 | else | 2861 | * SCSI error thread to be scheduled. |
3062 | status = SAS_ABORTED_TASK; | 2862 | */ |
2863 | spin_lock_irqsave(&task->task_state_lock, task_flags); | ||
2864 | task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; | ||
2865 | spin_unlock_irqrestore(&task->task_state_lock, task_flags); | ||
3063 | 2866 | ||
3064 | complete_to_host = isci_perform_normal_io_completion; | 2867 | /* Fail the I/O. */ |
3065 | break; | 2868 | response = SAS_TASK_UNDELIVERED; |
2869 | status = SAM_STAT_TASK_ABORTED; | ||
3066 | 2870 | ||
3067 | case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR: | 2871 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2872 | break; | ||
3068 | 2873 | ||
3069 | isci_request_handle_controller_specific_errors( | 2874 | case SCI_FAILURE_RETRY_REQUIRED: |
3070 | idev, request, task, &response, &status, | ||
3071 | &complete_to_host); | ||
3072 | 2875 | ||
3073 | break; | 2876 | /* Fail the I/O so it can be retried. */ |
2877 | response = SAS_TASK_UNDELIVERED; | ||
2878 | if (!idev) | ||
2879 | status = SAS_DEVICE_UNKNOWN; | ||
2880 | else | ||
2881 | status = SAS_ABORTED_TASK; | ||
3074 | 2882 | ||
3075 | case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED: | 2883 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
3076 | /* This is a special case, in that the I/O completion | 2884 | break; |
3077 | * is telling us that the device needs a reset. | ||
3078 | * In order for the device reset condition to be | ||
3079 | * noticed, the I/O has to be handled in the error | ||
3080 | * handler. Set the reset flag and cause the | ||
3081 | * SCSI error thread to be scheduled. | ||
3082 | */ | ||
3083 | spin_lock_irqsave(&task->task_state_lock, task_flags); | ||
3084 | task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; | ||
3085 | spin_unlock_irqrestore(&task->task_state_lock, task_flags); | ||
3086 | 2885 | ||
3087 | /* Fail the I/O. */ | ||
3088 | response = SAS_TASK_UNDELIVERED; | ||
3089 | status = SAM_STAT_TASK_ABORTED; | ||
3090 | 2886 | ||
3091 | complete_to_host = isci_perform_error_io_completion; | 2887 | default: |
3092 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2888 | /* Catch any otherwise unhandled error codes here. */ |
3093 | break; | 2889 | dev_dbg(&ihost->pdev->dev, |
2890 | "%s: invalid completion code: 0x%x - " | ||
2891 | "isci_request = %p\n", | ||
2892 | __func__, completion_status, request); | ||
3094 | 2893 | ||
3095 | case SCI_FAILURE_RETRY_REQUIRED: | 2894 | response = SAS_TASK_UNDELIVERED; |
3096 | 2895 | ||
3097 | /* Fail the I/O so it can be retried. */ | 2896 | /* See if the device has been/is being stopped. Note |
3098 | response = SAS_TASK_UNDELIVERED; | 2897 | * that we ignore the quiesce state, since we are |
3099 | if (!idev) | 2898 | * concerned about the actual device state. |
3100 | status = SAS_DEVICE_UNKNOWN; | 2899 | */ |
3101 | else | 2900 | if (!idev) |
3102 | status = SAS_ABORTED_TASK; | 2901 | status = SAS_DEVICE_UNKNOWN; |
2902 | else | ||
2903 | status = SAS_ABORTED_TASK; | ||
3103 | 2904 | ||
3104 | complete_to_host = isci_perform_normal_io_completion; | 2905 | if (SAS_PROTOCOL_SMP == task->task_proto) |
3105 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2906 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
3106 | break; | 2907 | else |
3107 | 2908 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | |
3108 | |||
3109 | default: | ||
3110 | /* Catch any otherwise unhandled error codes here. */ | ||
3111 | dev_dbg(&ihost->pdev->dev, | ||
3112 | "%s: invalid completion code: 0x%x - " | ||
3113 | "isci_request = %p\n", | ||
3114 | __func__, completion_status, request); | ||
3115 | |||
3116 | response = SAS_TASK_UNDELIVERED; | ||
3117 | |||
3118 | /* See if the device has been/is being stopped. Note | ||
3119 | * that we ignore the quiesce state, since we are | ||
3120 | * concerned about the actual device state. | ||
3121 | */ | ||
3122 | if (!idev) | ||
3123 | status = SAS_DEVICE_UNKNOWN; | ||
3124 | else | ||
3125 | status = SAS_ABORTED_TASK; | ||
3126 | |||
3127 | if (SAS_PROTOCOL_SMP == task->task_proto) { | ||
3128 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
3129 | complete_to_host = isci_perform_normal_io_completion; | ||
3130 | } else { | ||
3131 | clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | ||
3132 | complete_to_host = isci_perform_error_io_completion; | ||
3133 | } | ||
3134 | break; | ||
3135 | } | ||
3136 | break; | 2909 | break; |
3137 | } | 2910 | } |
3138 | 2911 | ||
@@ -3167,10 +2940,24 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
3167 | break; | 2940 | break; |
3168 | } | 2941 | } |
3169 | 2942 | ||
3170 | /* Put the completed request on the correct list */ | 2943 | spin_lock_irqsave(&task->task_state_lock, task_flags); |
3171 | isci_task_save_for_upper_layer_completion(ihost, request, response, | 2944 | |
3172 | status, complete_to_host | 2945 | task->task_status.resp = response; |
3173 | ); | 2946 | task->task_status.stat = status; |
2947 | |||
2948 | if (test_bit(IREQ_COMPLETE_IN_TARGET, &request->flags)) { | ||
2949 | /* Normal notification (task_done) */ | ||
2950 | task->task_state_flags |= SAS_TASK_STATE_DONE; | ||
2951 | task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | | ||
2952 | SAS_TASK_STATE_PENDING); | ||
2953 | } | ||
2954 | spin_unlock_irqrestore(&task->task_state_lock, task_flags); | ||
2955 | |||
2956 | /* Add to the completed list. */ | ||
2957 | list_add(&request->completed_node, &ihost->requests_to_complete); | ||
2958 | |||
2959 | /* Take the request off the device's pending request list. */ | ||
2960 | list_del_init(&request->dev_node); | ||
3174 | 2961 | ||
3175 | /* complete the io request to the core. */ | 2962 | /* complete the io request to the core. */ |
3176 | sci_controller_complete_io(ihost, request->target_device, request); | 2963 | sci_controller_complete_io(ihost, request->target_device, request); |
@@ -3626,7 +3413,6 @@ static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 t | |||
3626 | ireq->num_sg_entries = 0; | 3413 | ireq->num_sg_entries = 0; |
3627 | INIT_LIST_HEAD(&ireq->completed_node); | 3414 | INIT_LIST_HEAD(&ireq->completed_node); |
3628 | INIT_LIST_HEAD(&ireq->dev_node); | 3415 | INIT_LIST_HEAD(&ireq->dev_node); |
3629 | isci_request_change_state(ireq, allocated); | ||
3630 | 3416 | ||
3631 | return ireq; | 3417 | return ireq; |
3632 | } | 3418 | } |
@@ -3721,15 +3507,12 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide | |||
3721 | */ | 3507 | */ |
3722 | list_add(&ireq->dev_node, &idev->reqs_in_process); | 3508 | list_add(&ireq->dev_node, &idev->reqs_in_process); |
3723 | 3509 | ||
3724 | if (status == SCI_SUCCESS) { | 3510 | if (status != SCI_SUCCESS) { |
3725 | isci_request_change_state(ireq, started); | ||
3726 | } else { | ||
3727 | /* The request did not really start in the | 3511 | /* The request did not really start in the |
3728 | * hardware, so clear the request handle | 3512 | * hardware, so clear the request handle |
3729 | * here so no terminations will be done. | 3513 | * here so no terminations will be done. |
3730 | */ | 3514 | */ |
3731 | set_bit(IREQ_TERMINATED, &ireq->flags); | 3515 | set_bit(IREQ_TERMINATED, &ireq->flags); |
3732 | isci_request_change_state(ireq, completed); | ||
3733 | } | 3516 | } |
3734 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 3517 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
3735 | 3518 | ||