mic_intr.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /*
  2. * Intel MIC Platform Software Stack (MPSS)
  3. *
  4. * Copyright(c) 2013 Intel Corporation.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License, version 2, as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * The full GNU General Public License is included in this distribution in
  16. * the file called "COPYING".
  17. *
  18. * Intel MIC Host driver.
  19. *
  20. */
  21. #include <linux/pci.h>
  22. #include <linux/interrupt.h>
  23. #include "../common/mic_dev.h"
  24. #include "mic_device.h"
  25. /*
  26. * mic_invoke_callback - Invoke callback functions registered for
  27. * the corresponding source id.
  28. *
  29. * @mdev: pointer to the mic_device instance
  30. * @idx: The interrupt source id.
  31. *
  32. * Returns none.
  33. */
  34. static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
  35. {
  36. struct mic_intr_cb *intr_cb;
  37. struct pci_dev *pdev = container_of(mdev->sdev->parent,
  38. struct pci_dev, dev);
  39. spin_lock(&mdev->irq_info.mic_intr_lock);
  40. list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list)
  41. if (intr_cb->func)
  42. intr_cb->func(pdev->irq, intr_cb->data);
  43. spin_unlock(&mdev->irq_info.mic_intr_lock);
  44. }
  45. /**
  46. * mic_interrupt - Generic interrupt handler for
  47. * MSI and INTx based interrupts.
  48. */
  49. static irqreturn_t mic_interrupt(int irq, void *dev)
  50. {
  51. struct mic_device *mdev = dev;
  52. struct mic_intr_info *info = mdev->intr_info;
  53. u32 mask;
  54. int i;
  55. mask = mdev->ops->ack_interrupt(mdev);
  56. if (!mask)
  57. return IRQ_NONE;
  58. for (i = info->intr_start_idx[MIC_INTR_DB];
  59. i < info->intr_len[MIC_INTR_DB]; i++)
  60. if (mask & BIT(i))
  61. mic_invoke_callback(mdev, i);
  62. return IRQ_HANDLED;
  63. }
  64. /* Return the interrupt offset from the index. Index is 0 based. */
  65. static u16 mic_map_src_to_offset(struct mic_device *mdev,
  66. int intr_src, enum mic_intr_type type) {
  67. if (type >= MIC_NUM_INTR_TYPES)
  68. return MIC_NUM_OFFSETS;
  69. if (intr_src >= mdev->intr_info->intr_len[type])
  70. return MIC_NUM_OFFSETS;
  71. return mdev->intr_info->intr_start_idx[type] + intr_src;
  72. }
  73. /* Return next available msix_entry. */
  74. static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
  75. {
  76. int i;
  77. struct mic_irq_info *info = &mdev->irq_info;
  78. for (i = 0; i < info->num_vectors; i++)
  79. if (!info->mic_msi_map[i])
  80. return &info->msix_entries[i];
  81. return NULL;
  82. }
  83. /**
  84. * mic_register_intr_callback - Register a callback handler for the
  85. * given source id.
  86. *
  87. * @mdev: pointer to the mic_device instance
  88. * @idx: The source id to be registered.
  89. * @func: The function to be called when the source id receives
  90. * the interrupt.
  91. * @data: Private data of the requester.
  92. * Return the callback structure that was registered or an
  93. * appropriate error on failure.
  94. */
  95. static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
  96. u8 idx, irqreturn_t (*func) (int irq, void *dev),
  97. void *data)
  98. {
  99. struct mic_intr_cb *intr_cb;
  100. unsigned long flags;
  101. int rc;
  102. intr_cb = kmalloc(sizeof(struct mic_intr_cb), GFP_KERNEL);
  103. if (!intr_cb)
  104. return ERR_PTR(-ENOMEM);
  105. intr_cb->func = func;
  106. intr_cb->data = data;
  107. intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
  108. 0, 0, GFP_KERNEL);
  109. if (intr_cb->cb_id < 0) {
  110. rc = intr_cb->cb_id;
  111. goto ida_fail;
  112. }
  113. spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
  114. list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
  115. spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
  116. return intr_cb;
  117. ida_fail:
  118. kfree(intr_cb);
  119. return ERR_PTR(rc);
  120. }
  121. /**
  122. * mic_unregister_intr_callback - Unregister the callback handler
  123. * identified by its callback id.
  124. *
  125. * @mdev: pointer to the mic_device instance
  126. * @idx: The callback structure id to be unregistered.
  127. * Return the source id that was unregistered or MIC_NUM_OFFSETS if no
  128. * such callback handler was found.
  129. */
  130. static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
  131. {
  132. struct list_head *pos, *tmp;
  133. struct mic_intr_cb *intr_cb;
  134. unsigned long flags;
  135. int i;
  136. for (i = 0; i < MIC_NUM_OFFSETS; i++) {
  137. spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
  138. list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
  139. intr_cb = list_entry(pos, struct mic_intr_cb, list);
  140. if (intr_cb->cb_id == idx) {
  141. list_del(pos);
  142. ida_simple_remove(&mdev->irq_info.cb_ida,
  143. intr_cb->cb_id);
  144. kfree(intr_cb);
  145. spin_unlock_irqrestore(
  146. &mdev->irq_info.mic_intr_lock, flags);
  147. return i;
  148. }
  149. }
  150. spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
  151. }
  152. return MIC_NUM_OFFSETS;
  153. }
  154. /**
  155. * mic_setup_msix - Initializes MSIx interrupts.
  156. *
  157. * @mdev: pointer to mic_device instance
  158. *
  159. *
  160. * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  161. */
  162. static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev)
  163. {
  164. int rc, i;
  165. mdev->irq_info.msix_entries = kmalloc(sizeof(struct msix_entry) *
  166. MIC_MIN_MSIX, GFP_KERNEL);
  167. if (!mdev->irq_info.msix_entries) {
  168. rc = -ENOMEM;
  169. goto err_nomem1;
  170. }
  171. for (i = 0; i < MIC_MIN_MSIX; i++)
  172. mdev->irq_info.msix_entries[i].entry = i;
  173. rc = pci_enable_msix(pdev, mdev->irq_info.msix_entries,
  174. MIC_MIN_MSIX);
  175. if (rc) {
  176. dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
  177. goto err_enable_msix;
  178. }
  179. mdev->irq_info.num_vectors = MIC_MIN_MSIX;
  180. mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
  181. mdev->irq_info.num_vectors), GFP_KERNEL);
  182. if (!mdev->irq_info.mic_msi_map) {
  183. rc = -ENOMEM;
  184. goto err_nomem2;
  185. }
  186. dev_dbg(mdev->sdev->parent,
  187. "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
  188. return 0;
  189. err_nomem2:
  190. pci_disable_msix(pdev);
  191. err_enable_msix:
  192. kfree(mdev->irq_info.msix_entries);
  193. err_nomem1:
  194. mdev->irq_info.num_vectors = 0;
  195. return rc;
  196. }
  197. /**
  198. * mic_setup_callbacks - Initialize data structures needed
  199. * to handle callbacks.
  200. *
  201. * @mdev: pointer to mic_device instance
  202. */
  203. static int mic_setup_callbacks(struct mic_device *mdev)
  204. {
  205. int i;
  206. mdev->irq_info.cb_list = kmalloc(sizeof(struct list_head) *
  207. MIC_NUM_OFFSETS, GFP_KERNEL);
  208. if (!mdev->irq_info.cb_list)
  209. return -ENOMEM;
  210. for (i = 0; i < MIC_NUM_OFFSETS; i++)
  211. INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
  212. ida_init(&mdev->irq_info.cb_ida);
  213. spin_lock_init(&mdev->irq_info.mic_intr_lock);
  214. return 0;
  215. }
  216. /**
  217. * mic_release_callbacks - Uninitialize data structures needed
  218. * to handle callbacks.
  219. *
  220. * @mdev: pointer to mic_device instance
  221. */
  222. static void mic_release_callbacks(struct mic_device *mdev)
  223. {
  224. unsigned long flags;
  225. struct list_head *pos, *tmp;
  226. struct mic_intr_cb *intr_cb;
  227. int i;
  228. for (i = 0; i < MIC_NUM_OFFSETS; i++) {
  229. spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
  230. if (list_empty(&mdev->irq_info.cb_list[i])) {
  231. spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
  232. flags);
  233. break;
  234. }
  235. list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
  236. intr_cb = list_entry(pos, struct mic_intr_cb, list);
  237. list_del(pos);
  238. ida_simple_remove(&mdev->irq_info.cb_ida,
  239. intr_cb->cb_id);
  240. kfree(intr_cb);
  241. }
  242. spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
  243. }
  244. ida_destroy(&mdev->irq_info.cb_ida);
  245. kfree(mdev->irq_info.cb_list);
  246. }
  247. /**
  248. * mic_setup_msi - Initializes MSI interrupts.
  249. *
  250. * @mdev: pointer to mic_device instance
  251. * @pdev: PCI device structure
  252. *
  253. * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  254. */
  255. static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
  256. {
  257. int rc;
  258. rc = pci_enable_msi(pdev);
  259. if (rc) {
  260. dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
  261. return rc;
  262. }
  263. mdev->irq_info.num_vectors = 1;
  264. mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
  265. mdev->irq_info.num_vectors), GFP_KERNEL);
  266. if (!mdev->irq_info.mic_msi_map) {
  267. rc = -ENOMEM;
  268. goto err_nomem1;
  269. }
  270. rc = mic_setup_callbacks(mdev);
  271. if (rc) {
  272. dev_err(&pdev->dev, "Error setting up callbacks\n");
  273. goto err_nomem2;
  274. }
  275. rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
  276. if (rc) {
  277. dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
  278. goto err_irq_req_fail;
  279. }
  280. dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
  281. return 0;
  282. err_irq_req_fail:
  283. mic_release_callbacks(mdev);
  284. err_nomem2:
  285. kfree(mdev->irq_info.mic_msi_map);
  286. err_nomem1:
  287. pci_disable_msi(pdev);
  288. mdev->irq_info.num_vectors = 0;
  289. return rc;
  290. }
  291. /**
  292. * mic_setup_intx - Initializes legacy interrupts.
  293. *
  294. * @mdev: pointer to mic_device instance
  295. * @pdev: PCI device structure
  296. *
  297. * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  298. */
  299. static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
  300. {
  301. int rc;
  302. pci_msi_off(pdev);
  303. /* Enable intx */
  304. pci_intx(pdev, 1);
  305. rc = mic_setup_callbacks(mdev);
  306. if (rc) {
  307. dev_err(&pdev->dev, "Error setting up callbacks\n");
  308. goto err_nomem;
  309. }
  310. rc = request_irq(pdev->irq, mic_interrupt,
  311. IRQF_SHARED, "mic-intx", mdev);
  312. if (rc)
  313. goto err;
  314. dev_dbg(&pdev->dev, "intx irq setup\n");
  315. return 0;
  316. err:
  317. mic_release_callbacks(mdev);
  318. err_nomem:
  319. return rc;
  320. }
  321. /**
  322. * mic_next_db - Retrieve the next doorbell interrupt source id.
  323. * The id is picked sequentially from the available pool of
  324. * doorlbell ids.
  325. *
  326. * @mdev: pointer to the mic_device instance.
  327. *
  328. * Returns the next doorbell interrupt source.
  329. */
  330. int mic_next_db(struct mic_device *mdev)
  331. {
  332. int next_db;
  333. next_db = mdev->irq_info.next_avail_src %
  334. mdev->intr_info->intr_len[MIC_INTR_DB];
  335. mdev->irq_info.next_avail_src++;
  336. return next_db;
  337. }
  338. #define COOKIE_ID_SHIFT 16
  339. #define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
  340. #define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
  341. #define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
  342. /**
  343. * mic_request_irq - request an irq. mic_mutex needs
  344. * to be held before calling this function.
  345. *
  346. * @mdev: pointer to mic_device instance
  347. * @func: The callback function that handles the interrupt.
  348. * The function needs to call ack_interrupts
  349. * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
  350. * @name: The ASCII name of the callee requesting the irq.
  351. * @data: private data that is returned back when calling the
  352. * function handler.
  353. * @intr_src: The source id of the requester. Its the doorbell id
  354. * for Doorbell interrupts and DMA channel id for DMA interrupts.
  355. * @type: The type of interrupt. Values defined in mic_intr_type
  356. *
  357. * returns: The cookie that is transparent to the caller. Passed
  358. * back when calling mic_free_irq. An appropriate error code
  359. * is returned on failure. Caller needs to use IS_ERR(return_val)
  360. * to check for failure and PTR_ERR(return_val) to obtained the
  361. * error code.
  362. *
  363. */
  364. struct mic_irq *mic_request_irq(struct mic_device *mdev,
  365. irqreturn_t (*func)(int irq, void *dev),
  366. const char *name, void *data, int intr_src,
  367. enum mic_intr_type type)
  368. {
  369. u16 offset;
  370. int rc = 0;
  371. struct msix_entry *msix = NULL;
  372. unsigned long cookie = 0;
  373. u16 entry;
  374. struct mic_intr_cb *intr_cb;
  375. struct pci_dev *pdev = container_of(mdev->sdev->parent,
  376. struct pci_dev, dev);
  377. offset = mic_map_src_to_offset(mdev, intr_src, type);
  378. if (offset >= MIC_NUM_OFFSETS) {
  379. dev_err(mdev->sdev->parent,
  380. "Error mapping index %d to a valid source id.\n",
  381. intr_src);
  382. rc = -EINVAL;
  383. goto err;
  384. }
  385. if (mdev->irq_info.num_vectors > 1) {
  386. msix = mic_get_available_vector(mdev);
  387. if (!msix) {
  388. dev_err(mdev->sdev->parent,
  389. "No MSIx vectors available for use.\n");
  390. rc = -ENOSPC;
  391. goto err;
  392. }
  393. rc = request_irq(msix->vector, func, 0, name, data);
  394. if (rc) {
  395. dev_dbg(mdev->sdev->parent,
  396. "request irq failed rc = %d\n", rc);
  397. goto err;
  398. }
  399. entry = msix->entry;
  400. mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
  401. mdev->intr_ops->program_msi_to_src_map(mdev,
  402. entry, offset, true);
  403. cookie = MK_COOKIE(entry, offset);
  404. dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
  405. msix->vector, intr_src);
  406. } else {
  407. intr_cb = mic_register_intr_callback(mdev,
  408. offset, func, data);
  409. if (IS_ERR(intr_cb)) {
  410. dev_err(mdev->sdev->parent,
  411. "No available callback entries for use\n");
  412. rc = PTR_ERR(intr_cb);
  413. goto err;
  414. }
  415. entry = 0;
  416. if (pci_dev_msi_enabled(pdev)) {
  417. mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
  418. mdev->intr_ops->program_msi_to_src_map(mdev,
  419. entry, offset, true);
  420. }
  421. cookie = MK_COOKIE(entry, intr_cb->cb_id);
  422. dev_dbg(mdev->sdev->parent, "callback %d registered for src: %d\n",
  423. intr_cb->cb_id, intr_src);
  424. }
  425. return (struct mic_irq *)cookie;
  426. err:
  427. return ERR_PTR(rc);
  428. }
  429. /**
  430. * mic_free_irq - free irq. mic_mutex
  431. * needs to be held before calling this function.
  432. *
  433. * @mdev: pointer to mic_device instance
  434. * @cookie: cookie obtained during a successful call to mic_request_irq
  435. * @data: private data specified by the calling function during the
  436. * mic_request_irq
  437. *
  438. * returns: none.
  439. */
  440. void mic_free_irq(struct mic_device *mdev,
  441. struct mic_irq *cookie, void *data)
  442. {
  443. u32 offset;
  444. u32 entry;
  445. u8 src_id;
  446. unsigned int irq;
  447. struct pci_dev *pdev = container_of(mdev->sdev->parent,
  448. struct pci_dev, dev);
  449. entry = GET_ENTRY((unsigned long)cookie);
  450. offset = GET_OFFSET((unsigned long)cookie);
  451. if (mdev->irq_info.num_vectors > 1) {
  452. if (entry >= mdev->irq_info.num_vectors) {
  453. dev_warn(mdev->sdev->parent,
  454. "entry %d should be < num_irq %d\n",
  455. entry, mdev->irq_info.num_vectors);
  456. return;
  457. }
  458. irq = mdev->irq_info.msix_entries[entry].vector;
  459. free_irq(irq, data);
  460. mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
  461. mdev->intr_ops->program_msi_to_src_map(mdev,
  462. entry, offset, false);
  463. dev_dbg(mdev->sdev->parent, "irq: %d freed\n", irq);
  464. } else {
  465. irq = pdev->irq;
  466. src_id = mic_unregister_intr_callback(mdev, offset);
  467. if (src_id >= MIC_NUM_OFFSETS) {
  468. dev_warn(mdev->sdev->parent, "Error unregistering callback\n");
  469. return;
  470. }
  471. if (pci_dev_msi_enabled(pdev)) {
  472. mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
  473. mdev->intr_ops->program_msi_to_src_map(mdev,
  474. entry, src_id, false);
  475. }
  476. dev_dbg(mdev->sdev->parent, "callback %d unregistered for src: %d\n",
  477. offset, src_id);
  478. }
  479. }
  480. /**
  481. * mic_setup_interrupts - Initializes interrupts.
  482. *
  483. * @mdev: pointer to mic_device instance
  484. * @pdev: PCI device structure
  485. *
  486. * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  487. */
  488. int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
  489. {
  490. int rc;
  491. rc = mic_setup_msix(mdev, pdev);
  492. if (!rc)
  493. goto done;
  494. rc = mic_setup_msi(mdev, pdev);
  495. if (!rc)
  496. goto done;
  497. rc = mic_setup_intx(mdev, pdev);
  498. if (rc) {
  499. dev_err(mdev->sdev->parent, "no usable interrupts\n");
  500. return rc;
  501. }
  502. done:
  503. mdev->intr_ops->enable_interrupts(mdev);
  504. return 0;
  505. }
  506. /**
  507. * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
  508. *
  509. * @mdev: pointer to mic_device instance
  510. * @pdev: PCI device structure
  511. *
  512. * returns none.
  513. */
  514. void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
  515. {
  516. int i;
  517. mdev->intr_ops->disable_interrupts(mdev);
  518. if (mdev->irq_info.num_vectors > 1) {
  519. for (i = 0; i < mdev->irq_info.num_vectors; i++) {
  520. if (mdev->irq_info.mic_msi_map[i])
  521. dev_warn(&pdev->dev, "irq %d may still be in use.\n",
  522. mdev->irq_info.msix_entries[i].vector);
  523. }
  524. kfree(mdev->irq_info.mic_msi_map);
  525. kfree(mdev->irq_info.msix_entries);
  526. pci_disable_msix(pdev);
  527. } else {
  528. if (pci_dev_msi_enabled(pdev)) {
  529. free_irq(pdev->irq, mdev);
  530. kfree(mdev->irq_info.mic_msi_map);
  531. pci_disable_msi(pdev);
  532. } else {
  533. free_irq(pdev->irq, mdev);
  534. }
  535. mic_release_callbacks(mdev);
  536. }
  537. }
  538. /**
  539. * mic_intr_restore - Restore MIC interrupt registers.
  540. *
  541. * @mdev: pointer to mic_device instance.
  542. *
  543. * Restore the interrupt registers to values previously
  544. * stored in the SW data structures. mic_mutex needs to
  545. * be held before calling this function.
  546. *
  547. * returns None.
  548. */
  549. void mic_intr_restore(struct mic_device *mdev)
  550. {
  551. int entry, offset;
  552. struct pci_dev *pdev = container_of(mdev->sdev->parent,
  553. struct pci_dev, dev);
  554. if (!pci_dev_msi_enabled(pdev))
  555. return;
  556. for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
  557. for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
  558. if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
  559. mdev->intr_ops->program_msi_to_src_map(mdev,
  560. entry, offset, true);
  561. }
  562. }
  563. }