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