probe.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-10-24 GuEe-GUI first version
  9. */
  10. #include <rtthread.h>
  11. #define DBG_TAG "pci.probe"
  12. #define DBG_LVL DBG_INFO
  13. #include <rtdbg.h>
  14. #include <drivers/pci.h>
  15. #include <drivers/core/bus.h>
  16. rt_inline void spin_lock(struct rt_spinlock *spinlock)
  17. {
  18. rt_hw_spin_lock(&spinlock->lock);
  19. }
  20. rt_inline void spin_unlock(struct rt_spinlock *spinlock)
  21. {
  22. rt_hw_spin_unlock(&spinlock->lock);
  23. }
  24. struct rt_pci_host_bridge *rt_pci_host_bridge_alloc(rt_size_t priv_size)
  25. {
  26. struct rt_pci_host_bridge *bridge = rt_calloc(1, sizeof(*bridge) + priv_size);
  27. return bridge;
  28. }
  29. rt_err_t rt_pci_host_bridge_free(struct rt_pci_host_bridge *bridge)
  30. {
  31. if (!bridge)
  32. {
  33. return -RT_EINVAL;
  34. }
  35. if (bridge->bus_regions)
  36. {
  37. rt_free(bridge->bus_regions);
  38. }
  39. if (bridge->dma_regions)
  40. {
  41. rt_free(bridge->dma_regions);
  42. }
  43. rt_free(bridge);
  44. return RT_EOK;
  45. }
  46. rt_err_t rt_pci_host_bridge_init(struct rt_pci_host_bridge *host_bridge)
  47. {
  48. rt_err_t err = RT_EOK;
  49. if (host_bridge->parent.ofw_node)
  50. {
  51. err = rt_pci_ofw_host_bridge_init(host_bridge->parent.ofw_node, host_bridge);
  52. }
  53. return err;
  54. }
  55. struct rt_pci_device *rt_pci_alloc_device(struct rt_pci_bus *bus)
  56. {
  57. struct rt_pci_device *pdev = rt_calloc(1, sizeof(*pdev));
  58. if (!pdev)
  59. {
  60. return RT_NULL;
  61. }
  62. rt_list_init(&pdev->list);
  63. pdev->bus = bus;
  64. if (bus)
  65. {
  66. spin_lock(&bus->lock);
  67. rt_list_insert_before(&bus->devices_nodes, &pdev->list);
  68. spin_unlock(&bus->lock);
  69. }
  70. pdev->subsystem_vendor = PCI_ANY_ID;
  71. pdev->subsystem_device = PCI_ANY_ID;
  72. pdev->irq = -1;
  73. for (int i = 0; i < RT_ARRAY_SIZE(pdev->resource); ++i)
  74. {
  75. pdev->resource[i].flags = PCI_BUS_REGION_F_NONE;
  76. }
  77. #ifdef RT_PCI_MSI
  78. rt_list_init(&pdev->msi_desc_nodes);
  79. rt_spin_lock_init(&pdev->msi_lock);
  80. #endif
  81. return pdev;
  82. }
  83. struct rt_pci_device *rt_pci_scan_single_device(struct rt_pci_bus *bus, rt_uint32_t devfn)
  84. {
  85. rt_err_t err;
  86. struct rt_pci_device *pdev = RT_NULL;
  87. rt_uint16_t vendor = PCI_ANY_ID, device = PCI_ANY_ID;
  88. if (!bus)
  89. {
  90. goto _end;
  91. }
  92. err = rt_pci_bus_read_config_u16(bus, devfn, PCIR_VENDOR, &vendor);
  93. rt_pci_bus_read_config_u16(bus, devfn, PCIR_DEVICE, &device);
  94. if (vendor == (typeof(vendor))PCI_ANY_ID ||
  95. vendor == (typeof(vendor))0x0000 || err)
  96. {
  97. goto _end;
  98. }
  99. if (!(pdev = rt_pci_alloc_device(bus)))
  100. {
  101. goto _end;
  102. }
  103. pdev->devfn = devfn;
  104. pdev->vendor = vendor;
  105. pdev->device = device;
  106. rt_dm_dev_set_name(&pdev->parent, "%04x:%02x:%02x.%u",
  107. rt_pci_domain(pdev), pdev->bus->number,
  108. RT_PCI_SLOT(pdev->devfn), RT_PCI_FUNC(pdev->devfn));
  109. if (rt_pci_setup_device(pdev))
  110. {
  111. rt_free(pdev);
  112. pdev = RT_NULL;
  113. goto _end;
  114. }
  115. rt_pci_device_register(pdev);
  116. _end:
  117. return pdev;
  118. }
  119. static rt_bool_t pci_intx_mask_broken(struct rt_pci_device *pdev)
  120. {
  121. rt_bool_t res = RT_FALSE;
  122. rt_uint16_t orig, toggle, new;
  123. rt_pci_read_config_u16(pdev, PCIR_COMMAND, &orig);
  124. toggle = orig ^ PCIM_CMD_INTxDIS;
  125. rt_pci_write_config_u16(pdev, PCIR_COMMAND, toggle);
  126. rt_pci_read_config_u16(pdev, PCIR_COMMAND, &new);
  127. rt_pci_write_config_u16(pdev, PCIR_COMMAND, orig);
  128. if (new != toggle)
  129. {
  130. res = RT_TRUE;
  131. }
  132. return res;
  133. }
  134. static void pci_read_irq(struct rt_pci_device *pdev)
  135. {
  136. rt_uint8_t irq = 0;
  137. rt_pci_read_config_u8(pdev, PCIR_INTPIN, &irq);
  138. pdev->pin = irq;
  139. if (irq)
  140. {
  141. rt_pci_read_config_u8(pdev, PCIR_INTLINE, &irq);
  142. }
  143. pdev->irq = irq;
  144. }
  145. static void pcie_set_port_type(struct rt_pci_device *pdev)
  146. {
  147. int pos;
  148. if (!(pos = rt_pci_find_capability(pdev, PCIY_EXPRESS)))
  149. {
  150. return;
  151. }
  152. pdev->pcie_cap = pos;
  153. }
  154. static void pci_configure_ari(struct rt_pci_device *pdev)
  155. {
  156. rt_uint32_t cap, ctl2_ari;
  157. struct rt_pci_device *bridge;
  158. if (!rt_pci_is_pcie(pdev) || pdev->devfn)
  159. {
  160. return;
  161. }
  162. bridge = pdev->bus->self;
  163. if (rt_pci_is_root_bus(pdev->bus) || !bridge)
  164. {
  165. return;
  166. }
  167. rt_pci_read_config_u32(bridge, bridge->pcie_cap + PCIER_DEVICE_CAP2, &cap);
  168. if (!(cap & PCIEM_CAP2_ARI))
  169. {
  170. return;
  171. }
  172. rt_pci_read_config_u32(bridge, bridge->pcie_cap + PCIER_DEVICE_CTL2, &ctl2_ari);
  173. if (rt_pci_find_ext_capability(pdev, PCIZ_ARI))
  174. {
  175. ctl2_ari |= PCIEM_CTL2_ARI;
  176. bridge->ari_enabled = RT_TRUE;
  177. }
  178. else
  179. {
  180. ctl2_ari &= ~PCIEM_CTL2_ARI;
  181. bridge->ari_enabled = RT_FALSE;
  182. }
  183. rt_pci_write_config_u32(bridge, bridge->pcie_cap + PCIER_DEVICE_CTL2, ctl2_ari);
  184. }
  185. static rt_uint16_t pci_cfg_space_size_ext(struct rt_pci_device *pdev)
  186. {
  187. rt_uint32_t status;
  188. if (rt_pci_read_config_u32(pdev, PCI_REGMAX + 1, &status))
  189. {
  190. return PCI_REGMAX + 1;
  191. }
  192. return PCIE_REGMAX + 1;
  193. }
  194. static rt_uint16_t pci_cfg_space_size(struct rt_pci_device *pdev)
  195. {
  196. int pos;
  197. rt_uint32_t status;
  198. rt_uint16_t class = pdev->class >> 8;
  199. if (class == PCIS_BRIDGE_HOST)
  200. {
  201. return pci_cfg_space_size_ext(pdev);
  202. }
  203. if (rt_pci_is_pcie(pdev))
  204. {
  205. return pci_cfg_space_size_ext(pdev);
  206. }
  207. pos = rt_pci_find_capability(pdev, PCIY_PCIX);
  208. if (!pos)
  209. {
  210. return PCI_REGMAX + 1;
  211. }
  212. rt_pci_read_config_u32(pdev, pos + PCIXR_STATUS, &status);
  213. if (status & (PCIXM_STATUS_266CAP | PCIXM_STATUS_533CAP))
  214. {
  215. return pci_cfg_space_size_ext(pdev);
  216. }
  217. return PCI_REGMAX + 1;
  218. }
  219. static void pci_init_capabilities(struct rt_pci_device *pdev)
  220. {
  221. rt_pci_pme_init(pdev);
  222. #ifdef RT_PCI_MSI
  223. rt_pci_msi_init(pdev); /* Disable MSI */
  224. rt_pci_msix_init(pdev); /* Disable MSI-X */
  225. #endif
  226. pcie_set_port_type(pdev);
  227. pdev->cfg_size = pci_cfg_space_size(pdev);
  228. pci_configure_ari(pdev);
  229. pdev->no_msi = RT_FALSE;
  230. pdev->msi_enabled = RT_FALSE;
  231. pdev->msix_enabled = RT_FALSE;
  232. }
  233. rt_err_t rt_pci_setup_device(struct rt_pci_device *pdev)
  234. {
  235. rt_uint8_t pos;
  236. rt_uint32_t class = 0;
  237. struct rt_pci_host_bridge *host_bridge;
  238. if (!pdev)
  239. {
  240. return -RT_EINVAL;
  241. }
  242. if (!(host_bridge = rt_pci_find_host_bridge(pdev->bus)))
  243. {
  244. return -RT_EINVAL;
  245. }
  246. rt_pci_ofw_device_init(pdev);
  247. rt_pci_read_config_u32(pdev, PCIR_REVID, &class);
  248. pdev->revision = class & 0xff;
  249. pdev->class = class >> 8; /* Upper 3 bytes */
  250. rt_pci_read_config_u8(pdev, PCIR_HDRTYPE, &pdev->hdr_type);
  251. /* Clear errors left from system firmware */
  252. rt_pci_write_config_u16(pdev, PCIR_STATUS, 0xffff);
  253. if (pdev->hdr_type & 0x80)
  254. {
  255. pdev->multi_function = RT_TRUE;
  256. }
  257. pdev->hdr_type &= PCIM_HDRTYPE;
  258. if (pci_intx_mask_broken(pdev))
  259. {
  260. pdev->broken_intx_masking = RT_TRUE;
  261. }
  262. rt_dm_dev_set_name(&pdev->parent, "%04x:%02x:%02x.%u", rt_pci_domain(pdev),
  263. pdev->bus->number, RT_PCI_SLOT(pdev->devfn), RT_PCI_FUNC(pdev->devfn));
  264. switch (pdev->hdr_type)
  265. {
  266. case PCIM_HDRTYPE_NORMAL:
  267. if (class == PCIS_BRIDGE_PCI)
  268. {
  269. goto error;
  270. }
  271. pci_read_irq(pdev);
  272. rt_pci_device_alloc_resource(host_bridge, pdev);
  273. rt_pci_read_config_u16(pdev, PCIR_SUBVEND_0, &pdev->subsystem_vendor);
  274. rt_pci_read_config_u16(pdev, PCIR_SUBDEV_0, &pdev->subsystem_device);
  275. break;
  276. case PCIM_HDRTYPE_BRIDGE:
  277. pci_read_irq(pdev);
  278. rt_pci_device_alloc_resource(host_bridge, pdev);
  279. pos = rt_pci_find_capability(pdev, PCIY_SUBVENDOR);
  280. if (pos)
  281. {
  282. rt_pci_read_config_u16(pdev, PCIR_SUBVENDCAP, &pdev->subsystem_vendor);
  283. rt_pci_read_config_u16(pdev, PCIR_SUBDEVCAP, &pdev->subsystem_device);
  284. }
  285. break;
  286. case PCIM_HDRTYPE_CARDBUS:
  287. if (class != PCIS_BRIDGE_CARDBUS)
  288. {
  289. goto error;
  290. }
  291. pci_read_irq(pdev);
  292. rt_pci_device_alloc_resource(host_bridge, pdev);
  293. rt_pci_read_config_u16(pdev, PCIR_SUBVEND_2, &pdev->subsystem_vendor);
  294. rt_pci_read_config_u16(pdev, PCIR_SUBDEV_2, &pdev->subsystem_device);
  295. break;
  296. default:
  297. LOG_E("Ignoring device unknown header type %02x", pdev->hdr_type);
  298. return -RT_EIO;
  299. error:
  300. LOG_E("Ignoring class %08x (doesn't match header type %02x)", pdev->class, pdev->hdr_type);
  301. pdev->class = PCIC_NOT_DEFINED << 8;
  302. }
  303. pci_init_capabilities(pdev);
  304. if (rt_pci_is_pcie(pdev))
  305. {
  306. rt_pci_read_config_u16(pdev, pdev->pcie_cap + PCIER_FLAGS, &pdev->exp_flags);
  307. }
  308. return RT_EOK;
  309. }
  310. static struct rt_pci_bus *pci_alloc_bus(struct rt_pci_bus *parent);
  311. static rt_err_t pci_child_bus_init(struct rt_pci_bus *bus, rt_uint32_t bus_no,
  312. struct rt_pci_host_bridge *host_bridge, struct rt_pci_device *pdev)
  313. {
  314. rt_err_t err;
  315. struct rt_pci_bus *parent_bus = bus->parent;
  316. bus->sysdata = parent_bus->sysdata;
  317. bus->self = pdev;
  318. bus->ops = host_bridge->child_ops ? : parent_bus->ops;
  319. bus->number = bus_no;
  320. rt_sprintf(bus->name, "%04x:%02x", host_bridge->domain, bus_no);
  321. rt_pci_ofw_bus_init(bus);
  322. if (bus->ops->add)
  323. {
  324. if ((err = bus->ops->add(bus)))
  325. {
  326. rt_pci_ofw_bus_free(bus);
  327. LOG_E("PCI-Bus<%s> add bus failed with err = %s",
  328. bus->name, rt_strerror(err));
  329. return err;
  330. }
  331. }
  332. return RT_EOK;
  333. }
  334. static rt_bool_t pci_ea_fixed_busnrs(struct rt_pci_device *pdev,
  335. rt_uint8_t *sec, rt_uint8_t *sub)
  336. {
  337. int pos, offset;
  338. rt_uint32_t dw;
  339. rt_uint8_t ea_sec, ea_sub;
  340. pos = rt_pci_find_capability(pdev, PCIY_EA);
  341. if (!pos)
  342. {
  343. return RT_FALSE;
  344. }
  345. offset = pos + PCIR_EA_FIRST_ENT;
  346. rt_pci_read_config_u32(pdev, offset, &dw);
  347. ea_sec = PCIM_EA_SEC_NR(dw);
  348. ea_sub = PCIM_EA_SUB_NR(dw);
  349. if (ea_sec == 0 || ea_sub < ea_sec)
  350. {
  351. return RT_FALSE;
  352. }
  353. *sec = ea_sec;
  354. *sub = ea_sub;
  355. return RT_TRUE;
  356. }
  357. static void pcie_fixup_link(struct rt_pci_device *pdev)
  358. {
  359. int pos = pdev->pcie_cap;
  360. rt_uint16_t exp_lnkctl, exp_lnkctl2, exp_lnksta;
  361. rt_uint16_t exp_type = pdev->exp_flags & PCIEM_FLAGS_TYPE;
  362. if ((pdev->exp_flags & PCIEM_FLAGS_VERSION) < 2)
  363. {
  364. return;
  365. }
  366. if (exp_type != PCIEM_TYPE_ROOT_PORT &&
  367. exp_type != PCIEM_TYPE_DOWNSTREAM_PORT &&
  368. exp_type != PCIEM_TYPE_PCIE_BRIDGE)
  369. {
  370. return;
  371. }
  372. rt_pci_read_config_u16(pdev, pos + PCIER_LINK_CTL, &exp_lnkctl);
  373. rt_pci_read_config_u16(pdev, pos + PCIER_LINK_CTL2, &exp_lnkctl2);
  374. rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL2,
  375. (exp_lnkctl2 & ~PCIEM_LNKCTL2_TLS) | PCIEM_LNKCTL2_TLS_2_5GT);
  376. rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL,
  377. exp_lnkctl | PCIEM_LINK_CTL_RETRAIN_LINK);
  378. for (int i = 0; i < 20; ++i)
  379. {
  380. rt_pci_read_config_u16(pdev, pos + PCIER_LINK_STA, &exp_lnksta);
  381. if (!!(exp_lnksta & PCIEM_LINK_STA_DL_ACTIVE))
  382. {
  383. goto _status_sync;
  384. }
  385. rt_thread_mdelay(10);
  386. }
  387. /* Fail, restore */
  388. rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL2, exp_lnkctl2);
  389. rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL,
  390. exp_lnkctl | PCIEM_LINK_CTL_RETRAIN_LINK);
  391. _status_sync:
  392. /* Wait a while for success or failure */
  393. rt_thread_mdelay(100);
  394. }
  395. static rt_uint32_t pci_scan_bridge_extend(struct rt_pci_bus *bus, struct rt_pci_device *pdev,
  396. rt_uint32_t bus_no_start, rt_uint32_t buses, rt_bool_t reconfigured)
  397. {
  398. rt_bool_t fixed_buses;
  399. rt_uint8_t fixed_sub, fixed_sec;
  400. rt_uint8_t primary, secondary, subordinate;
  401. rt_uint32_t value, bus_no = bus_no_start;
  402. struct rt_pci_bus *next_bus;
  403. struct rt_pci_host_bridge *host_bridge;
  404. /* We not supported init CardBus, it always used in the PC servers. */
  405. if (pdev->hdr_type == PCIM_HDRTYPE_CARDBUS)
  406. {
  407. LOG_E("CardBus is not supported in system");
  408. goto _end;
  409. }
  410. rt_pci_read_config_u32(pdev, PCIR_PRIBUS_1, &value);
  411. primary = value & 0xff;
  412. secondary = (value >> 8) & 0xff;
  413. subordinate = (value >> 16) & 0xff;
  414. if (primary == bus->number && bus->number > secondary && secondary > subordinate)
  415. {
  416. if (!reconfigured)
  417. {
  418. goto _end;
  419. }
  420. LOG_I("Bridge configuration: primary(%02x) secondary(%02x) subordinate(%02x)",
  421. primary, secondary, subordinate);
  422. }
  423. if (pdev->pcie_cap)
  424. {
  425. pcie_fixup_link(pdev);
  426. }
  427. ++bus_no;
  428. /* Count of subordinate */
  429. buses -= !!buses;
  430. host_bridge = rt_pci_find_host_bridge(bus);
  431. RT_ASSERT(host_bridge != RT_NULL);
  432. /* Clear errors */
  433. rt_pci_write_config_u16(pdev, PCIR_STATUS, RT_UINT16_MAX);
  434. fixed_buses = pci_ea_fixed_busnrs(pdev, &fixed_sec, &fixed_sub);
  435. if (!(next_bus = pci_alloc_bus(bus)))
  436. {
  437. goto _end;
  438. }
  439. /* Clear bus info */
  440. rt_pci_write_config_u32(pdev, PCIR_PRIBUS_1, value & ~0xffffff);
  441. if (!(next_bus = pci_alloc_bus(bus)))
  442. {
  443. LOG_E("Alloc bus(%02x) fail", bus_no);
  444. goto _end;
  445. }
  446. if (pci_child_bus_init(next_bus, bus_no, host_bridge, pdev))
  447. {
  448. goto _end;
  449. }
  450. /* Fill primary, secondary */
  451. value = (buses & 0xff000000) | (bus->number << 0) | (next_bus->number << 8);
  452. rt_pci_write_config_u32(pdev, PCIR_PRIBUS_1, value);
  453. bus_no = rt_pci_scan_child_buses(next_bus, buses);
  454. /* Fill subordinate */
  455. value |= next_bus->number + rt_list_len(&next_bus->children_nodes);
  456. rt_pci_write_config_u32(pdev, PCIR_PRIBUS_1, value);
  457. if (fixed_buses)
  458. {
  459. bus_no = fixed_sub;
  460. }
  461. rt_pci_write_config_u8(pdev, PCIR_SUBBUS_1, bus_no);
  462. _end:
  463. return bus_no;
  464. }
  465. rt_uint32_t rt_pci_scan_bridge(struct rt_pci_bus *bus, struct rt_pci_device *pdev,
  466. rt_uint32_t bus_no_start, rt_bool_t reconfigured)
  467. {
  468. if (!bus || !pdev)
  469. {
  470. return RT_UINT32_MAX;
  471. }
  472. return pci_scan_bridge_extend(bus, pdev, bus_no_start, 0, reconfigured);
  473. }
  474. rt_inline rt_bool_t only_one_child(struct rt_pci_bus *bus)
  475. {
  476. struct rt_pci_device *pdev;
  477. if (rt_pci_is_root_bus(bus))
  478. {
  479. return RT_FALSE;
  480. }
  481. pdev = bus->self;
  482. if (rt_pci_is_pcie(pdev))
  483. {
  484. rt_uint16_t exp_type = pdev->exp_flags & PCIEM_FLAGS_TYPE;
  485. if (exp_type == PCIEM_TYPE_ROOT_PORT ||
  486. exp_type == PCIEM_TYPE_DOWNSTREAM_PORT ||
  487. exp_type == PCIEM_TYPE_PCIE_BRIDGE)
  488. {
  489. return RT_TRUE;
  490. }
  491. }
  492. return RT_FALSE;
  493. }
  494. static int next_fn(struct rt_pci_bus *bus, struct rt_pci_device *pdev, int fn)
  495. {
  496. if (!rt_pci_is_root_bus(bus) && bus->self->ari_enabled)
  497. {
  498. int pos, next_fn;
  499. rt_uint16_t cap = 0;
  500. if (!pdev)
  501. {
  502. return -RT_EINVAL;
  503. }
  504. pos = rt_pci_find_ext_capability(pdev, PCIZ_ARI);
  505. if (!pos)
  506. {
  507. return -RT_EINVAL;
  508. }
  509. rt_pci_read_config_u16(pdev, pos + PCIR_ARI_CAP, &cap);
  510. next_fn = PCIM_ARI_CAP_NFN(cap);
  511. if (next_fn <= fn)
  512. {
  513. return -RT_EINVAL;
  514. }
  515. return next_fn;
  516. }
  517. if (fn >= RT_PCI_FUNCTION_MAX - 1)
  518. {
  519. return -RT_EINVAL;
  520. }
  521. if (pdev && !pdev->multi_function)
  522. {
  523. return -RT_EINVAL;
  524. }
  525. return fn + 1;
  526. }
  527. rt_size_t rt_pci_scan_slot(struct rt_pci_bus *bus, rt_uint32_t devfn)
  528. {
  529. rt_size_t nr = 0;
  530. struct rt_pci_device *pdev = RT_NULL;
  531. if (!bus)
  532. {
  533. return nr;
  534. }
  535. if (devfn > 0 && only_one_child(bus))
  536. {
  537. return nr;
  538. }
  539. for (int func = 0; func >= 0; func = next_fn(bus, pdev, func))
  540. {
  541. pdev = rt_pci_scan_single_device(bus, devfn + func);
  542. if (pdev)
  543. {
  544. ++nr;
  545. if (func > 0)
  546. {
  547. pdev->multi_function = RT_TRUE;
  548. }
  549. }
  550. else if (func == 0)
  551. {
  552. break;
  553. }
  554. }
  555. return nr;
  556. }
  557. rt_uint32_t rt_pci_scan_child_buses(struct rt_pci_bus *bus, rt_size_t buses)
  558. {
  559. rt_uint32_t bus_no;
  560. struct rt_pci_device *pdev = RT_NULL;
  561. if (!bus)
  562. {
  563. bus_no = RT_UINT32_MAX;
  564. goto _end;
  565. }
  566. bus_no = bus->number;
  567. for (rt_uint32_t devfn = 0;
  568. devfn < RT_PCI_DEVFN(RT_PCI_DEVICE_MAX - 1, RT_PCI_FUNCTION_MAX - 1);
  569. devfn += RT_PCI_FUNCTION_MAX)
  570. {
  571. rt_pci_scan_slot(bus, devfn);
  572. }
  573. rt_pci_foreach_bridge(pdev, bus)
  574. {
  575. int offset;
  576. bus_no = pci_scan_bridge_extend(bus, pdev, bus_no, buses, RT_TRUE);
  577. offset = bus_no - bus->number;
  578. if (buses > offset)
  579. {
  580. buses -= offset;
  581. }
  582. else
  583. {
  584. break;
  585. }
  586. }
  587. _end:
  588. return bus_no;
  589. }
  590. rt_uint32_t rt_pci_scan_child_bus(struct rt_pci_bus *bus)
  591. {
  592. return rt_pci_scan_child_buses(bus, 0);
  593. }
  594. static struct rt_pci_bus *pci_alloc_bus(struct rt_pci_bus *parent)
  595. {
  596. struct rt_pci_bus *bus = rt_calloc(1, sizeof(*bus));
  597. if (!bus)
  598. {
  599. return RT_NULL;
  600. }
  601. bus->parent = parent;
  602. rt_list_init(&bus->list);
  603. rt_list_init(&bus->children_nodes);
  604. rt_list_init(&bus->devices_nodes);
  605. rt_spin_lock_init(&bus->lock);
  606. return bus;
  607. }
  608. rt_err_t rt_pci_host_bridge_register(struct rt_pci_host_bridge *host_bridge)
  609. {
  610. struct rt_pci_bus *bus = pci_alloc_bus(RT_NULL);
  611. if (!bus)
  612. {
  613. return -RT_ENOMEM;
  614. }
  615. host_bridge->root_bus = bus;
  616. bus->sysdata = host_bridge->sysdata;
  617. bus->host_bridge = host_bridge;
  618. bus->ops = host_bridge->ops;
  619. bus->number = host_bridge->bus_range[0];
  620. rt_sprintf(bus->name, "%04x:%02x", host_bridge->domain, bus->number);
  621. if (bus->ops->add)
  622. {
  623. rt_err_t err = bus->ops->add(bus);
  624. if (err)
  625. {
  626. LOG_E("PCI-Bus<%s> add bus failed with err = %s", bus->name, rt_strerror(err));
  627. }
  628. }
  629. return RT_EOK;
  630. }
  631. rt_err_t rt_pci_scan_root_bus_bridge(struct rt_pci_host_bridge *host_bridge)
  632. {
  633. rt_err_t err;
  634. if ((err = rt_pci_host_bridge_register(host_bridge)))
  635. {
  636. return err;
  637. }
  638. rt_pci_scan_child_bus(host_bridge->root_bus);
  639. return err;
  640. }
  641. rt_err_t rt_pci_host_bridge_probe(struct rt_pci_host_bridge *host_bridge)
  642. {
  643. rt_err_t err;
  644. err = rt_pci_scan_root_bus_bridge(host_bridge);
  645. return err;
  646. }
  647. static rt_bool_t pci_remove_bus_device(struct rt_pci_device *pdev, void *data)
  648. {
  649. /* Bus will free if this is the last device */
  650. rt_bus_remove_device(&pdev->parent);
  651. /* To find all devices, always return false */
  652. return RT_FALSE;
  653. }
  654. rt_err_t rt_pci_host_bridge_remove(struct rt_pci_host_bridge *host_bridge)
  655. {
  656. rt_err_t err = RT_EOK;
  657. if (host_bridge && host_bridge->root_bus)
  658. {
  659. rt_pci_enum_device(host_bridge->root_bus, pci_remove_bus_device, RT_NULL);
  660. host_bridge->root_bus = RT_NULL;
  661. }
  662. else
  663. {
  664. err = -RT_EINVAL;
  665. }
  666. return err;
  667. }
  668. rt_err_t rt_pci_bus_remove(struct rt_pci_bus *bus)
  669. {
  670. rt_err_t err = RT_EOK;
  671. if (bus)
  672. {
  673. spin_lock(&bus->lock);
  674. if (rt_list_isempty(&bus->children_nodes) &&
  675. rt_list_isempty(&bus->devices_nodes))
  676. {
  677. rt_list_remove(&bus->list);
  678. spin_unlock(&bus->lock);
  679. if (bus->ops->remove)
  680. {
  681. bus->ops->remove(bus);
  682. }
  683. rt_pci_ofw_bus_free(bus);
  684. rt_free(bus);
  685. }
  686. else
  687. {
  688. spin_unlock(&bus->lock);
  689. err = -RT_EBUSY;
  690. }
  691. }
  692. else
  693. {
  694. err = -RT_EINVAL;
  695. }
  696. return err;
  697. }
  698. rt_err_t rt_pci_device_remove(struct rt_pci_device *pdev)
  699. {
  700. rt_err_t err = RT_EOK;
  701. if (pdev)
  702. {
  703. struct rt_pci_bus *bus = pdev->bus;
  704. spin_lock(&bus->lock);
  705. while (pdev->parent.ref_count > 1)
  706. {
  707. spin_unlock(&bus->lock);
  708. rt_thread_yield();
  709. spin_lock(&bus->lock);
  710. }
  711. rt_list_remove(&pdev->list);
  712. spin_unlock(&bus->lock);
  713. rt_free(pdev);
  714. }
  715. else
  716. {
  717. err = -RT_EINVAL;
  718. }
  719. return err;
  720. }