remote_device.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  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 "isci.h"
  56. #include "scic_io_request.h"
  57. #include "scic_remote_device.h"
  58. #include "scic_phy.h"
  59. #include "scic_port.h"
  60. #include "port.h"
  61. #include "remote_device.h"
  62. #include "request.h"
  63. #include "task.h"
  64. /**
  65. * isci_remote_device_deconstruct() - This function frees an isci_remote_device.
  66. * @isci_host: This parameter specifies the isci host object.
  67. * @isci_device: This parameter specifies the remote device to be freed.
  68. *
  69. */
  70. static void isci_remote_device_deconstruct(
  71. struct isci_host *isci_host,
  72. struct isci_remote_device *isci_device)
  73. {
  74. dev_dbg(&isci_host->pdev->dev,
  75. "%s: isci_device = %p\n", __func__, isci_device);
  76. /* There should not be any outstanding io's. All paths to
  77. * here should go through isci_remote_device_nuke_requests.
  78. * If we hit this condition, we will need a way to complete
  79. * io requests in process */
  80. while (!list_empty(&isci_device->reqs_in_process)) {
  81. dev_err(&isci_host->pdev->dev,
  82. "%s: ** request list not empty! **\n", __func__);
  83. BUG();
  84. }
  85. /* Remove all related references to this device and free
  86. * the cache object.
  87. */
  88. scic_remote_device_destruct(isci_device->sci_device_handle);
  89. isci_device->domain_dev->lldd_dev = NULL;
  90. list_del(&isci_device->node);
  91. kmem_cache_free(isci_kmem_cache, isci_device);
  92. }
  93. /**
  94. * isci_remote_device_construct() - This function calls the scic remote device
  95. * construct and start functions, it waits on the remote device start
  96. * completion.
  97. * @port: This parameter specifies the isci port with the remote device.
  98. * @isci_device: This parameter specifies the isci remote device
  99. *
  100. * status from the scic calls, the caller to this function should clean up
  101. * resources as appropriate.
  102. */
  103. static enum sci_status isci_remote_device_construct(
  104. struct isci_port *port,
  105. struct isci_remote_device *isci_device)
  106. {
  107. enum sci_status status = SCI_SUCCESS;
  108. /* let the core do it's common constuction. */
  109. scic_remote_device_construct(port->sci_port_handle,
  110. isci_device->sci_device_handle);
  111. /* let the core do it's device specific constuction. */
  112. if (isci_device->domain_dev->parent &&
  113. (isci_device->domain_dev->parent->dev_type == EDGE_DEV)) {
  114. int i;
  115. /* struct smp_response_discover discover_response; */
  116. struct discover_resp discover_response;
  117. struct domain_device *parent =
  118. isci_device->domain_dev->parent;
  119. struct expander_device *parent_ex = &parent->ex_dev;
  120. for (i = 0; i < parent_ex->num_phys; i++) {
  121. struct ex_phy *phy = &parent_ex->ex_phy[i];
  122. if ((phy->phy_state == PHY_VACANT) ||
  123. (phy->phy_state == PHY_NOT_PRESENT))
  124. continue;
  125. if (SAS_ADDR(phy->attached_sas_addr)
  126. == SAS_ADDR(isci_device->domain_dev->sas_addr)) {
  127. discover_response.attached_dev_type
  128. = phy->attached_dev_type;
  129. discover_response.linkrate
  130. = phy->linkrate;
  131. discover_response.attached_sata_host
  132. = phy->attached_sata_host;
  133. discover_response.attached_sata_dev
  134. = phy->attached_sata_dev;
  135. discover_response.attached_sata_ps
  136. = phy->attached_sata_ps;
  137. discover_response.iproto
  138. = phy->attached_iproto >> 1;
  139. discover_response.tproto
  140. = phy->attached_tproto >> 1;
  141. memcpy(
  142. discover_response.attached_sas_addr,
  143. phy->attached_sas_addr,
  144. SAS_ADDR_SIZE
  145. );
  146. discover_response.attached_phy_id
  147. = phy->attached_phy_id;
  148. discover_response.change_count
  149. = phy->phy_change_count;
  150. discover_response.routing_attr
  151. = phy->routing_attr;
  152. discover_response.hmin_linkrate
  153. = phy->phy->minimum_linkrate_hw;
  154. discover_response.hmax_linkrate
  155. = phy->phy->maximum_linkrate_hw;
  156. discover_response.pmin_linkrate
  157. = phy->phy->minimum_linkrate;
  158. discover_response.pmax_linkrate
  159. = phy->phy->maximum_linkrate;
  160. }
  161. }
  162. dev_dbg(&port->isci_host->pdev->dev,
  163. "%s: parent->dev_type = EDGE_DEV\n",
  164. __func__);
  165. status = scic_remote_device_ea_construct(
  166. isci_device->sci_device_handle,
  167. (struct smp_response_discover *)&discover_response
  168. );
  169. } else
  170. status = scic_remote_device_da_construct(
  171. isci_device->sci_device_handle
  172. );
  173. if (status != SCI_SUCCESS) {
  174. dev_dbg(&port->isci_host->pdev->dev,
  175. "%s: scic_remote_device_da_construct failed - "
  176. "isci_device = %p\n",
  177. __func__,
  178. isci_device);
  179. return status;
  180. }
  181. sci_object_set_association(
  182. isci_device->sci_device_handle,
  183. isci_device
  184. );
  185. BUG_ON(port->isci_host == NULL);
  186. /* start the device. */
  187. status = scic_remote_device_start(
  188. isci_device->sci_device_handle,
  189. ISCI_REMOTE_DEVICE_START_TIMEOUT
  190. );
  191. if (status != SCI_SUCCESS) {
  192. dev_warn(&port->isci_host->pdev->dev,
  193. "%s: scic_remote_device_start failed\n",
  194. __func__);
  195. return status;
  196. }
  197. return status;
  198. }
  199. /**
  200. * isci_remote_device_nuke_requests() - This function terminates all requests
  201. * for a given remote device.
  202. * @isci_device: This parameter specifies the remote device
  203. *
  204. */
  205. void isci_remote_device_nuke_requests(
  206. struct isci_remote_device *isci_device)
  207. {
  208. DECLARE_COMPLETION_ONSTACK(aborted_task_completion);
  209. struct isci_host *isci_host;
  210. isci_host = isci_device->isci_port->isci_host;
  211. dev_dbg(&isci_host->pdev->dev,
  212. "%s: isci_device = %p\n", __func__, isci_device);
  213. /* Cleanup all requests pending for this device. */
  214. isci_terminate_pending_requests(isci_host, isci_device, terminating);
  215. dev_dbg(&isci_host->pdev->dev,
  216. "%s: isci_device = %p, done\n", __func__, isci_device);
  217. }
  218. /**
  219. * This function builds the isci_remote_device when a libsas dev_found message
  220. * is received.
  221. * @isci_host: This parameter specifies the isci host object.
  222. * @port: This parameter specifies the isci_port conected to this device.
  223. *
  224. * pointer to new isci_remote_device.
  225. */
  226. static struct isci_remote_device *
  227. isci_remote_device_alloc(struct isci_host *isci_host, struct isci_port *port)
  228. {
  229. struct isci_remote_device *isci_device;
  230. struct scic_sds_remote_device *sci_dev;
  231. isci_device = kmem_cache_zalloc(isci_kmem_cache, GFP_KERNEL);
  232. if (!isci_device) {
  233. dev_warn(&isci_host->pdev->dev, "%s: failed\n", __func__);
  234. return NULL;
  235. }
  236. sci_dev = (struct scic_sds_remote_device *) &isci_device[1];
  237. isci_device->sci_device_handle = sci_dev;
  238. INIT_LIST_HEAD(&isci_device->reqs_in_process);
  239. INIT_LIST_HEAD(&isci_device->node);
  240. isci_device->host_quiesce = false;
  241. spin_lock_init(&isci_device->state_lock);
  242. spin_lock_init(&isci_device->host_quiesce_lock);
  243. isci_remote_device_change_state(isci_device, isci_freed);
  244. return isci_device;
  245. }
  246. /**
  247. * isci_device_set_host_quiesce_lock_state() - This function sets the host I/O
  248. * quiesce lock state for the remote_device object.
  249. * @isci_device,: This parameter points to the isci_remote_device object
  250. * @isci_device: This parameter specifies the new quiesce state.
  251. *
  252. */
  253. void isci_device_set_host_quiesce_lock_state(
  254. struct isci_remote_device *isci_device,
  255. bool lock_state)
  256. {
  257. unsigned long flags;
  258. dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
  259. "%s: isci_device=%p, lock_state=%d\n",
  260. __func__, isci_device, lock_state);
  261. spin_lock_irqsave(&isci_device->host_quiesce_lock, flags);
  262. isci_device->host_quiesce = lock_state;
  263. spin_unlock_irqrestore(&isci_device->host_quiesce_lock, flags);
  264. }
  265. /**
  266. * isci_remote_device_ready() - This function is called by the scic when the
  267. * remote device is ready. We mark the isci device as ready and signal the
  268. * waiting proccess.
  269. * @isci_host: This parameter specifies the isci host object.
  270. * @isci_device: This parameter specifies the remote device
  271. *
  272. */
  273. void isci_remote_device_ready(struct isci_remote_device *isci_device)
  274. {
  275. unsigned long flags;
  276. dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
  277. "%s: isci_device = %p\n", __func__, isci_device);
  278. /* device ready is actually a "ready for io" state. */
  279. if ((isci_starting == isci_remote_device_get_state(isci_device)) ||
  280. (isci_ready == isci_remote_device_get_state(isci_device))) {
  281. spin_lock_irqsave(&isci_device->isci_port->remote_device_lock,
  282. flags);
  283. isci_remote_device_change_state(isci_device, isci_ready_for_io);
  284. if (isci_device->completion)
  285. complete(isci_device->completion);
  286. spin_unlock_irqrestore(
  287. &isci_device->isci_port->remote_device_lock,
  288. flags);
  289. }
  290. }
  291. /**
  292. * isci_remote_device_not_ready() - This function is called by the scic when
  293. * the remote device is not ready. We mark the isci device as ready (not
  294. * "ready_for_io") and signal the waiting proccess.
  295. * @isci_host: This parameter specifies the isci host object.
  296. * @isci_device: This parameter specifies the remote device
  297. *
  298. */
  299. void isci_remote_device_not_ready(
  300. struct isci_remote_device *isci_device,
  301. u32 reason_code)
  302. {
  303. dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
  304. "%s: isci_device = %p\n", __func__, isci_device);
  305. if (reason_code == SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED)
  306. isci_remote_device_change_state(isci_device, isci_stopping);
  307. else
  308. /* device ready is actually a "not ready for io" state. */
  309. isci_remote_device_change_state(isci_device, isci_ready);
  310. }
  311. /**
  312. * isci_remote_device_stop_complete() - This function is called by the scic
  313. * when the remote device stop has completed. We mark the isci device as not
  314. * ready and remove the isci remote device.
  315. * @isci_host: This parameter specifies the isci host object.
  316. * @isci_device: This parameter specifies the remote device.
  317. * @status: This parameter specifies status of the completion.
  318. *
  319. */
  320. void isci_remote_device_stop_complete(
  321. struct isci_host *isci_host,
  322. struct isci_remote_device *isci_device,
  323. enum sci_status status)
  324. {
  325. struct completion *completion = isci_device->completion;
  326. dev_dbg(&isci_host->pdev->dev,
  327. "%s: complete isci_device = %p, status = 0x%x\n",
  328. __func__,
  329. isci_device,
  330. status);
  331. isci_remote_device_change_state(isci_device, isci_stopped);
  332. /* after stop, we can tear down resources. */
  333. isci_remote_device_deconstruct(isci_host, isci_device);
  334. /* notify interested parties. */
  335. if (completion)
  336. complete(completion);
  337. }
  338. /**
  339. * isci_remote_device_start_complete() - This function is called by the scic
  340. * when the remote device start has completed
  341. * @isci_host: This parameter specifies the isci host object.
  342. * @isci_device: This parameter specifies the remote device.
  343. * @status: This parameter specifies status of the completion.
  344. *
  345. */
  346. void isci_remote_device_start_complete(
  347. struct isci_host *isci_host,
  348. struct isci_remote_device *isci_device,
  349. enum sci_status status)
  350. {
  351. }
  352. /**
  353. * isci_remote_device_stop() - This function is called internally to stop the
  354. * remote device.
  355. * @isci_host: This parameter specifies the isci host object.
  356. * @isci_device: This parameter specifies the remote device.
  357. *
  358. * The status of the scic request to stop.
  359. */
  360. enum sci_status isci_remote_device_stop(
  361. struct isci_remote_device *isci_device)
  362. {
  363. enum sci_status status;
  364. unsigned long flags;
  365. DECLARE_COMPLETION_ONSTACK(completion);
  366. dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
  367. "%s: isci_device = %p\n", __func__, isci_device);
  368. isci_remote_device_change_state(isci_device, isci_stopping);
  369. /* We need comfirmation that stop completed. */
  370. isci_device->completion = &completion;
  371. BUG_ON(isci_device->isci_port == NULL);
  372. BUG_ON(isci_device->isci_port->isci_host == NULL);
  373. spin_lock_irqsave(&isci_device->isci_port->isci_host->scic_lock, flags);
  374. status = scic_remote_device_stop(
  375. isci_device->sci_device_handle,
  376. 50
  377. );
  378. spin_unlock_irqrestore(&isci_device->isci_port->isci_host->scic_lock, flags);
  379. /* Wait for the stop complete callback. */
  380. if (status == SCI_SUCCESS)
  381. wait_for_completion(&completion);
  382. dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
  383. "%s: isci_device = %p - after completion wait\n",
  384. __func__, isci_device);
  385. isci_device->completion = NULL;
  386. return status;
  387. }
  388. /**
  389. * isci_remote_device_gone() - This function is called by libsas when a domain
  390. * device is removed.
  391. * @domain_device: This parameter specifies the libsas domain device.
  392. *
  393. */
  394. void isci_remote_device_gone(
  395. struct domain_device *domain_dev)
  396. {
  397. struct isci_remote_device *isci_device = isci_dev_from_domain_dev(
  398. domain_dev);
  399. dev_err(&isci_device->isci_port->isci_host->pdev->dev,
  400. "%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
  401. __func__, domain_dev, isci_device, isci_device->isci_port);
  402. if (isci_device != NULL)
  403. isci_remote_device_stop(isci_device);
  404. }
  405. /**
  406. * isci_remote_device_found() - This function is called by libsas when a remote
  407. * device is discovered. A remote device object is created and started. the
  408. * function then sleeps until the sci core device started message is
  409. * received.
  410. * @domain_device: This parameter specifies the libsas domain device.
  411. *
  412. * status, zero indicates success.
  413. */
  414. int isci_remote_device_found(struct domain_device *domain_dev)
  415. {
  416. unsigned long flags;
  417. struct isci_host *isci_host;
  418. struct isci_port *isci_port;
  419. struct isci_phy *isci_phy;
  420. struct asd_sas_port *sas_port;
  421. struct asd_sas_phy *sas_phy;
  422. struct isci_remote_device *isci_device;
  423. enum sci_status status;
  424. DECLARE_COMPLETION_ONSTACK(completion);
  425. isci_host = isci_host_from_sas_ha(domain_dev->port->ha);
  426. dev_dbg(&isci_host->pdev->dev,
  427. "%s: domain_device = %p\n", __func__, domain_dev);
  428. wait_for_start(isci_host);
  429. sas_port = domain_dev->port;
  430. sas_phy = list_first_entry(&sas_port->phy_list, struct asd_sas_phy,
  431. port_phy_el);
  432. isci_phy = to_isci_phy(sas_phy);
  433. isci_port = isci_phy->isci_port;
  434. /* we are being called for a device on this port,
  435. * so it has to come up eventually
  436. */
  437. wait_for_completion(&isci_port->start_complete);
  438. if ((isci_stopping == isci_port_get_state(isci_port)) ||
  439. (isci_stopped == isci_port_get_state(isci_port)))
  440. return -ENODEV;
  441. isci_device = isci_remote_device_alloc(isci_host, isci_port);
  442. INIT_LIST_HEAD(&isci_device->node);
  443. domain_dev->lldd_dev = isci_device;
  444. isci_device->domain_dev = domain_dev;
  445. isci_device->isci_port = isci_port;
  446. isci_remote_device_change_state(isci_device, isci_starting);
  447. spin_lock_irqsave(&isci_port->remote_device_lock, flags);
  448. list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
  449. /* for the device ready event. */
  450. isci_device->completion = &completion;
  451. status = isci_remote_device_construct(isci_port, isci_device);
  452. spin_unlock_irqrestore(&isci_port->remote_device_lock, flags);
  453. /* wait for the device ready callback. */
  454. wait_for_completion(isci_device->completion);
  455. isci_device->completion = NULL;
  456. dev_dbg(&isci_host->pdev->dev,
  457. "%s: isci_device = %p\n",
  458. __func__, isci_device);
  459. if (status != SCI_SUCCESS) {
  460. spin_lock_irqsave(&isci_port->remote_device_lock, flags);
  461. isci_remote_device_deconstruct(
  462. isci_host,
  463. isci_device
  464. );
  465. spin_unlock_irqrestore(&isci_port->remote_device_lock, flags);
  466. return -ENODEV;
  467. }
  468. return 0;
  469. }
  470. /**
  471. * isci_device_is_reset_pending() - This function will check if there is any
  472. * pending reset condition on the device.
  473. * @request: This parameter is the isci_device object.
  474. *
  475. * true if there is a reset pending for the device.
  476. */
  477. bool isci_device_is_reset_pending(
  478. struct isci_host *isci_host,
  479. struct isci_remote_device *isci_device)
  480. {
  481. struct isci_request *isci_request;
  482. struct isci_request *tmp_req;
  483. bool reset_is_pending = false;
  484. unsigned long flags;
  485. dev_dbg(&isci_host->pdev->dev,
  486. "%s: isci_device = %p\n", __func__, isci_device);
  487. spin_lock_irqsave(&isci_host->scic_lock, flags);
  488. /* Check for reset on all pending requests. */
  489. list_for_each_entry_safe(isci_request, tmp_req,
  490. &isci_device->reqs_in_process, dev_node) {
  491. dev_dbg(&isci_host->pdev->dev,
  492. "%s: isci_device = %p request = %p\n",
  493. __func__, isci_device, isci_request);
  494. if (isci_request->ttype == io_task) {
  495. unsigned long flags;
  496. struct sas_task *task = isci_request_access_task(
  497. isci_request);
  498. spin_lock_irqsave(&task->task_state_lock, flags);
  499. if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
  500. reset_is_pending = true;
  501. spin_unlock_irqrestore(&task->task_state_lock, flags);
  502. }
  503. }
  504. spin_unlock_irqrestore(&isci_host->scic_lock, flags);
  505. dev_dbg(&isci_host->pdev->dev,
  506. "%s: isci_device = %p reset_is_pending = %d\n",
  507. __func__, isci_device, reset_is_pending);
  508. return reset_is_pending;
  509. }
  510. /**
  511. * isci_device_clear_reset_pending() - This function will clear if any pending
  512. * reset condition flags on the device.
  513. * @request: This parameter is the isci_device object.
  514. *
  515. * true if there is a reset pending for the device.
  516. */
  517. void isci_device_clear_reset_pending(struct isci_remote_device *isci_device)
  518. {
  519. struct isci_request *isci_request;
  520. struct isci_request *tmp_req;
  521. struct isci_host *isci_host = NULL;
  522. unsigned long flags = 0;
  523. /* FIXME more port gone confusion, and this time it makes the
  524. * locking "fun"
  525. */
  526. if (isci_device->isci_port != NULL)
  527. isci_host = isci_device->isci_port->isci_host;
  528. /*
  529. * FIXME when the isci_host gets sorted out
  530. * use dev_dbg()
  531. */
  532. pr_debug("%s: isci_device=%p, isci_host=%p\n",
  533. __func__, isci_device, isci_host);
  534. if (isci_host != NULL)
  535. spin_lock_irqsave(&isci_host->scic_lock, flags);
  536. else
  537. pr_err("%s: isci_device %p; isci_host == NULL!\n",
  538. __func__, isci_device);
  539. /* Clear reset pending on all pending requests. */
  540. list_for_each_entry_safe(isci_request, tmp_req,
  541. &isci_device->reqs_in_process, dev_node) {
  542. /*
  543. * FIXME when the conditional spinlock is gone
  544. * change to dev_dbg()
  545. */
  546. pr_debug("%s: isci_device = %p request = %p\n",
  547. __func__, isci_device, isci_request);
  548. if (isci_request->ttype == io_task) {
  549. unsigned long flags2;
  550. struct sas_task *task = isci_request_access_task(
  551. isci_request);
  552. spin_lock_irqsave(&task->task_state_lock, flags2);
  553. task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
  554. spin_unlock_irqrestore(&task->task_state_lock, flags2);
  555. }
  556. }
  557. if (isci_host != NULL)
  558. spin_unlock_irqrestore(&isci_host->scic_lock, flags);
  559. }
  560. /**
  561. * isci_remote_device_change_state() - This function gets the status of the
  562. * remote_device object.
  563. * @isci_device: This parameter points to the isci_remote_device object
  564. *
  565. * status of the object as a isci_status enum.
  566. */
  567. void isci_remote_device_change_state(
  568. struct isci_remote_device *isci_device,
  569. enum isci_status status)
  570. {
  571. unsigned long flags;
  572. spin_lock_irqsave(&isci_device->state_lock, flags);
  573. isci_device->status = status;
  574. spin_unlock_irqrestore(&isci_device->state_lock, flags);
  575. }