host.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  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_port.h"
  59. #include "port.h"
  60. #include "request.h"
  61. #include "host.h"
  62. /**
  63. * isci_isr() - This function is the interrupt service routine for the
  64. * controller. It schedules the tasklet and returns.
  65. * @vec: This parameter specifies the interrupt vector.
  66. * @data: This parameter specifies the ISCI host object.
  67. *
  68. * IRQ_HANDLED if out interrupt otherwise, IRQ_NONE
  69. */
  70. irqreturn_t isci_isr(int vec, void *data)
  71. {
  72. struct isci_host *isci_host
  73. = (struct isci_host *)data;
  74. struct scic_controller_handler_methods *handlers
  75. = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
  76. irqreturn_t ret = IRQ_NONE;
  77. if (isci_host_get_state(isci_host) != isci_starting
  78. && handlers->interrupt_handler) {
  79. if (handlers->interrupt_handler(isci_host->core_controller)) {
  80. if (isci_host_get_state(isci_host) != isci_stopped) {
  81. tasklet_schedule(
  82. &isci_host->completion_tasklet);
  83. } else
  84. dev_dbg(&isci_host->pdev->dev,
  85. "%s: controller stopped\n",
  86. __func__);
  87. ret = IRQ_HANDLED;
  88. }
  89. } else
  90. dev_warn(&isci_host->pdev->dev,
  91. "%s: get_handler_methods failed, "
  92. "isci_host->status = 0x%x\n",
  93. __func__,
  94. isci_host_get_state(isci_host));
  95. return ret;
  96. }
  97. irqreturn_t isci_legacy_isr(int vec, void *data)
  98. {
  99. struct pci_dev *pdev = data;
  100. struct isci_host *isci_host;
  101. struct scic_controller_handler_methods *handlers;
  102. irqreturn_t ret = IRQ_NONE;
  103. /*
  104. * Since this is a legacy interrupt, either or both
  105. * controllers could have triggered it. Thus, we have to call
  106. * the legacy interrupt handler for all controllers on the
  107. * PCI function.
  108. */
  109. for_each_isci_host(isci_host, pdev) {
  110. handlers = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
  111. if (isci_host_get_state(isci_host) != isci_starting
  112. && handlers->interrupt_handler) {
  113. if (handlers->interrupt_handler(isci_host->core_controller)) {
  114. if (isci_host_get_state(isci_host) != isci_stopped) {
  115. tasklet_schedule(
  116. &isci_host->completion_tasklet);
  117. } else
  118. dev_dbg(&isci_host->pdev->dev,
  119. "%s: controller stopped\n",
  120. __func__);
  121. ret = IRQ_HANDLED;
  122. }
  123. } else
  124. dev_warn(&isci_host->pdev->dev,
  125. "%s: get_handler_methods failed, "
  126. "isci_host->status = 0x%x\n",
  127. __func__,
  128. isci_host_get_state(isci_host));
  129. }
  130. return ret;
  131. }
  132. /**
  133. * isci_host_start_complete() - This function is called by the core library,
  134. * through the ISCI Module, to indicate controller start status.
  135. * @isci_host: This parameter specifies the ISCI host object
  136. * @completion_status: This parameter specifies the completion status from the
  137. * core library.
  138. *
  139. */
  140. void isci_host_start_complete(
  141. struct isci_host *isci_host,
  142. enum sci_status completion_status)
  143. {
  144. if (completion_status == SCI_SUCCESS) {
  145. dev_dbg(&isci_host->pdev->dev,
  146. "%s: completion_status: SCI_SUCCESS\n", __func__);
  147. isci_host_change_state(isci_host, isci_ready);
  148. complete_all(&isci_host->start_complete);
  149. } else
  150. dev_err(&isci_host->pdev->dev,
  151. "controller start failed with "
  152. "completion_status = 0x%x;",
  153. completion_status);
  154. }
  155. /**
  156. * isci_host_scan_finished() - This function is one of the SCSI Host Template
  157. * functions. The SCSI midlayer calls this function during a target scan,
  158. * approx. once every 10 millisecs.
  159. * @shost: This parameter specifies the SCSI host being scanned
  160. * @time: This parameter specifies the number of ticks since the scan started.
  161. *
  162. * scan status, zero indicates the SCSI midlayer should continue to poll,
  163. * otherwise assume controller is ready.
  164. */
  165. int isci_host_scan_finished(
  166. struct Scsi_Host *shost,
  167. unsigned long time)
  168. {
  169. struct isci_host *isci_host
  170. = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost));
  171. struct scic_controller_handler_methods *handlers
  172. = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
  173. if (handlers->interrupt_handler == NULL) {
  174. dev_err(&isci_host->pdev->dev,
  175. "%s: scic_controller_get_handler_methods failed\n",
  176. __func__);
  177. return 1;
  178. }
  179. /**
  180. * check interrupt_handler's status and call completion_handler if true,
  181. * link_up events should be coming from the scu core lib, as phy's come
  182. * online. for each link_up from the core, call
  183. * get_received_identify_address_frame, copy the frame into the
  184. * sas_phy object and call libsas notify_port_event(PORTE_BYTES_DMAED).
  185. * continue to return zero from thee scan_finished routine until
  186. * the scic_cb_controller_start_complete() call comes from the core.
  187. **/
  188. if (handlers->interrupt_handler(isci_host->core_controller))
  189. handlers->completion_handler(isci_host->core_controller);
  190. if (isci_starting == isci_host_get_state(isci_host)
  191. && time < (HZ * 10)) {
  192. dev_dbg(&isci_host->pdev->dev,
  193. "%s: isci_host->status = %d, time = %ld\n",
  194. __func__, isci_host_get_state(isci_host), time);
  195. return 0;
  196. }
  197. dev_dbg(&isci_host->pdev->dev,
  198. "%s: isci_host->status = %d, time = %ld\n",
  199. __func__, isci_host_get_state(isci_host), time);
  200. scic_controller_enable_interrupts(isci_host->core_controller);
  201. return 1;
  202. }
  203. /**
  204. * isci_host_scan_start() - This function is one of the SCSI Host Template
  205. * function, called by the SCSI mid layer berfore a target scan begins. The
  206. * core library controller start routine is called from here.
  207. * @shost: This parameter specifies the SCSI host to be scanned
  208. *
  209. */
  210. void isci_host_scan_start(struct Scsi_Host *shost)
  211. {
  212. struct isci_host *isci_host;
  213. isci_host = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost));
  214. isci_host_change_state(isci_host, isci_starting);
  215. scic_controller_disable_interrupts(isci_host->core_controller);
  216. init_completion(&isci_host->start_complete);
  217. scic_controller_start(
  218. isci_host->core_controller,
  219. scic_controller_get_suggested_start_timeout(
  220. isci_host->core_controller)
  221. );
  222. }
  223. void isci_host_stop_complete(
  224. struct isci_host *isci_host,
  225. enum sci_status completion_status)
  226. {
  227. isci_host_change_state(isci_host, isci_stopped);
  228. scic_controller_disable_interrupts(
  229. isci_host->core_controller
  230. );
  231. complete(&isci_host->stop_complete);
  232. }
  233. static struct coherent_memory_info *isci_host_alloc_mdl_struct(
  234. struct isci_host *isci_host,
  235. u32 size)
  236. {
  237. struct coherent_memory_info *mdl_struct;
  238. void *uncached_address = NULL;
  239. mdl_struct = devm_kzalloc(&isci_host->pdev->dev,
  240. sizeof(*mdl_struct),
  241. GFP_KERNEL);
  242. if (!mdl_struct)
  243. return NULL;
  244. INIT_LIST_HEAD(&mdl_struct->node);
  245. uncached_address = dmam_alloc_coherent(&isci_host->pdev->dev,
  246. size,
  247. &mdl_struct->dma_handle,
  248. GFP_KERNEL);
  249. if (!uncached_address)
  250. return NULL;
  251. /* memset the whole memory area. */
  252. memset((char *)uncached_address, 0, size);
  253. mdl_struct->vaddr = uncached_address;
  254. mdl_struct->size = (size_t)size;
  255. return mdl_struct;
  256. }
  257. static void isci_host_build_mde(
  258. struct sci_physical_memory_descriptor *mde_struct,
  259. struct coherent_memory_info *mdl_struct)
  260. {
  261. unsigned long address = 0;
  262. dma_addr_t dma_addr = 0;
  263. address = (unsigned long)mdl_struct->vaddr;
  264. dma_addr = mdl_struct->dma_handle;
  265. /* to satisfy the alignment. */
  266. if ((address % mde_struct->constant_memory_alignment) != 0) {
  267. int align_offset
  268. = (mde_struct->constant_memory_alignment
  269. - (address % mde_struct->constant_memory_alignment));
  270. address += align_offset;
  271. dma_addr += align_offset;
  272. }
  273. mde_struct->virtual_address = (void *)address;
  274. mde_struct->physical_address = dma_addr;
  275. mdl_struct->mde = mde_struct;
  276. }
  277. static int isci_host_mdl_allocate_coherent(
  278. struct isci_host *isci_host)
  279. {
  280. struct sci_physical_memory_descriptor *current_mde;
  281. struct coherent_memory_info *mdl_struct;
  282. u32 size = 0;
  283. struct sci_base_memory_descriptor_list *mdl_handle
  284. = sci_controller_get_memory_descriptor_list_handle(
  285. isci_host->core_controller);
  286. sci_mdl_first_entry(mdl_handle);
  287. current_mde = sci_mdl_get_current_entry(mdl_handle);
  288. while (current_mde != NULL) {
  289. size = (current_mde->constant_memory_size
  290. + current_mde->constant_memory_alignment);
  291. mdl_struct = isci_host_alloc_mdl_struct(isci_host, size);
  292. if (!mdl_struct)
  293. return -ENOMEM;
  294. list_add_tail(&mdl_struct->node, &isci_host->mdl_struct_list);
  295. isci_host_build_mde(current_mde, mdl_struct);
  296. sci_mdl_next_entry(mdl_handle);
  297. current_mde = sci_mdl_get_current_entry(mdl_handle);
  298. }
  299. return 0;
  300. }
  301. /**
  302. * isci_host_completion_routine() - This function is the delayed service
  303. * routine that calls the sci core library's completion handler. It's
  304. * scheduled as a tasklet from the interrupt service routine when interrupts
  305. * in use, or set as the timeout function in polled mode.
  306. * @data: This parameter specifies the ISCI host object
  307. *
  308. */
  309. static void isci_host_completion_routine(unsigned long data)
  310. {
  311. struct isci_host *isci_host = (struct isci_host *)data;
  312. struct scic_controller_handler_methods *handlers
  313. = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
  314. struct list_head completed_request_list;
  315. struct list_head aborted_request_list;
  316. struct list_head *current_position;
  317. struct list_head *next_position;
  318. struct isci_request *request;
  319. struct isci_request *next_request;
  320. struct sas_task *task;
  321. INIT_LIST_HEAD(&completed_request_list);
  322. INIT_LIST_HEAD(&aborted_request_list);
  323. spin_lock_irq(&isci_host->scic_lock);
  324. if (handlers->completion_handler) {
  325. handlers->completion_handler(
  326. isci_host->core_controller
  327. );
  328. }
  329. /* Take the lists of completed I/Os from the host. */
  330. list_splice_init(&isci_host->requests_to_complete,
  331. &completed_request_list);
  332. list_splice_init(&isci_host->requests_to_abort,
  333. &aborted_request_list);
  334. spin_unlock_irq(&isci_host->scic_lock);
  335. /* Process any completions in the lists. */
  336. list_for_each_safe(current_position, next_position,
  337. &completed_request_list) {
  338. request = list_entry(current_position, struct isci_request,
  339. completed_node);
  340. task = isci_request_access_task(request);
  341. /* Normal notification (task_done) */
  342. dev_dbg(&isci_host->pdev->dev,
  343. "%s: Normal - request/task = %p/%p\n",
  344. __func__,
  345. request,
  346. task);
  347. task->task_done(task);
  348. task->lldd_task = NULL;
  349. /* Free the request object. */
  350. isci_request_free(isci_host, request);
  351. }
  352. list_for_each_entry_safe(request, next_request, &aborted_request_list,
  353. completed_node) {
  354. task = isci_request_access_task(request);
  355. /* Use sas_task_abort */
  356. dev_warn(&isci_host->pdev->dev,
  357. "%s: Error - request/task = %p/%p\n",
  358. __func__,
  359. request,
  360. task);
  361. /* Put the task into the abort path. */
  362. sas_task_abort(task);
  363. }
  364. }
  365. void isci_host_deinit(
  366. struct isci_host *isci_host)
  367. {
  368. int i;
  369. isci_host_change_state(isci_host, isci_stopping);
  370. for (i = 0; i < SCI_MAX_PORTS; i++) {
  371. struct isci_port *port = &isci_host->isci_ports[i];
  372. struct isci_remote_device *device, *tmpdev;
  373. list_for_each_entry_safe(device, tmpdev,
  374. &port->remote_dev_list, node) {
  375. isci_remote_device_change_state(device, isci_stopping);
  376. isci_remote_device_stop(device);
  377. }
  378. }
  379. /* stop the comtroller and wait for completion. */
  380. init_completion(&isci_host->stop_complete);
  381. scic_controller_stop(
  382. isci_host->core_controller,
  383. SCIC_CONTROLLER_STOP_TIMEOUT
  384. );
  385. wait_for_completion(&isci_host->stop_complete);
  386. /* next, reset the controller. */
  387. scic_controller_reset(isci_host->core_controller);
  388. }
  389. static int isci_verify_firmware(const struct firmware *fw,
  390. struct isci_firmware *isci_fw)
  391. {
  392. const u8 *tmp;
  393. if (fw->size < ISCI_FIRMWARE_MIN_SIZE)
  394. return -EINVAL;
  395. tmp = fw->data;
  396. /* 12th char should be the NULL terminate for the ID string */
  397. if (tmp[11] != '\0')
  398. return -EINVAL;
  399. if (strncmp("#SCU MAGIC#", tmp, 11) != 0)
  400. return -EINVAL;
  401. isci_fw->id = tmp;
  402. isci_fw->version = fw->data[ISCI_FW_VER_OFS];
  403. isci_fw->subversion = fw->data[ISCI_FW_SUBVER_OFS];
  404. tmp = fw->data + ISCI_FW_DATA_OFS;
  405. while (*tmp != ISCI_FW_HDR_EOF) {
  406. switch (*tmp) {
  407. case ISCI_FW_HDR_PHYMASK:
  408. tmp++;
  409. isci_fw->phy_masks_size = *tmp;
  410. tmp++;
  411. isci_fw->phy_masks = (const u32 *)tmp;
  412. tmp += sizeof(u32) * isci_fw->phy_masks_size;
  413. break;
  414. case ISCI_FW_HDR_PHYGEN:
  415. tmp++;
  416. isci_fw->phy_gens_size = *tmp;
  417. tmp++;
  418. isci_fw->phy_gens = (const u32 *)tmp;
  419. tmp += sizeof(u32) * isci_fw->phy_gens_size;
  420. break;
  421. case ISCI_FW_HDR_SASADDR:
  422. tmp++;
  423. isci_fw->sas_addrs_size = *tmp;
  424. tmp++;
  425. isci_fw->sas_addrs = (const u64 *)tmp;
  426. tmp += sizeof(u64) * isci_fw->sas_addrs_size;
  427. break;
  428. default:
  429. pr_err("bad field in firmware binary blob\n");
  430. return -EINVAL;
  431. }
  432. }
  433. pr_info("isci firmware v%u.%u loaded.\n",
  434. isci_fw->version, isci_fw->subversion);
  435. return SCI_SUCCESS;
  436. }
  437. static void __iomem *scu_base(struct isci_host *isci_host)
  438. {
  439. struct pci_dev *pdev = isci_host->pdev;
  440. int id = isci_host->id;
  441. return pcim_iomap_table(pdev)[SCI_SCU_BAR * 2] + SCI_SCU_BAR_SIZE * id;
  442. }
  443. static void __iomem *smu_base(struct isci_host *isci_host)
  444. {
  445. struct pci_dev *pdev = isci_host->pdev;
  446. int id = isci_host->id;
  447. return pcim_iomap_table(pdev)[SCI_SMU_BAR * 2] + SCI_SMU_BAR_SIZE * id;
  448. }
  449. #define SCI_MAX_TIMER_COUNT 25
  450. int isci_host_init(struct isci_host *isci_host)
  451. {
  452. int err = 0;
  453. int index = 0;
  454. enum sci_status status;
  455. struct scic_sds_controller *controller;
  456. struct scic_sds_port *scic_port;
  457. struct scic_controller_handler_methods *handlers
  458. = &isci_host->scic_irq_handlers[0];
  459. union scic_oem_parameters scic_oem_params;
  460. union scic_user_parameters scic_user_params;
  461. const struct firmware *fw = NULL;
  462. struct isci_firmware *isci_fw = NULL;
  463. INIT_LIST_HEAD(&isci_host->timer_list_struct.timers);
  464. isci_timer_list_construct(
  465. &isci_host->timer_list_struct,
  466. SCI_MAX_TIMER_COUNT
  467. );
  468. controller = scic_controller_alloc(&isci_host->pdev->dev);
  469. if (!controller) {
  470. err = -ENOMEM;
  471. dev_err(&isci_host->pdev->dev, "%s: failed (%d)\n", __func__, err);
  472. goto out;
  473. }
  474. isci_host->core_controller = controller;
  475. spin_lock_init(&isci_host->state_lock);
  476. spin_lock_init(&isci_host->scic_lock);
  477. spin_lock_init(&isci_host->queue_lock);
  478. isci_host_change_state(isci_host, isci_starting);
  479. isci_host->can_queue = ISCI_CAN_QUEUE_VAL;
  480. status = scic_controller_construct(controller, scu_base(isci_host),
  481. smu_base(isci_host));
  482. if (status != SCI_SUCCESS) {
  483. dev_err(&isci_host->pdev->dev,
  484. "%s: scic_controller_construct failed - status = %x\n",
  485. __func__,
  486. status);
  487. err = -ENODEV;
  488. goto out;
  489. }
  490. isci_host->sas_ha.dev = &isci_host->pdev->dev;
  491. isci_host->sas_ha.lldd_ha = isci_host;
  492. /*----------- SCIC controller Initialization Stuff ------------------
  493. * set association host adapter struct in core controller.
  494. */
  495. sci_object_set_association(isci_host->core_controller,
  496. (void *)isci_host
  497. );
  498. /* grab initial values stored in the controller object for OEM and USER
  499. * parameters */
  500. scic_oem_parameters_get(controller, &scic_oem_params);
  501. scic_user_parameters_get(controller, &scic_user_params);
  502. isci_fw = devm_kzalloc(&isci_host->pdev->dev,
  503. sizeof(struct isci_firmware),
  504. GFP_KERNEL);
  505. if (!isci_fw) {
  506. dev_warn(&isci_host->pdev->dev,
  507. "allocating firmware struct failed\n");
  508. dev_warn(&isci_host->pdev->dev,
  509. "Default OEM configuration being used:"
  510. " 4 narrow ports, and default SAS Addresses\n");
  511. goto set_default_params;
  512. }
  513. status = request_firmware(&fw, ISCI_FW_NAME, &isci_host->pdev->dev);
  514. if (status) {
  515. dev_warn(&isci_host->pdev->dev,
  516. "Loading firmware failed, using default values\n");
  517. dev_warn(&isci_host->pdev->dev,
  518. "Default OEM configuration being used:"
  519. " 4 narrow ports, and default SAS Addresses\n");
  520. goto set_default_params;
  521. }
  522. else {
  523. status = isci_verify_firmware(fw, isci_fw);
  524. if (status != SCI_SUCCESS) {
  525. dev_warn(&isci_host->pdev->dev,
  526. "firmware verification failed\n");
  527. dev_warn(&isci_host->pdev->dev,
  528. "Default OEM configuration being used:"
  529. " 4 narrow ports, and default SAS "
  530. "Addresses\n");
  531. goto set_default_params;
  532. }
  533. /* grab any OEM and USER parameters specified at module load */
  534. status = isci_parse_oem_parameters(&scic_oem_params,
  535. isci_host->id, isci_fw);
  536. if (status != SCI_SUCCESS) {
  537. dev_warn(&isci_host->pdev->dev,
  538. "parsing firmware oem parameters failed\n");
  539. err = -EINVAL;
  540. goto out;
  541. }
  542. status = isci_parse_user_parameters(&scic_user_params,
  543. isci_host->id, isci_fw);
  544. if (status != SCI_SUCCESS) {
  545. dev_warn(&isci_host->pdev->dev,
  546. "%s: isci_parse_user_parameters"
  547. " failed\n", __func__);
  548. err = -EINVAL;
  549. goto out;
  550. }
  551. }
  552. set_default_params:
  553. status = scic_oem_parameters_set(isci_host->core_controller,
  554. &scic_oem_params
  555. );
  556. if (status != SCI_SUCCESS) {
  557. dev_warn(&isci_host->pdev->dev,
  558. "%s: scic_oem_parameters_set failed\n",
  559. __func__);
  560. err = -ENODEV;
  561. goto out;
  562. }
  563. status = scic_user_parameters_set(isci_host->core_controller,
  564. &scic_user_params
  565. );
  566. if (status != SCI_SUCCESS) {
  567. dev_warn(&isci_host->pdev->dev,
  568. "%s: scic_user_parameters_set failed\n",
  569. __func__);
  570. err = -ENODEV;
  571. goto out;
  572. }
  573. status = scic_controller_initialize(isci_host->core_controller);
  574. if (status != SCI_SUCCESS) {
  575. dev_warn(&isci_host->pdev->dev,
  576. "%s: scic_controller_initialize failed -"
  577. " status = 0x%x\n",
  578. __func__, status);
  579. err = -ENODEV;
  580. goto out;
  581. }
  582. /* @todo: use both MSI-X interrupts, and don't do indirect
  583. * calls to the handlers just register direct calls
  584. */
  585. if (isci_host->pdev->msix_enabled) {
  586. status = scic_controller_get_handler_methods(
  587. SCIC_MSIX_INTERRUPT_TYPE,
  588. SCI_MSIX_DOUBLE_VECTOR,
  589. handlers
  590. );
  591. } else {
  592. status = scic_controller_get_handler_methods(
  593. SCIC_LEGACY_LINE_INTERRUPT_TYPE,
  594. 0,
  595. handlers
  596. );
  597. }
  598. if (status != SCI_SUCCESS) {
  599. handlers->interrupt_handler = NULL;
  600. handlers->completion_handler = NULL;
  601. dev_err(&isci_host->pdev->dev,
  602. "%s: scic_controller_get_handler_methods failed\n",
  603. __func__);
  604. }
  605. tasklet_init(&isci_host->completion_tasklet,
  606. isci_host_completion_routine,
  607. (unsigned long)isci_host
  608. );
  609. INIT_LIST_HEAD(&(isci_host->mdl_struct_list));
  610. INIT_LIST_HEAD(&isci_host->requests_to_complete);
  611. INIT_LIST_HEAD(&isci_host->requests_to_abort);
  612. /* populate mdl with dma memory. scu_mdl_allocate_coherent() */
  613. err = isci_host_mdl_allocate_coherent(isci_host);
  614. if (err)
  615. goto err_out;
  616. /*
  617. * keep the pool alloc size around, will use it for a bounds checking
  618. * when trying to convert virtual addresses to physical addresses
  619. */
  620. isci_host->dma_pool_alloc_size = sizeof(struct isci_request) +
  621. scic_io_request_get_object_size();
  622. isci_host->dma_pool = dmam_pool_create(DRV_NAME, &isci_host->pdev->dev,
  623. isci_host->dma_pool_alloc_size,
  624. SLAB_HWCACHE_ALIGN, 0);
  625. if (!isci_host->dma_pool) {
  626. err = -ENOMEM;
  627. goto req_obj_err_out;
  628. }
  629. for (index = 0; index < SCI_MAX_PORTS; index++) {
  630. isci_port_init(&isci_host->isci_ports[index],
  631. isci_host, index);
  632. }
  633. for (index = 0; index < SCI_MAX_PHYS; index++)
  634. isci_phy_init(&isci_host->phys[index], isci_host, index);
  635. /* Why are we doing this? Is this even necessary? */
  636. memcpy(&isci_host->sas_addr[0], &isci_host->phys[0].sas_addr[0],
  637. SAS_ADDR_SIZE);
  638. /* Start the ports */
  639. for (index = 0; index < SCI_MAX_PORTS; index++) {
  640. scic_controller_get_port_handle(controller, index, &scic_port);
  641. scic_port_start(scic_port);
  642. }
  643. goto out;
  644. /* SPB_Debug: destroy request object cache */
  645. req_obj_err_out:
  646. /* SPB_Debug: destroy remote object cache */
  647. err_out:
  648. /* SPB_Debug: undo controller init, construct and alloc, remove from parent
  649. * controller list. */
  650. out:
  651. if (fw)
  652. release_firmware(fw);
  653. return err;
  654. }