ssp_request.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * This file is provided under a dual BSD/GPLv2 license. When using or
  3. * redistributing this file, you may do so under either license.
  4. *
  5. * GPL LICENSE SUMMARY
  6. *
  7. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of version 2 of the GNU General Public License as
  11. * published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  21. * The full GNU General Public License is included in this distribution
  22. * in the file called LICENSE.GPL.
  23. *
  24. * BSD LICENSE
  25. *
  26. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  27. * All rights reserved.
  28. *
  29. * Redistribution and use in source and binary forms, with or without
  30. * modification, are permitted provided that the following conditions
  31. * are met:
  32. *
  33. * * Redistributions of source code must retain the above copyright
  34. * notice, this list of conditions and the following disclaimer.
  35. * * Redistributions in binary form must reproduce the above copyright
  36. * notice, this list of conditions and the following disclaimer in
  37. * the documentation and/or other materials provided with the
  38. * distribution.
  39. * * Neither the name of Intel Corporation nor the names of its
  40. * contributors may be used to endorse or promote products derived
  41. * from this software without specific prior written permission.
  42. *
  43. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  44. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  45. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  46. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  47. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  48. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  49. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  50. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  51. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  53. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54. */
  55. #include "host.h"
  56. #include "request.h"
  57. #include "state_machine.h"
  58. #include "scu_task_context.h"
  59. #include "scu_completion_codes.h"
  60. /**
  61. * This method processes the completions transport layer (TL) status to
  62. * determine if the RAW task management frame was sent successfully. If the
  63. * raw frame was sent successfully, then the state for the task request
  64. * transitions to waiting for a response frame.
  65. * @sci_req: This parameter specifies the request for which the TC
  66. * completion was received.
  67. * @completion_code: This parameter indicates the completion status information
  68. * for the TC.
  69. *
  70. * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
  71. * this method always returns success.
  72. */
  73. static enum sci_status scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler(
  74. struct scic_sds_request *sci_req,
  75. u32 completion_code)
  76. {
  77. switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
  78. case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
  79. scic_sds_request_set_status(
  80. sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS
  81. );
  82. sci_base_state_machine_change_state(
  83. &sci_req->started_substate_machine,
  84. SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
  85. );
  86. break;
  87. case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
  88. /*
  89. * Currently, the decision is to simply allow the task request to
  90. * timeout if the task IU wasn't received successfully.
  91. * There is a potential for receiving multiple task responses if we
  92. * decide to send the task IU again. */
  93. dev_warn(scic_to_dev(sci_req->owning_controller),
  94. "%s: TaskRequest:0x%p CompletionCode:%x - "
  95. "ACK/NAK timeout\n",
  96. __func__,
  97. sci_req,
  98. completion_code);
  99. sci_base_state_machine_change_state(
  100. &sci_req->started_substate_machine,
  101. SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
  102. );
  103. break;
  104. default:
  105. /*
  106. * All other completion status cause the IO to be complete. If a NAK
  107. * was received, then it is up to the user to retry the request. */
  108. scic_sds_request_set_status(
  109. sci_req,
  110. SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
  111. SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
  112. );
  113. sci_base_state_machine_change_state(&sci_req->state_machine,
  114. SCI_BASE_REQUEST_STATE_COMPLETED);
  115. break;
  116. }
  117. return SCI_SUCCESS;
  118. }
  119. /**
  120. * This method is responsible for processing a terminate/abort request for this
  121. * TC while the request is waiting for the task management response
  122. * unsolicited frame.
  123. * @sci_req: This parameter specifies the request for which the
  124. * termination was requested.
  125. *
  126. * This method returns an indication as to whether the abort request was
  127. * successfully handled. need to update to ensure the received UF doesn't cause
  128. * damage to subsequent requests (i.e. put the extended tag in a holding
  129. * pattern for this particular device).
  130. */
  131. static enum sci_status scic_sds_ssp_task_request_await_tc_response_abort_handler(
  132. struct scic_sds_request *request)
  133. {
  134. sci_base_state_machine_change_state(&request->state_machine,
  135. SCI_BASE_REQUEST_STATE_ABORTING);
  136. sci_base_state_machine_change_state(&request->state_machine,
  137. SCI_BASE_REQUEST_STATE_COMPLETED);
  138. return SCI_SUCCESS;
  139. }
  140. /**
  141. * This method processes an unsolicited frame while the task mgmt request is
  142. * waiting for a response frame. It will copy the response data, release
  143. * the unsolicited frame, and transition the request to the
  144. * SCI_BASE_REQUEST_STATE_COMPLETED state.
  145. * @sci_req: This parameter specifies the request for which the
  146. * unsolicited frame was received.
  147. * @frame_index: This parameter indicates the unsolicited frame index that
  148. * should contain the response.
  149. *
  150. * This method returns an indication of whether the TC response frame was
  151. * handled successfully or not. SCI_SUCCESS Currently this value is always
  152. * returned and indicates successful processing of the TC response. Should
  153. * probably update to check frame type and make sure it is a response frame.
  154. */
  155. static enum sci_status scic_sds_ssp_task_request_await_tc_response_frame_handler(
  156. struct scic_sds_request *request,
  157. u32 frame_index)
  158. {
  159. scic_sds_io_request_copy_response(request);
  160. sci_base_state_machine_change_state(&request->state_machine,
  161. SCI_BASE_REQUEST_STATE_COMPLETED);
  162. scic_sds_controller_release_frame(request->owning_controller,
  163. frame_index);
  164. return SCI_SUCCESS;
  165. }
  166. static const struct scic_sds_io_request_state_handler scic_sds_ssp_task_request_started_substate_handler_table[] = {
  167. [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
  168. .abort_handler = scic_sds_request_started_state_abort_handler,
  169. .tc_completion_handler = scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler,
  170. },
  171. [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
  172. .abort_handler = scic_sds_ssp_task_request_await_tc_response_abort_handler,
  173. .frame_handler = scic_sds_ssp_task_request_await_tc_response_frame_handler,
  174. }
  175. };
  176. /**
  177. * This method performs the actions required when entering the
  178. * SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
  179. * sub-state. This includes setting the IO request state handlers for this
  180. * sub-state.
  181. * @object: This parameter specifies the request object for which the sub-state
  182. * change is occurring.
  183. *
  184. * none.
  185. */
  186. static void scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter(
  187. void *object)
  188. {
  189. struct scic_sds_request *sci_req = object;
  190. SET_STATE_HANDLER(
  191. sci_req,
  192. scic_sds_ssp_task_request_started_substate_handler_table,
  193. SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
  194. );
  195. }
  196. /**
  197. * This method performs the actions required when entering the
  198. * SCIC_SDS_IO_REQUEST_STARTED_SUBSTATE_AWAIT_TC_RESPONSE sub-state. This
  199. * includes setting the IO request state handlers for this sub-state.
  200. * @object: This parameter specifies the request object for which the sub-state
  201. * change is occurring.
  202. *
  203. * none.
  204. */
  205. static void scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter(
  206. void *object)
  207. {
  208. struct scic_sds_request *sci_req = object;
  209. SET_STATE_HANDLER(
  210. sci_req,
  211. scic_sds_ssp_task_request_started_substate_handler_table,
  212. SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
  213. );
  214. }
  215. const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[] = {
  216. [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
  217. .enter_state = scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter,
  218. },
  219. [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
  220. .enter_state = scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter,
  221. },
  222. };