diff options
Diffstat (limited to 'drivers/scsi/isci/host.c')
-rw-r--r-- | drivers/scsi/isci/host.c | 265 |
1 files changed, 64 insertions, 201 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index b08455f0d350..c99fab53dd0c 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -1018,33 +1018,11 @@ done: | |||
1018 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 1018 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | static void isci_tci_free(struct isci_host *ihost, u16 tci) | ||
1022 | { | ||
1023 | u16 tail = ihost->tci_tail & (SCI_MAX_IO_REQUESTS-1); | ||
1024 | |||
1025 | ihost->tci_pool[tail] = tci; | ||
1026 | ihost->tci_tail = tail + 1; | ||
1027 | } | ||
1028 | |||
1029 | static u16 isci_tci_alloc(struct isci_host *ihost) | ||
1030 | { | ||
1031 | u16 head = ihost->tci_head & (SCI_MAX_IO_REQUESTS-1); | ||
1032 | u16 tci = ihost->tci_pool[head]; | ||
1033 | |||
1034 | ihost->tci_head = head + 1; | ||
1035 | return tci; | ||
1036 | } | ||
1037 | |||
1038 | static u16 isci_tci_active(struct isci_host *ihost) | 1021 | static u16 isci_tci_active(struct isci_host *ihost) |
1039 | { | 1022 | { |
1040 | return CIRC_CNT(ihost->tci_head, ihost->tci_tail, SCI_MAX_IO_REQUESTS); | 1023 | return CIRC_CNT(ihost->tci_head, ihost->tci_tail, SCI_MAX_IO_REQUESTS); |
1041 | } | 1024 | } |
1042 | 1025 | ||
1043 | static u16 isci_tci_space(struct isci_host *ihost) | ||
1044 | { | ||
1045 | return CIRC_SPACE(ihost->tci_head, ihost->tci_tail, SCI_MAX_IO_REQUESTS); | ||
1046 | } | ||
1047 | |||
1048 | static enum sci_status scic_controller_start(struct scic_sds_controller *scic, | 1026 | static enum sci_status scic_controller_start(struct scic_sds_controller *scic, |
1049 | u32 timeout) | 1027 | u32 timeout) |
1050 | { | 1028 | { |
@@ -1205,6 +1183,11 @@ static void isci_host_completion_routine(unsigned long data) | |||
1205 | task->task_done(task); | 1183 | task->task_done(task); |
1206 | } | 1184 | } |
1207 | } | 1185 | } |
1186 | |||
1187 | spin_lock_irq(&isci_host->scic_lock); | ||
1188 | isci_free_tag(isci_host, request->sci.io_tag); | ||
1189 | spin_unlock_irq(&isci_host->scic_lock); | ||
1190 | |||
1208 | /* Free the request object. */ | 1191 | /* Free the request object. */ |
1209 | isci_request_free(isci_host, request); | 1192 | isci_request_free(isci_host, request); |
1210 | } | 1193 | } |
@@ -1242,6 +1225,7 @@ static void isci_host_completion_routine(unsigned long data) | |||
1242 | * of pending requests. | 1225 | * of pending requests. |
1243 | */ | 1226 | */ |
1244 | list_del_init(&request->dev_node); | 1227 | list_del_init(&request->dev_node); |
1228 | isci_free_tag(isci_host, request->sci.io_tag); | ||
1245 | spin_unlock_irq(&isci_host->scic_lock); | 1229 | spin_unlock_irq(&isci_host->scic_lock); |
1246 | 1230 | ||
1247 | /* Free the request object. */ | 1231 | /* Free the request object. */ |
@@ -2375,6 +2359,7 @@ static int scic_controller_mem_init(struct scic_sds_controller *scic) | |||
2375 | if (!scic->task_context_table) | 2359 | if (!scic->task_context_table) |
2376 | return -ENOMEM; | 2360 | return -ENOMEM; |
2377 | 2361 | ||
2362 | scic->task_context_dma = dma; | ||
2378 | writel(lower_32_bits(dma), &scic->smu_registers->host_task_table_lower); | 2363 | writel(lower_32_bits(dma), &scic->smu_registers->host_task_table_lower); |
2379 | writel(upper_32_bits(dma), &scic->smu_registers->host_task_table_upper); | 2364 | writel(upper_32_bits(dma), &scic->smu_registers->host_task_table_upper); |
2380 | 2365 | ||
@@ -2409,11 +2394,9 @@ int isci_host_init(struct isci_host *isci_host) | |||
2409 | 2394 | ||
2410 | spin_lock_init(&isci_host->state_lock); | 2395 | spin_lock_init(&isci_host->state_lock); |
2411 | spin_lock_init(&isci_host->scic_lock); | 2396 | spin_lock_init(&isci_host->scic_lock); |
2412 | spin_lock_init(&isci_host->queue_lock); | ||
2413 | init_waitqueue_head(&isci_host->eventq); | 2397 | init_waitqueue_head(&isci_host->eventq); |
2414 | 2398 | ||
2415 | isci_host_change_state(isci_host, isci_starting); | 2399 | isci_host_change_state(isci_host, isci_starting); |
2416 | isci_host->can_queue = ISCI_CAN_QUEUE_VAL; | ||
2417 | 2400 | ||
2418 | status = scic_controller_construct(&isci_host->sci, scu_base(isci_host), | 2401 | status = scic_controller_construct(&isci_host->sci, scu_base(isci_host), |
2419 | smu_base(isci_host)); | 2402 | smu_base(isci_host)); |
@@ -2611,51 +2594,6 @@ void scic_sds_controller_post_request( | |||
2611 | writel(request, &scic->smu_registers->post_context_port); | 2594 | writel(request, &scic->smu_registers->post_context_port); |
2612 | } | 2595 | } |
2613 | 2596 | ||
2614 | /** | ||
2615 | * This method will copy the soft copy of the task context into the physical | ||
2616 | * memory accessible by the controller. | ||
2617 | * @scic: This parameter specifies the controller for which to copy | ||
2618 | * the task context. | ||
2619 | * @sci_req: This parameter specifies the request for which the task | ||
2620 | * context is being copied. | ||
2621 | * | ||
2622 | * After this call is made the SCIC_SDS_IO_REQUEST object will always point to | ||
2623 | * the physical memory version of the task context. Thus, all subsequent | ||
2624 | * updates to the task context are performed in the TC table (i.e. DMAable | ||
2625 | * memory). none | ||
2626 | */ | ||
2627 | void scic_sds_controller_copy_task_context( | ||
2628 | struct scic_sds_controller *scic, | ||
2629 | struct scic_sds_request *sci_req) | ||
2630 | { | ||
2631 | struct scu_task_context *task_context_buffer; | ||
2632 | |||
2633 | task_context_buffer = scic_sds_controller_get_task_context_buffer( | ||
2634 | scic, sci_req->io_tag); | ||
2635 | |||
2636 | memcpy(task_context_buffer, | ||
2637 | sci_req->task_context_buffer, | ||
2638 | offsetof(struct scu_task_context, sgl_snapshot_ac)); | ||
2639 | |||
2640 | /* | ||
2641 | * Now that the soft copy of the TC has been copied into the TC | ||
2642 | * table accessible by the silicon. Thus, any further changes to | ||
2643 | * the TC (e.g. TC termination) occur in the appropriate location. */ | ||
2644 | sci_req->task_context_buffer = task_context_buffer; | ||
2645 | } | ||
2646 | |||
2647 | struct scu_task_context *scic_sds_controller_get_task_context_buffer(struct scic_sds_controller *scic, | ||
2648 | u16 io_tag) | ||
2649 | { | ||
2650 | u16 tci = ISCI_TAG_TCI(io_tag); | ||
2651 | |||
2652 | if (tci < scic->task_context_entries) { | ||
2653 | return &scic->task_context_table[tci]; | ||
2654 | } | ||
2655 | |||
2656 | return NULL; | ||
2657 | } | ||
2658 | |||
2659 | struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, u16 io_tag) | 2597 | struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, u16 io_tag) |
2660 | { | 2598 | { |
2661 | u16 task_index; | 2599 | u16 task_index; |
@@ -2801,6 +2739,60 @@ void scic_sds_controller_release_frame( | |||
2801 | &scic->scu_registers->sdma.unsolicited_frame_get_pointer); | 2739 | &scic->scu_registers->sdma.unsolicited_frame_get_pointer); |
2802 | } | 2740 | } |
2803 | 2741 | ||
2742 | void isci_tci_free(struct isci_host *ihost, u16 tci) | ||
2743 | { | ||
2744 | u16 tail = ihost->tci_tail & (SCI_MAX_IO_REQUESTS-1); | ||
2745 | |||
2746 | ihost->tci_pool[tail] = tci; | ||
2747 | ihost->tci_tail = tail + 1; | ||
2748 | } | ||
2749 | |||
2750 | static u16 isci_tci_alloc(struct isci_host *ihost) | ||
2751 | { | ||
2752 | u16 head = ihost->tci_head & (SCI_MAX_IO_REQUESTS-1); | ||
2753 | u16 tci = ihost->tci_pool[head]; | ||
2754 | |||
2755 | ihost->tci_head = head + 1; | ||
2756 | return tci; | ||
2757 | } | ||
2758 | |||
2759 | static u16 isci_tci_space(struct isci_host *ihost) | ||
2760 | { | ||
2761 | return CIRC_SPACE(ihost->tci_head, ihost->tci_tail, SCI_MAX_IO_REQUESTS); | ||
2762 | } | ||
2763 | |||
2764 | u16 isci_alloc_tag(struct isci_host *ihost) | ||
2765 | { | ||
2766 | if (isci_tci_space(ihost)) { | ||
2767 | u16 tci = isci_tci_alloc(ihost); | ||
2768 | u8 seq = ihost->sci.io_request_sequence[tci]; | ||
2769 | |||
2770 | return ISCI_TAG(seq, tci); | ||
2771 | } | ||
2772 | |||
2773 | return SCI_CONTROLLER_INVALID_IO_TAG; | ||
2774 | } | ||
2775 | |||
2776 | enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag) | ||
2777 | { | ||
2778 | struct scic_sds_controller *scic = &ihost->sci; | ||
2779 | u16 tci = ISCI_TAG_TCI(io_tag); | ||
2780 | u16 seq = ISCI_TAG_SEQ(io_tag); | ||
2781 | |||
2782 | /* prevent tail from passing head */ | ||
2783 | if (isci_tci_active(ihost) == 0) | ||
2784 | return SCI_FAILURE_INVALID_IO_TAG; | ||
2785 | |||
2786 | if (seq == scic->io_request_sequence[tci]) { | ||
2787 | scic->io_request_sequence[tci] = (seq+1) & (SCI_MAX_SEQ-1); | ||
2788 | |||
2789 | isci_tci_free(ihost, tci); | ||
2790 | |||
2791 | return SCI_SUCCESS; | ||
2792 | } | ||
2793 | return SCI_FAILURE_INVALID_IO_TAG; | ||
2794 | } | ||
2795 | |||
2804 | /** | 2796 | /** |
2805 | * scic_controller_start_io() - This method is called by the SCI user to | 2797 | * scic_controller_start_io() - This method is called by the SCI user to |
2806 | * send/start an IO request. If the method invocation is successful, then | 2798 | * send/start an IO request. If the method invocation is successful, then |
@@ -2811,27 +2803,11 @@ void scic_sds_controller_release_frame( | |||
2811 | * IO request. | 2803 | * IO request. |
2812 | * @io_request: the handle to the io request object to start. | 2804 | * @io_request: the handle to the io request object to start. |
2813 | * @io_tag: This parameter specifies a previously allocated IO tag that the | 2805 | * @io_tag: This parameter specifies a previously allocated IO tag that the |
2814 | * user desires to be utilized for this request. This parameter is optional. | 2806 | * user desires to be utilized for this request. |
2815 | * The user is allowed to supply SCI_CONTROLLER_INVALID_IO_TAG as the value | ||
2816 | * for this parameter. | ||
2817 | * | ||
2818 | * - IO tags are a protected resource. It is incumbent upon the SCI Core user | ||
2819 | * to ensure that each of the methods that may allocate or free available IO | ||
2820 | * tags are handled in a mutually exclusive manner. This method is one of said | ||
2821 | * methods requiring proper critical code section protection (e.g. semaphore, | ||
2822 | * spin-lock, etc.). - For SATA, the user is required to manage NCQ tags. As a | ||
2823 | * result, it is expected the user will have set the NCQ tag field in the host | ||
2824 | * to device register FIS prior to calling this method. There is also a | ||
2825 | * requirement for the user to call scic_stp_io_set_ncq_tag() prior to invoking | ||
2826 | * the scic_controller_start_io() method. scic_controller_allocate_tag() for | ||
2827 | * more information on allocating a tag. Indicate if the controller | ||
2828 | * successfully started the IO request. SCI_SUCCESS if the IO request was | ||
2829 | * successfully started. Determine the failure situations and return values. | ||
2830 | */ | 2807 | */ |
2831 | enum sci_status scic_controller_start_io(struct scic_sds_controller *scic, | 2808 | enum sci_status scic_controller_start_io(struct scic_sds_controller *scic, |
2832 | struct scic_sds_remote_device *rdev, | 2809 | struct scic_sds_remote_device *rdev, |
2833 | struct scic_sds_request *req, | 2810 | struct scic_sds_request *req) |
2834 | u16 io_tag) | ||
2835 | { | 2811 | { |
2836 | enum sci_status status; | 2812 | enum sci_status status; |
2837 | 2813 | ||
@@ -2902,17 +2878,6 @@ enum sci_status scic_controller_terminate_request( | |||
2902 | * @remote_device: The handle to the remote device object for which to complete | 2878 | * @remote_device: The handle to the remote device object for which to complete |
2903 | * the IO request. | 2879 | * the IO request. |
2904 | * @io_request: the handle to the io request object to complete. | 2880 | * @io_request: the handle to the io request object to complete. |
2905 | * | ||
2906 | * - IO tags are a protected resource. It is incumbent upon the SCI Core user | ||
2907 | * to ensure that each of the methods that may allocate or free available IO | ||
2908 | * tags are handled in a mutually exclusive manner. This method is one of said | ||
2909 | * methods requiring proper critical code section protection (e.g. semaphore, | ||
2910 | * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI | ||
2911 | * Core user, using the scic_controller_allocate_io_tag() method, then it is | ||
2912 | * the responsibility of the caller to invoke the scic_controller_free_io_tag() | ||
2913 | * method to free the tag (i.e. this method will not free the IO tag). Indicate | ||
2914 | * if the controller successfully completed the IO request. SCI_SUCCESS if the | ||
2915 | * completion process was successful. | ||
2916 | */ | 2881 | */ |
2917 | enum sci_status scic_controller_complete_io( | 2882 | enum sci_status scic_controller_complete_io( |
2918 | struct scic_sds_controller *scic, | 2883 | struct scic_sds_controller *scic, |
@@ -2963,31 +2928,11 @@ enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req) | |||
2963 | * @remote_device: the handle to the remote device object for which to start | 2928 | * @remote_device: the handle to the remote device object for which to start |
2964 | * the task management request. | 2929 | * the task management request. |
2965 | * @task_request: the handle to the task request object to start. | 2930 | * @task_request: the handle to the task request object to start. |
2966 | * @io_tag: This parameter specifies a previously allocated IO tag that the | ||
2967 | * user desires to be utilized for this request. Note this not the io_tag | ||
2968 | * of the request being managed. It is to be utilized for the task request | ||
2969 | * itself. This parameter is optional. The user is allowed to supply | ||
2970 | * SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter. | ||
2971 | * | ||
2972 | * - IO tags are a protected resource. It is incumbent upon the SCI Core user | ||
2973 | * to ensure that each of the methods that may allocate or free available IO | ||
2974 | * tags are handled in a mutually exclusive manner. This method is one of said | ||
2975 | * methods requiring proper critical code section protection (e.g. semaphore, | ||
2976 | * spin-lock, etc.). - The user must synchronize this task with completion | ||
2977 | * queue processing. If they are not synchronized then it is possible for the | ||
2978 | * io requests that are being managed by the task request can complete before | ||
2979 | * starting the task request. scic_controller_allocate_tag() for more | ||
2980 | * information on allocating a tag. Indicate if the controller successfully | ||
2981 | * started the IO request. SCI_TASK_SUCCESS if the task request was | ||
2982 | * successfully started. SCI_TASK_FAILURE_REQUIRES_SCSI_ABORT This value is | ||
2983 | * returned if there is/are task(s) outstanding that require termination or | ||
2984 | * completion before this request can succeed. | ||
2985 | */ | 2931 | */ |
2986 | enum sci_task_status scic_controller_start_task( | 2932 | enum sci_task_status scic_controller_start_task( |
2987 | struct scic_sds_controller *scic, | 2933 | struct scic_sds_controller *scic, |
2988 | struct scic_sds_remote_device *rdev, | 2934 | struct scic_sds_remote_device *rdev, |
2989 | struct scic_sds_request *req, | 2935 | struct scic_sds_request *req) |
2990 | u16 task_tag) | ||
2991 | { | 2936 | { |
2992 | enum sci_status status; | 2937 | enum sci_status status; |
2993 | 2938 | ||
@@ -3022,85 +2967,3 @@ enum sci_task_status scic_controller_start_task( | |||
3022 | 2967 | ||
3023 | return status; | 2968 | return status; |
3024 | } | 2969 | } |
3025 | |||
3026 | /** | ||
3027 | * scic_controller_allocate_io_tag() - This method will allocate a tag from the | ||
3028 | * pool of free IO tags. Direct allocation of IO tags by the SCI Core user | ||
3029 | * is optional. The scic_controller_start_io() method will allocate an IO | ||
3030 | * tag if this method is not utilized and the tag is not supplied to the IO | ||
3031 | * construct routine. Direct allocation of IO tags may provide additional | ||
3032 | * performance improvements in environments capable of supporting this usage | ||
3033 | * model. Additionally, direct allocation of IO tags also provides | ||
3034 | * additional flexibility to the SCI Core user. Specifically, the user may | ||
3035 | * retain IO tags across the lives of multiple IO requests. | ||
3036 | * @controller: the handle to the controller object for which to allocate the | ||
3037 | * tag. | ||
3038 | * | ||
3039 | * IO tags are a protected resource. It is incumbent upon the SCI Core user to | ||
3040 | * ensure that each of the methods that may allocate or free available IO tags | ||
3041 | * are handled in a mutually exclusive manner. This method is one of said | ||
3042 | * methods requiring proper critical code section protection (e.g. semaphore, | ||
3043 | * spin-lock, etc.). An unsigned integer representing an available IO tag. | ||
3044 | * SCI_CONTROLLER_INVALID_IO_TAG This value is returned if there are no | ||
3045 | * currently available tags to be allocated. All return other values indicate a | ||
3046 | * legitimate tag. | ||
3047 | */ | ||
3048 | u16 scic_controller_allocate_io_tag(struct scic_sds_controller *scic) | ||
3049 | { | ||
3050 | struct isci_host *ihost = scic_to_ihost(scic); | ||
3051 | |||
3052 | if (isci_tci_space(ihost)) { | ||
3053 | u16 tci = isci_tci_alloc(ihost); | ||
3054 | u8 seq = scic->io_request_sequence[tci]; | ||
3055 | |||
3056 | return ISCI_TAG(seq, tci); | ||
3057 | } | ||
3058 | |||
3059 | return SCI_CONTROLLER_INVALID_IO_TAG; | ||
3060 | } | ||
3061 | |||
3062 | /** | ||
3063 | * scic_controller_free_io_tag() - This method will free an IO tag to the pool | ||
3064 | * of free IO tags. This method provides the SCI Core user more flexibility | ||
3065 | * with regards to IO tags. The user may desire to keep an IO tag after an | ||
3066 | * IO request has completed, because they plan on re-using the tag for a | ||
3067 | * subsequent IO request. This method is only legal if the tag was | ||
3068 | * allocated via scic_controller_allocate_io_tag(). | ||
3069 | * @controller: This parameter specifies the handle to the controller object | ||
3070 | * for which to free/return the tag. | ||
3071 | * @io_tag: This parameter represents the tag to be freed to the pool of | ||
3072 | * available tags. | ||
3073 | * | ||
3074 | * - IO tags are a protected resource. It is incumbent upon the SCI Core user | ||
3075 | * to ensure that each of the methods that may allocate or free available IO | ||
3076 | * tags are handled in a mutually exclusive manner. This method is one of said | ||
3077 | * methods requiring proper critical code section protection (e.g. semaphore, | ||
3078 | * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI | ||
3079 | * Core user, using the scic_controller_allocate_io_tag() method, then it is | ||
3080 | * the responsibility of the caller to invoke this method to free the tag. This | ||
3081 | * method returns an indication of whether the tag was successfully put back | ||
3082 | * (freed) to the pool of available tags. SCI_SUCCESS This return value | ||
3083 | * indicates the tag was successfully placed into the pool of available IO | ||
3084 | * tags. SCI_FAILURE_INVALID_IO_TAG This value is returned if the supplied tag | ||
3085 | * is not a valid IO tag value. | ||
3086 | */ | ||
3087 | enum sci_status scic_controller_free_io_tag(struct scic_sds_controller *scic, | ||
3088 | u16 io_tag) | ||
3089 | { | ||
3090 | struct isci_host *ihost = scic_to_ihost(scic); | ||
3091 | u16 tci = ISCI_TAG_TCI(io_tag); | ||
3092 | u16 seq = ISCI_TAG_SEQ(io_tag); | ||
3093 | |||
3094 | /* prevent tail from passing head */ | ||
3095 | if (isci_tci_active(ihost) == 0) | ||
3096 | return SCI_FAILURE_INVALID_IO_TAG; | ||
3097 | |||
3098 | if (seq == scic->io_request_sequence[tci]) { | ||
3099 | scic->io_request_sequence[tci] = (seq+1) & (SCI_MAX_SEQ-1); | ||
3100 | |||
3101 | isci_tci_free(ihost, ISCI_TAG_TCI(io_tag)); | ||
3102 | |||
3103 | return SCI_SUCCESS; | ||
3104 | } | ||
3105 | return SCI_FAILURE_INVALID_IO_TAG; | ||
3106 | } | ||