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