1 /* 2 * Copyright (c) 2021 Travis Geiseblrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #pragma once 9 10 #include <sys/types.h> 11 #include <dev/bus/pci.h> 12 #include <lk/cpp.h> 13 #include <lk/err.h> 14 15 #include "device.h" 16 #include "bridge.h" 17 18 namespace pci { 19 20 class resource_allocator; 21 22 // bus device holds a list of devices and a reference to its bridge device 23 class bus { 24 public: 25 bus(pci_location_t loc, bridge *b, bool root_bus = false); 26 ~bus() = default; 27 28 DISALLOW_COPY_ASSIGN_AND_MOVE(bus); 29 30 static status_t probe(pci_location_t loc, bridge *bridge, bus **out_bus, bool root_bus = false); 31 32 // allocate resources for devices on this bus and recursively all of its children 33 status_t allocate_resources(resource_allocator &allocator); 34 loc()35 pci_location_t loc() const { return loc_; } bus_num()36 uint bus_num() const { return loc().bus; } 37 38 void add_device(device *d); 39 void dump(size_t indent = 0); 40 get_bridge()41 const bridge *get_bridge() const { return b_; } get_bridge()42 bridge *get_bridge() { return b_; } 43 44 template <typename F> 45 status_t for_every_device(F func); 46 47 void add_to_global_list(); 48 49 // master list of busses for easy iteration 50 list_node node = LIST_INITIAL_CLEARED_VALUE; list_node_ptr()51 list_node *list_node_ptr() { return &node; } 52 53 private: 54 pci_location_t loc_ = {}; 55 bridge *b_ = nullptr; 56 list_node child_devices_ = LIST_INITIAL_VALUE(child_devices_); 57 const bool root_bus_ = false; // changes some of the allocation behavior 58 }; 59 60 // call the provided functor on every device in this bus 61 template <typename F> for_every_device(F func)62inline status_t bus::for_every_device(F func) { 63 status_t err = NO_ERROR; 64 65 device *d; 66 list_for_every_entry(&child_devices_, d, device, node) { 67 err = func(d); 68 if (err != NO_ERROR) { 69 return err; 70 } 71 } 72 return err; 73 } 74 75 } // namespace pci 76