1 /* 2 * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2003, Marcus Overhagen. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include <device_manager.h> 10 #include <PCI.h> 11 12 #include <string.h> 13 14 #include "pci_private.h" 15 #include "pci.h" 16 17 18 // name of PCI root module 19 #define PCI_ROOT_MODULE_NAME "bus_managers/pci/root/driver_v1" 20 21 22 static float 23 pci_root_supports_device(device_node* parent) 24 { 25 // make sure parent is really device root 26 const char* bus; 27 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) 28 return B_ERROR; 29 30 if (strcmp(bus, "root")) 31 return 0.0; 32 33 return 1.0; 34 } 35 36 37 static status_t 38 pci_root_register_device(device_node* parent) 39 { 40 // XXX how do we handle this for PPC? 41 // I/O port for PCI config space address 42 #define PCI_CONFIG_ADDRESS 0xcf8 43 44 io_resource resources[2] = { 45 {B_IO_PORT, PCI_CONFIG_ADDRESS, 8}, 46 {} 47 }; 48 device_attr attrs[] = { 49 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "PCI"}}, 50 {B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_KEEP_DRIVER_LOADED}}, 51 {} 52 }; 53 54 return gDeviceManager->register_node(parent, PCI_ROOT_MODULE_NAME, attrs, 55 resources, NULL); 56 } 57 58 59 static status_t 60 pci_root_register_child_devices(void* cookie) 61 { 62 device_node* node = (device_node*)cookie; 63 64 pci_info info; 65 for (int32 i = 0; pci_get_nth_pci_info(i, &info) == B_OK; i++) { 66 uint8 domain; 67 uint8 bus; 68 if (gPCI->ResolveVirtualBus(info.bus, &domain, &bus) != B_OK) { 69 dprintf("FAILED!!!!\n"); 70 continue; 71 } 72 73 device_attr attrs[] = { 74 // info about device 75 {B_DEVICE_BUS, B_STRING_TYPE, {string: "pci"}}, 76 77 // location on PCI bus 78 {B_PCI_DEVICE_DOMAIN, B_UINT8_TYPE, {ui8: domain}}, 79 {B_PCI_DEVICE_BUS, B_UINT8_TYPE, {ui8: bus}}, 80 {B_PCI_DEVICE_DEVICE, B_UINT8_TYPE, {ui8: info.device}}, 81 {B_PCI_DEVICE_FUNCTION, B_UINT8_TYPE, {ui8: info.function}}, 82 83 // info about the device 84 {B_DEVICE_VENDOR_ID, B_UINT16_TYPE, { ui16: info.vendor_id }}, 85 {B_DEVICE_ID, B_UINT16_TYPE, { ui16: info.device_id }}, 86 87 {B_DEVICE_TYPE, B_UINT16_TYPE, { ui16: info.class_base }}, 88 {B_DEVICE_SUB_TYPE, B_UINT16_TYPE, { ui16: info.class_sub }}, 89 {B_DEVICE_INTERFACE, B_UINT16_TYPE, { ui16: info.class_api }}, 90 91 {B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_CHILD_ON_DEMAND}}, 92 {} 93 }; 94 95 gDeviceManager->register_node(node, PCI_DEVICE_MODULE_NAME, attrs, 96 NULL, NULL); 97 } 98 99 return B_OK; 100 } 101 102 103 static status_t 104 pci_root_init(device_node* node, void** _cookie) 105 { 106 *_cookie = node; 107 return B_OK; 108 } 109 110 111 static int32 112 pci_root_std_ops(int32 op, ...) 113 { 114 switch (op) { 115 case B_MODULE_INIT: 116 { 117 module_info *module; 118 return get_module(B_PCI_MODULE_NAME, &module); 119 // this serializes our module initialization 120 } 121 122 case B_MODULE_UNINIT: 123 return put_module(B_PCI_MODULE_NAME); 124 } 125 126 return B_BAD_VALUE; 127 } 128 129 130 struct pci_root_module_info gPCIRootModule = { 131 { 132 { 133 PCI_ROOT_MODULE_NAME, 134 0, 135 pci_root_std_ops 136 }, 137 138 pci_root_supports_device, 139 pci_root_register_device, 140 pci_root_init, 141 NULL, // uninit 142 pci_root_register_child_devices, 143 NULL, // rescan devices 144 NULL, // device removed 145 }, 146 147 &pci_read_config, 148 &pci_write_config 149 }; 150