stp_remote_device.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  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 "intel_ata.h"
  56. #include "intel_sata.h"
  57. #include "intel_sat.h"
  58. #include "sci_base_state.h"
  59. #include "scic_sds_controller.h"
  60. #include "scic_sds_port.h"
  61. #include "remote_device.h"
  62. #include "scic_sds_request.h"
  63. #include "sci_environment.h"
  64. #include "sci_util.h"
  65. #include "scu_event_codes.h"
  66. /**
  67. * This method will perform the STP request completion processing common to IO
  68. * requests and task requests of all types
  69. * @device: This parameter specifies the device for which the request is being
  70. * completed.
  71. * @request: This parameter specifies the request being completed.
  72. *
  73. * This method returns an indication as to whether the request processing
  74. * completed successfully.
  75. */
  76. static enum sci_status scic_sds_stp_remote_device_complete_request(
  77. struct scic_sds_remote_device *device,
  78. struct scic_sds_request *request)
  79. {
  80. enum sci_status status;
  81. status = scic_sds_io_request_complete(request);
  82. if (status == SCI_SUCCESS) {
  83. status = scic_sds_port_complete_io(
  84. device->owning_port, device, request);
  85. if (status == SCI_SUCCESS) {
  86. scic_sds_remote_device_decrement_request_count(device);
  87. if (request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
  88. /*
  89. * This request causes hardware error, device needs to be Lun Reset.
  90. * So here we force the state machine to IDLE state so the rest IOs
  91. * can reach RNC state handler, these IOs will be completed by RNC with
  92. * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */
  93. sci_base_state_machine_change_state(
  94. &device->ready_substate_machine,
  95. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
  96. );
  97. } else if (scic_sds_remote_device_get_request_count(device) == 0) {
  98. sci_base_state_machine_change_state(
  99. &device->ready_substate_machine,
  100. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
  101. );
  102. }
  103. }
  104. }
  105. if (status != SCI_SUCCESS)
  106. dev_err(scirdev_to_dev(device),
  107. "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
  108. "could not complete\n",
  109. __func__,
  110. device->owning_port,
  111. device,
  112. request,
  113. status);
  114. return status;
  115. }
  116. /*
  117. * *****************************************************************************
  118. * * STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
  119. * ***************************************************************************** */
  120. /**
  121. * This is the READY NCQ substate handler to start task management request. In
  122. * this routine, we suspend and resume the RNC.
  123. * @device: The target device a task management request towards to.
  124. * @request: The task request.
  125. *
  126. * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to
  127. * let controller_start_task_handler know that the controller can't post TC for
  128. * task request yet, instead, when RNC gets resumed, a controller_continue_task
  129. * callback will be called.
  130. */
  131. static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
  132. struct scic_sds_remote_device *device,
  133. struct scic_sds_request *request)
  134. {
  135. enum sci_status status;
  136. /* Will the port allow the io request to start? */
  137. status = device->owning_port->state_handlers->start_io_handler(
  138. device->owning_port, device, request);
  139. if (status != SCI_SUCCESS)
  140. return status;
  141. status = scic_sds_remote_node_context_start_task(&device->rnc, request);
  142. if (status != SCI_SUCCESS)
  143. goto out;
  144. status = request->state_handlers->start_handler(request);
  145. if (status != SCI_SUCCESS)
  146. goto out;
  147. /*
  148. * Note: If the remote device state is not IDLE this will replace
  149. * the request that probably resulted in the task management request.
  150. */
  151. device->working_request = request;
  152. sci_base_state_machine_change_state(&device->ready_substate_machine,
  153. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
  154. /*
  155. * The remote node context must cleanup the TCi to NCQ mapping table.
  156. * The only way to do this correctly is to either write to the TLCR
  157. * register or to invalidate and repost the RNC. In either case the
  158. * remote node context state machine will take the correct action when
  159. * the remote node context is suspended and later resumed.
  160. */
  161. scic_sds_remote_node_context_suspend(&device->rnc,
  162. SCI_SOFTWARE_SUSPENSION, NULL, NULL);
  163. scic_sds_remote_node_context_resume(&device->rnc,
  164. scic_sds_remote_device_continue_request,
  165. device);
  166. out:
  167. scic_sds_remote_device_start_request(device, request, status);
  168. /*
  169. * We need to let the controller start request handler know that it can't
  170. * post TC yet. We will provide a callback function to post TC when RNC gets
  171. * resumed.
  172. */
  173. return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
  174. }
  175. /*
  176. * *****************************************************************************
  177. * * STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
  178. * ***************************************************************************** */
  179. /**
  180. * This method will handle the start io operation for a sata device that is in
  181. * the command idle state. - Evalute the type of IO request to be started -
  182. * If its an NCQ request change to NCQ substate - If its any other command
  183. * change to the CMD substate
  184. * @device:
  185. * @request:
  186. *
  187. * If this is a softreset we may want to have a different substate.
  188. * enum sci_status
  189. */
  190. static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
  191. struct scic_sds_remote_device *sci_dev,
  192. struct scic_sds_request *request)
  193. {
  194. enum sci_status status;
  195. struct isci_request *isci_request =
  196. (struct isci_request *)sci_object_get_association(request);
  197. /* Will the port allow the io request to start? */
  198. status = sci_dev->owning_port->state_handlers->start_io_handler(
  199. sci_dev->owning_port, sci_dev, request);
  200. if (status != SCI_SUCCESS)
  201. return status;
  202. status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
  203. if (status != SCI_SUCCESS)
  204. goto out;
  205. status = request->state_handlers->start_handler(request);
  206. if (status != SCI_SUCCESS)
  207. goto out;
  208. if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
  209. sci_base_state_machine_change_state(&sci_dev->ready_substate_machine,
  210. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
  211. } else {
  212. sci_dev->working_request = request;
  213. sci_base_state_machine_change_state(&sci_dev->ready_substate_machine,
  214. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
  215. }
  216. out:
  217. scic_sds_remote_device_start_request(sci_dev, request, status);
  218. return status;
  219. }
  220. /**
  221. *
  222. * @[in]: device The device received event.
  223. * @[in]: event_code The event code.
  224. *
  225. * This method will handle the event for a sata device that is in the idle
  226. * state. We pick up suspension events to handle specifically to this state. We
  227. * resume the RNC right away. enum sci_status
  228. */
  229. static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
  230. struct scic_sds_remote_device *sci_dev,
  231. u32 event_code)
  232. {
  233. enum sci_status status;
  234. status = scic_sds_remote_device_general_event_handler(sci_dev, event_code);
  235. if (status == SCI_SUCCESS) {
  236. if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
  237. || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
  238. status = scic_sds_remote_node_context_resume(
  239. &sci_dev->rnc, NULL, NULL);
  240. }
  241. }
  242. return status;
  243. }
  244. /*
  245. * *****************************************************************************
  246. * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
  247. * ***************************************************************************** */
  248. static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
  249. struct scic_sds_remote_device *sci_dev,
  250. struct scic_sds_request *request)
  251. {
  252. enum sci_status status;
  253. struct isci_request *isci_request =
  254. (struct isci_request *)sci_object_get_association(request);
  255. if (isci_sata_get_sat_protocol(isci_request) == SAT_PROTOCOL_FPDMA) {
  256. status = sci_dev->owning_port->state_handlers->start_io_handler(
  257. sci_dev->owning_port,
  258. sci_dev,
  259. request);
  260. if (status != SCI_SUCCESS)
  261. return status;
  262. status = scic_sds_remote_node_context_start_io(&sci_dev->rnc, request);
  263. if (status != SCI_SUCCESS)
  264. return status;
  265. status = request->state_handlers->start_handler(request);
  266. scic_sds_remote_device_start_request(sci_dev, request, status);
  267. } else
  268. status = SCI_FAILURE_INVALID_STATE;
  269. return status;
  270. }
  271. /**
  272. * This method will handle events received while the STP device is in the ready
  273. * command substate.
  274. * @sci_dev: This is the device object that is receiving the event.
  275. * @event_code: The event code to process.
  276. *
  277. * enum sci_status
  278. */
  279. static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
  280. struct scic_sds_remote_device *sci_dev,
  281. u32 frame_index)
  282. {
  283. enum sci_status status;
  284. struct sata_fis_header *frame_header;
  285. status = scic_sds_unsolicited_frame_control_get_header(
  286. &(scic_sds_remote_device_get_controller(sci_dev)->uf_control),
  287. frame_index,
  288. (void **)&frame_header
  289. );
  290. if (status == SCI_SUCCESS) {
  291. if (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS &&
  292. (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
  293. sci_dev->not_ready_reason =
  294. SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
  295. /*
  296. * / @todo Check sactive and complete associated IO
  297. * if any.
  298. */
  299. sci_base_state_machine_change_state(
  300. &sci_dev->ready_substate_machine,
  301. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  302. );
  303. } else if (frame_header->fis_type == SATA_FIS_TYPE_REGD2H &&
  304. (frame_header->status & ATA_STATUS_REG_ERROR_BIT)) {
  305. /*
  306. * Some devices return D2H FIS when an NCQ error is detected.
  307. * Treat this like an SDB error FIS ready reason.
  308. */
  309. sci_dev->not_ready_reason =
  310. SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
  311. sci_base_state_machine_change_state(
  312. &sci_dev->ready_substate_machine,
  313. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  314. );
  315. } else {
  316. status = SCI_FAILURE;
  317. }
  318. scic_sds_controller_release_frame(
  319. scic_sds_remote_device_get_controller(sci_dev), frame_index
  320. );
  321. }
  322. return status;
  323. }
  324. /*
  325. * *****************************************************************************
  326. * * STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
  327. * ***************************************************************************** */
  328. /**
  329. * This device is already handling a command it can not accept new commands
  330. * until this one is complete.
  331. * @device:
  332. * @request:
  333. *
  334. * enum sci_status
  335. */
  336. static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
  337. struct scic_sds_remote_device *device,
  338. struct scic_sds_request *request)
  339. {
  340. return SCI_FAILURE_INVALID_STATE;
  341. }
  342. static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
  343. struct scic_sds_remote_device *sci_dev,
  344. u32 suspend_type)
  345. {
  346. enum sci_status status;
  347. status = scic_sds_remote_node_context_suspend(&sci_dev->rnc,
  348. suspend_type, NULL, NULL);
  349. return status;
  350. }
  351. static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
  352. struct scic_sds_remote_device *sci_dev,
  353. u32 frame_index)
  354. {
  355. enum sci_status status;
  356. /*
  357. * / The device doe not process any UF received from the hardware while
  358. * / in this state. All unsolicited frames are forwarded to the io request
  359. * / object. */
  360. status = scic_sds_io_request_frame_handler(
  361. sci_dev->working_request,
  362. frame_index
  363. );
  364. return status;
  365. }
  366. /*
  367. * *****************************************************************************
  368. * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
  369. * ***************************************************************************** */
  370. /*
  371. * *****************************************************************************
  372. * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS
  373. * ***************************************************************************** */
  374. /*
  375. * *****************************************************************************
  376. * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
  377. * ***************************************************************************** */
  378. static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
  379. struct scic_sds_remote_device *device,
  380. struct scic_sds_request *request)
  381. {
  382. return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
  383. }
  384. /**
  385. * This method will perform the STP request (both io or task) completion
  386. * processing for await reset state.
  387. * @device: This parameter specifies the device for which the request is being
  388. * completed.
  389. * @request: This parameter specifies the request being completed.
  390. *
  391. * This method returns an indication as to whether the request processing
  392. * completed successfully.
  393. */
  394. static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
  395. struct scic_sds_remote_device *device,
  396. struct scic_sds_request *request)
  397. {
  398. struct scic_sds_request *sci_req = (struct scic_sds_request *)request;
  399. enum sci_status status;
  400. status = scic_sds_io_request_complete(sci_req);
  401. if (status == SCI_SUCCESS) {
  402. status = scic_sds_port_complete_io(
  403. device->owning_port, device, sci_req
  404. );
  405. if (status == SCI_SUCCESS)
  406. scic_sds_remote_device_decrement_request_count(device);
  407. }
  408. if (status != SCI_SUCCESS)
  409. dev_err(scirdev_to_dev(device),
  410. "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
  411. "could not complete\n",
  412. __func__,
  413. device->owning_port,
  414. device,
  415. sci_req,
  416. status);
  417. return status;
  418. }
  419. static const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = {
  420. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
  421. .start_handler = scic_sds_remote_device_default_start_handler,
  422. .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
  423. .fail_handler = scic_sds_remote_device_default_fail_handler,
  424. .destruct_handler = scic_sds_remote_device_default_destruct_handler,
  425. .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
  426. .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
  427. .start_io_handler = scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
  428. .complete_io_handler = scic_sds_remote_device_default_complete_request_handler,
  429. .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
  430. .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
  431. .complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
  432. .suspend_handler = scic_sds_remote_device_default_suspend_handler,
  433. .resume_handler = scic_sds_remote_device_default_resume_handler,
  434. .event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler,
  435. .frame_handler = scic_sds_remote_device_default_frame_handler
  436. },
  437. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
  438. .start_handler = scic_sds_remote_device_default_start_handler,
  439. .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
  440. .fail_handler = scic_sds_remote_device_default_fail_handler,
  441. .destruct_handler = scic_sds_remote_device_default_destruct_handler,
  442. .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
  443. .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
  444. .start_io_handler = scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
  445. .complete_io_handler = scic_sds_stp_remote_device_complete_request,
  446. .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
  447. .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
  448. .complete_task_handler = scic_sds_stp_remote_device_complete_request,
  449. .suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
  450. .resume_handler = scic_sds_remote_device_default_resume_handler,
  451. .event_handler = scic_sds_remote_device_general_event_handler,
  452. .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
  453. },
  454. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
  455. .start_handler = scic_sds_remote_device_default_start_handler,
  456. .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
  457. .fail_handler = scic_sds_remote_device_default_fail_handler,
  458. .destruct_handler = scic_sds_remote_device_default_destruct_handler,
  459. .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
  460. .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
  461. .start_io_handler = scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
  462. .complete_io_handler = scic_sds_stp_remote_device_complete_request,
  463. .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
  464. .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
  465. .complete_task_handler = scic_sds_stp_remote_device_complete_request,
  466. .suspend_handler = scic_sds_remote_device_default_suspend_handler,
  467. .resume_handler = scic_sds_remote_device_default_resume_handler,
  468. .event_handler = scic_sds_remote_device_general_event_handler,
  469. .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
  470. },
  471. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
  472. .start_handler = scic_sds_remote_device_default_start_handler,
  473. .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
  474. .fail_handler = scic_sds_remote_device_default_fail_handler,
  475. .destruct_handler = scic_sds_remote_device_default_destruct_handler,
  476. .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
  477. .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
  478. .start_io_handler = scic_sds_remote_device_default_start_request_handler,
  479. .complete_io_handler = scic_sds_stp_remote_device_complete_request,
  480. .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
  481. .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
  482. .complete_task_handler = scic_sds_stp_remote_device_complete_request,
  483. .suspend_handler = scic_sds_remote_device_default_suspend_handler,
  484. .resume_handler = scic_sds_remote_device_default_resume_handler,
  485. .event_handler = scic_sds_remote_device_general_event_handler,
  486. .frame_handler = scic_sds_remote_device_general_frame_handler
  487. },
  488. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
  489. .start_handler = scic_sds_remote_device_default_start_handler,
  490. .stop_handler = scic_sds_remote_device_ready_state_stop_handler,
  491. .fail_handler = scic_sds_remote_device_default_fail_handler,
  492. .destruct_handler = scic_sds_remote_device_default_destruct_handler,
  493. .reset_handler = scic_sds_remote_device_ready_state_reset_handler,
  494. .reset_complete_handler = scic_sds_remote_device_default_reset_complete_handler,
  495. .start_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
  496. .complete_io_handler = scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
  497. .continue_io_handler = scic_sds_remote_device_default_continue_request_handler,
  498. .start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
  499. .complete_task_handler = scic_sds_stp_remote_device_complete_request,
  500. .suspend_handler = scic_sds_remote_device_default_suspend_handler,
  501. .resume_handler = scic_sds_remote_device_default_resume_handler,
  502. .event_handler = scic_sds_remote_device_general_event_handler,
  503. .frame_handler = scic_sds_remote_device_general_frame_handler
  504. }
  505. };
  506. /*
  507. * *****************************************************************************
  508. * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
  509. * ***************************************************************************** */
  510. static void
  511. scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(void *user_cookie)
  512. {
  513. struct scic_sds_remote_device *sci_dev = user_cookie;
  514. struct isci_remote_device *idev = sci_object_get_association(sci_dev);
  515. struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
  516. struct isci_host *ihost = sci_object_get_association(scic);
  517. /*
  518. * For NCQ operation we do not issue a
  519. * scic_cb_remote_device_not_ready(). As a result, avoid sending
  520. * the ready notification.
  521. */
  522. if (sci_dev->ready_substate_machine.previous_state_id !=
  523. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
  524. isci_remote_device_ready(ihost, idev);
  525. }
  526. /*
  527. * *****************************************************************************
  528. * * STP REMOTE DEVICE READY IDLE SUBSTATE
  529. * ***************************************************************************** */
  530. /**
  531. *
  532. * @device: This is the SCI base object which is cast into a
  533. * struct scic_sds_remote_device object.
  534. *
  535. */
  536. static void scic_sds_stp_remote_device_ready_idle_substate_enter(
  537. struct sci_base_object *device)
  538. {
  539. struct scic_sds_remote_device *sci_dev;
  540. sci_dev = (struct scic_sds_remote_device *)device;
  541. SET_STATE_HANDLER(
  542. sci_dev,
  543. scic_sds_stp_remote_device_ready_substate_handler_table,
  544. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
  545. );
  546. sci_dev->working_request = NULL;
  547. if (scic_sds_remote_node_context_is_ready(&sci_dev->rnc)) {
  548. /*
  549. * Since the RNC is ready, it's alright to finish completion
  550. * processing (e.g. signal the remote device is ready). */
  551. scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
  552. sci_dev
  553. );
  554. } else {
  555. scic_sds_remote_node_context_resume(
  556. &sci_dev->rnc,
  557. scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
  558. sci_dev);
  559. }
  560. }
  561. static void scic_sds_stp_remote_device_ready_cmd_substate_enter(struct sci_base_object *object)
  562. {
  563. struct scic_sds_remote_device *sci_dev = container_of(object, typeof(*sci_dev),
  564. parent);
  565. struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
  566. struct isci_host *ihost = sci_object_get_association(scic);
  567. struct isci_remote_device *idev = sci_object_get_association(sci_dev);
  568. BUG_ON(sci_dev->working_request == NULL);
  569. SET_STATE_HANDLER(sci_dev,
  570. scic_sds_stp_remote_device_ready_substate_handler_table,
  571. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);
  572. isci_remote_device_not_ready(ihost, idev,
  573. SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
  574. }
  575. static void scic_sds_stp_remote_device_ready_ncq_substate_enter(struct sci_base_object *object)
  576. {
  577. struct scic_sds_remote_device *sci_dev = container_of(object, typeof(*sci_dev),
  578. parent);
  579. SET_STATE_HANDLER(sci_dev,
  580. scic_sds_stp_remote_device_ready_substate_handler_table,
  581. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ);
  582. }
  583. static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base_object *object)
  584. {
  585. struct scic_sds_remote_device *sci_dev = container_of(object, typeof(*sci_dev),
  586. parent);
  587. struct scic_sds_controller *scic = scic_sds_remote_device_get_controller(sci_dev);
  588. struct isci_host *ihost = sci_object_get_association(scic);
  589. struct isci_remote_device *idev = sci_object_get_association(sci_dev);
  590. SET_STATE_HANDLER(sci_dev,
  591. scic_sds_stp_remote_device_ready_substate_handler_table,
  592. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR);
  593. if (sci_dev->not_ready_reason ==
  594. SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
  595. isci_remote_device_not_ready(ihost, idev, sci_dev->not_ready_reason);
  596. }
  597. /*
  598. * *****************************************************************************
  599. * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
  600. * ***************************************************************************** */
  601. /**
  602. * The enter routine to READY AWAIT RESET substate.
  603. * @device: This is the SCI base object which is cast into a
  604. * struct scic_sds_remote_device object.
  605. *
  606. */
  607. static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
  608. struct sci_base_object *device)
  609. {
  610. struct scic_sds_remote_device *sci_dev;
  611. sci_dev = (struct scic_sds_remote_device *)device;
  612. SET_STATE_HANDLER(
  613. sci_dev,
  614. scic_sds_stp_remote_device_ready_substate_handler_table,
  615. SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
  616. );
  617. }
  618. const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = {
  619. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
  620. .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
  621. },
  622. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
  623. .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
  624. },
  625. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
  626. .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
  627. },
  628. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
  629. .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
  630. },
  631. [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
  632. .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
  633. },
  634. };