1/* 2 * pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 1.1.1.1 $) 3 * 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or (at 12 * your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 */ 25 26#include <linux/kernel.h> 27#include <linux/module.h> 28#include <linux/init.h> 29#include <linux/types.h> 30#include <linux/proc_fs.h> 31#include <linux/spinlock.h> 32#include <linux/pm.h> 33#include <linux/pci.h> 34#include <linux/acpi.h> 35#include <acpi/acpi_bus.h> 36#include <acpi/acpi_drivers.h> 37 38#define _COMPONENT ACPI_PCI_COMPONENT 39ACPI_MODULE_NAME("pci_root"); 40#define ACPI_PCI_ROOT_CLASS "pci_bridge" 41#define ACPI_PCI_ROOT_HID "PNP0A03" 42#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" 43static int acpi_pci_root_add(struct acpi_device *device); 44static int acpi_pci_root_remove(struct acpi_device *device, int type); 45static int acpi_pci_root_start(struct acpi_device *device); 46 47static struct acpi_driver acpi_pci_root_driver = { 48 .name = "pci_root", 49 .class = ACPI_PCI_ROOT_CLASS, 50 .ids = ACPI_PCI_ROOT_HID, 51 .ops = { 52 .add = acpi_pci_root_add, 53 .remove = acpi_pci_root_remove, 54 .start = acpi_pci_root_start, 55 }, 56}; 57 58struct acpi_pci_root { 59 struct list_head node; 60 struct acpi_device * device; 61 struct acpi_pci_id id; 62 struct pci_bus *bus; 63}; 64 65static LIST_HEAD(acpi_pci_roots); 66 67static struct acpi_pci_driver *sub_driver; 68 69int acpi_pci_register_driver(struct acpi_pci_driver *driver) 70{ 71 int n = 0; 72 struct list_head *entry; 73 74 struct acpi_pci_driver **pptr = &sub_driver; 75 while (*pptr) 76 pptr = &(*pptr)->next; 77 *pptr = driver; 78 79 if (!driver->add) 80 return 0; 81 82 list_for_each(entry, &acpi_pci_roots) { 83 struct acpi_pci_root *root; 84 root = list_entry(entry, struct acpi_pci_root, node); 85 driver->add(root->device->handle); 86 n++; 87 } 88 89 return n; 90} 91 92EXPORT_SYMBOL(acpi_pci_register_driver); 93 94void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) 95{ 96 struct list_head *entry; 97 98 struct acpi_pci_driver **pptr = &sub_driver; 99 while (*pptr) { 100 if (*pptr == driver) 101 break; 102 pptr = &(*pptr)->next; 103 } 104 BUG_ON(!*pptr); 105 *pptr = (*pptr)->next; 106 107 if (!driver->remove) 108 return; 109 110 list_for_each(entry, &acpi_pci_roots) { 111 struct acpi_pci_root *root; 112 root = list_entry(entry, struct acpi_pci_root, node); 113 driver->remove(root->device->handle); 114 } 115} 116 117EXPORT_SYMBOL(acpi_pci_unregister_driver); 118 119acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) 120{ 121 struct acpi_pci_root *tmp; 122 123 list_for_each_entry(tmp, &acpi_pci_roots, node) { 124 if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) 125 return tmp->device->handle; 126 } 127 return NULL; 128} 129 130EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); 131 132static acpi_status 133get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 134{ 135 int *busnr = data; 136 struct acpi_resource_address64 address; 137 138 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && 139 resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && 140 resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) 141 return AE_OK; 142 143 acpi_resource_to_address64(resource, &address); 144 if ((address.address_length > 0) && 145 (address.resource_type == ACPI_BUS_NUMBER_RANGE)) 146 *busnr = address.minimum; 147 148 return AE_OK; 149} 150 151static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) 152{ 153 acpi_status status; 154 155 *busnum = -1; 156 status = 157 acpi_walk_resources(handle, METHOD_NAME__CRS, 158 get_root_bridge_busnr_callback, busnum); 159 if (ACPI_FAILURE(status)) 160 return status; 161 /* Check if we really get a bus number from _CRS */ 162 if (*busnum == -1) 163 return AE_ERROR; 164 return AE_OK; 165} 166 167static void acpi_pci_bridge_scan(struct acpi_device *device) 168{ 169 int status; 170 struct acpi_device *child = NULL; 171 172 if (device->flags.bus_address) 173 if (device->parent && device->parent->ops.bind) { 174 status = device->parent->ops.bind(device); 175 if (!status) { 176 list_for_each_entry(child, &device->children, node) 177 acpi_pci_bridge_scan(child); 178 } 179 } 180} 181 182static int acpi_pci_root_add(struct acpi_device *device) 183{ 184 int result = 0; 185 struct acpi_pci_root *root = NULL; 186 struct acpi_pci_root *tmp; 187 acpi_status status = AE_OK; 188 unsigned long value = 0; 189 acpi_handle handle = NULL; 190 struct acpi_device *child; 191 192 193 if (!device) 194 return -EINVAL; 195 196 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); 197 if (!root) 198 return -ENOMEM; 199 INIT_LIST_HEAD(&root->node); 200 201 root->device = device; 202 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); 203 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); 204 acpi_driver_data(device) = root; 205 206 device->ops.bind = acpi_pci_bind; 207 208 /* 209 * Segment 210 * ------- 211 * Obtained via _SEG, if exists, otherwise assumed to be zero (0). 212 */ 213 status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, 214 &value); 215 switch (status) { 216 case AE_OK: 217 root->id.segment = (u16) value; 218 break; 219 case AE_NOT_FOUND: 220 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 221 "Assuming segment 0 (no _SEG)\n")); 222 root->id.segment = 0; 223 break; 224 default: 225 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG")); 226 result = -ENODEV; 227 goto end; 228 } 229 230 /* 231 * Bus 232 * --- 233 * Obtained via _BBN, if exists, otherwise assumed to be zero (0). 234 */ 235 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, 236 &value); 237 switch (status) { 238 case AE_OK: 239 root->id.bus = (u16) value; 240 break; 241 case AE_NOT_FOUND: 242 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); 243 root->id.bus = 0; 244 break; 245 default: 246 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN")); 247 result = -ENODEV; 248 goto end; 249 } 250 251 /* Some systems have wrong _BBN */ 252 list_for_each_entry(tmp, &acpi_pci_roots, node) { 253 if ((tmp->id.segment == root->id.segment) 254 && (tmp->id.bus == root->id.bus)) { 255 int bus = 0; 256 acpi_status status; 257 258 printk(KERN_ERR PREFIX 259 "Wrong _BBN value, reboot" 260 " and use option 'pci=noacpi'\n"); 261 262 status = try_get_root_bridge_busnr(device->handle, &bus); 263 if (ACPI_FAILURE(status)) 264 break; 265 if (bus != root->id.bus) { 266 printk(KERN_INFO PREFIX 267 "PCI _CRS %d overrides _BBN 0\n", bus); 268 root->id.bus = bus; 269 } 270 break; 271 } 272 } 273 /* 274 * Device & Function 275 * ----------------- 276 * Obtained from _ADR (which has already been evaluated for us). 277 */ 278 root->id.device = device->pnp.bus_address >> 16; 279 root->id.function = device->pnp.bus_address & 0xFFFF; 280 281 /* 282 * TBD: Need PCI interface for enumeration/configuration of roots. 283 */ 284 285 /* TBD: Locking */ 286 list_add_tail(&root->node, &acpi_pci_roots); 287 288 printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", 289 acpi_device_name(device), acpi_device_bid(device), 290 root->id.segment, root->id.bus); 291 292 /* 293 * Scan the Root Bridge 294 * -------------------- 295 * Must do this prior to any attempt to bind the root device, as the 296 * PCI namespace does not get created until this call is made (and 297 * thus the root bridge's pci_dev does not exist). 298 */ 299 root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); 300 if (!root->bus) { 301 printk(KERN_ERR PREFIX 302 "Bus %04x:%02x not present in PCI namespace\n", 303 root->id.segment, root->id.bus); 304 result = -ENODEV; 305 goto end; 306 } 307 308 /* 309 * Attach ACPI-PCI Context 310 * ----------------------- 311 * Thus binding the ACPI and PCI devices. 312 */ 313 result = acpi_pci_bind_root(device, &root->id, root->bus); 314 if (result) 315 goto end; 316 317 /* 318 * PCI Routing Table 319 * ----------------- 320 * Evaluate and parse _PRT, if exists. 321 */ 322 status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); 323 if (ACPI_SUCCESS(status)) 324 result = acpi_pci_irq_add_prt(device->handle, root->id.segment, 325 root->id.bus); 326 327 /* 328 * Scan and bind all _ADR-Based Devices 329 */ 330 list_for_each_entry(child, &device->children, node) 331 acpi_pci_bridge_scan(child); 332 333 end: 334 if (result) { 335 if (!list_empty(&root->node)) 336 list_del(&root->node); 337 kfree(root); 338 } 339 340 return result; 341} 342 343static int acpi_pci_root_start(struct acpi_device *device) 344{ 345 struct acpi_pci_root *root; 346 347 348 list_for_each_entry(root, &acpi_pci_roots, node) { 349 if (root->device == device) { 350 pci_bus_add_devices(root->bus); 351 return 0; 352 } 353 } 354 return -ENODEV; 355} 356 357static int acpi_pci_root_remove(struct acpi_device *device, int type) 358{ 359 struct acpi_pci_root *root = NULL; 360 361 362 if (!device || !acpi_driver_data(device)) 363 return -EINVAL; 364 365 root = acpi_driver_data(device); 366 367 kfree(root); 368 369 return 0; 370} 371 372static int __init acpi_pci_root_init(void) 373{ 374 375 if (acpi_pci_disabled) 376 return 0; 377 378 /* DEBUG: 379 acpi_dbg_layer = ACPI_PCI_COMPONENT; 380 acpi_dbg_level = 0xFFFFFFFF; 381 */ 382 383 if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) 384 return -ENODEV; 385 386 return 0; 387} 388 389subsys_initcall(acpi_pci_root_init); 390