1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * IBM Hot Plug Controller Driver 4 * 5 * Written By: Irene Zubarev, IBM Corporation 6 * 7 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 8 * Copyright (C) 2001,2002 IBM Corp. 9 * 10 * All rights reserved. 11 * 12 * Send feedback to <gregkh@us.ibm.com> 13 * 14 */ 15 16 #include <linux/module.h> 17 #include <linux/slab.h> 18 #include <linux/pci.h> 19 #include <linux/list.h> 20 #include <linux/init.h> 21 #include "ibmphp.h" 22 23 static int flags = 0; /* for testing */ 24 25 static void update_resources(struct bus_node *bus_cur, int type, int rangeno); 26 static int once_over(void); 27 static int remove_ranges(struct bus_node *, struct bus_node *); 28 static int update_bridge_ranges(struct bus_node **); 29 static int add_bus_range(int type, struct range_node *, struct bus_node *); 30 static void fix_resources(struct bus_node *); 31 static struct bus_node *find_bus_wprev(u8, struct bus_node **, u8); 32 33 static LIST_HEAD(gbuses); 34 35 static struct bus_node * __init alloc_error_bus(struct ebda_pci_rsrc *curr, u8 busno, int flag) 36 { 37 struct bus_node *newbus; 38 39 if (!(curr) && !(flag)) { 40 err("NULL pointer passed\n"); 41 return NULL; 42 } 43 44 newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL); 45 if (!newbus) 46 return NULL; 47 48 if (flag) 49 newbus->busno = busno; 50 else 51 newbus->busno = curr->bus_num; 52 list_add_tail(&newbus->bus_list, &gbuses); 53 return newbus; 54 } 55 56 static struct resource_node * __init alloc_resources(struct ebda_pci_rsrc *curr) 57 { 58 struct resource_node *rs; 59 60 if (!curr) { 61 err("NULL passed to allocate\n"); 62 return NULL; 63 } 64 65 rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL); 66 if (!rs) 67 return NULL; 68 69 rs->busno = curr->bus_num; 70 rs->devfunc = curr->dev_fun; 71 rs->start = curr->start_addr; 72 rs->end = curr->end_addr; 73 rs->len = curr->end_addr - curr->start_addr + 1; 74 return rs; 75 } 76 77 static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus) 78 { 79 struct bus_node *newbus; 80 struct range_node *newrange; 81 u8 num_ranges = 0; 82 83 if (first_bus) { 84 newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL); 85 if (!newbus) 86 return -ENOMEM; 87 88 newbus->busno = curr->bus_num; 89 } else { 90 newbus = *new_bus; 91 switch (flag) { 92 case MEM: 93 num_ranges = newbus->noMemRanges; 94 break; 95 case PFMEM: 96 num_ranges = newbus->noPFMemRanges; 97 break; 98 case IO: 99 num_ranges = newbus->noIORanges; 100 break; 101 } 102 } 103 104 newrange = kzalloc(sizeof(struct range_node), GFP_KERNEL); 105 if (!newrange) { 106 if (first_bus) 107 kfree(newbus); 108 return -ENOMEM; 109 } 110 newrange->start = curr->start_addr; 111 newrange->end = curr->end_addr; 112 113 if (first_bus || (!num_ranges)) 114 newrange->rangeno = 1; 115 else { 116 /* need to insert our range */ 117 add_bus_range(flag, newrange, newbus); 118 debug("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end); 119 } 120 121 switch (flag) { 122 case MEM: 123 newbus->rangeMem = newrange; 124 if (first_bus) 125 newbus->noMemRanges = 1; 126 else { 127 debug("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 128 ++newbus->noMemRanges; 129 fix_resources(newbus); 130 } 131 break; 132 case IO: 133 newbus->rangeIO = newrange; 134 if (first_bus) 135 newbus->noIORanges = 1; 136 else { 137 debug("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 138 ++newbus->noIORanges; 139 fix_resources(newbus); 140 } 141 break; 142 case PFMEM: 143 newbus->rangePFMem = newrange; 144 if (first_bus) 145 newbus->noPFMemRanges = 1; 146 else { 147 debug("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 148 ++newbus->noPFMemRanges; 149 fix_resources(newbus); 150 } 151 152 break; 153 } 154 155 *new_bus = newbus; 156 *new_range = newrange; 157 return 0; 158 } 159 160 161 /* Notes: 162 * 1. The ranges are ordered. The buses are not ordered. (First come) 163 * 164 * 2. If cannot allocate out of PFMem range, allocate from Mem ranges. PFmemFromMem 165 * are not sorted. (no need since use mem node). To not change the entire code, we 166 * also add mem node whenever this case happens so as not to change 167 * ibmphp_check_mem_resource etc(and since it really is taking Mem resource) 168 */ 169 170 /***************************************************************************** 171 * This is the Resource Management initialization function. It will go through 172 * the Resource list taken from EBDA and fill in this module's data structures 173 * 174 * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES, 175 * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW 176 * 177 * Input: ptr to the head of the resource list from EBDA 178 * Output: 0, -1 or error codes 179 ***************************************************************************/ 180 int __init ibmphp_rsrc_init(void) 181 { 182 struct ebda_pci_rsrc *curr; 183 struct range_node *newrange = NULL; 184 struct bus_node *newbus = NULL; 185 struct bus_node *bus_cur; 186 struct bus_node *bus_prev; 187 struct resource_node *new_io = NULL; 188 struct resource_node *new_mem = NULL; 189 struct resource_node *new_pfmem = NULL; 190 int rc; 191 192 list_for_each_entry(curr, &ibmphp_ebda_pci_rsrc_head, 193 ebda_pci_rsrc_list) { 194 if (!(curr->rsrc_type & PCIDEVMASK)) { 195 /* EBDA still lists non PCI devices, so ignore... */ 196 debug("this is not a PCI DEVICE in rsrc_init, please take care\n"); 197 // continue; 198 } 199 200 /* this is a primary bus resource */ 201 if (curr->rsrc_type & PRIMARYBUSMASK) { 202 /* memory */ 203 if ((curr->rsrc_type & RESTYPE) == MMASK) { 204 /* no bus structure exists in place yet */ 205 if (list_empty(&gbuses)) { 206 rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1); 207 if (rc) 208 return rc; 209 list_add_tail(&newbus->bus_list, &gbuses); 210 debug("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 211 } else { 212 bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1); 213 /* found our bus */ 214 if (bus_cur) { 215 rc = alloc_bus_range(&bus_cur, &newrange, curr, MEM, 0); 216 if (rc) 217 return rc; 218 } else { 219 /* went through all the buses and didn't find ours, need to create a new bus node */ 220 rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1); 221 if (rc) 222 return rc; 223 224 list_add_tail(&newbus->bus_list, &gbuses); 225 debug("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 226 } 227 } 228 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) { 229 /* prefetchable memory */ 230 if (list_empty(&gbuses)) { 231 /* no bus structure exists in place yet */ 232 rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1); 233 if (rc) 234 return rc; 235 list_add_tail(&newbus->bus_list, &gbuses); 236 debug("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 237 } else { 238 bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1); 239 if (bus_cur) { 240 /* found our bus */ 241 rc = alloc_bus_range(&bus_cur, &newrange, curr, PFMEM, 0); 242 if (rc) 243 return rc; 244 } else { 245 /* went through all the buses and didn't find ours, need to create a new bus node */ 246 rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1); 247 if (rc) 248 return rc; 249 list_add_tail(&newbus->bus_list, &gbuses); 250 debug("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 251 } 252 } 253 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) { 254 /* IO */ 255 if (list_empty(&gbuses)) { 256 /* no bus structure exists in place yet */ 257 rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1); 258 if (rc) 259 return rc; 260 list_add_tail(&newbus->bus_list, &gbuses); 261 debug("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 262 } else { 263 bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1); 264 if (bus_cur) { 265 rc = alloc_bus_range(&bus_cur, &newrange, curr, IO, 0); 266 if (rc) 267 return rc; 268 } else { 269 /* went through all the buses and didn't find ours, need to create a new bus node */ 270 rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1); 271 if (rc) 272 return rc; 273 list_add_tail(&newbus->bus_list, &gbuses); 274 debug("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); 275 } 276 } 277 278 } else { 279 ; /* type is reserved WHAT TO DO IN THIS CASE??? 280 NOTHING TO DO??? */ 281 } 282 } else { 283 /* regular pci device resource */ 284 if ((curr->rsrc_type & RESTYPE) == MMASK) { 285 /* Memory resource */ 286 new_mem = alloc_resources(curr); 287 if (!new_mem) 288 return -ENOMEM; 289 new_mem->type = MEM; 290 /* 291 * if it didn't find the bus, means PCI dev 292 * came b4 the Primary Bus info, so need to 293 * create a bus rangeno becomes a problem... 294 * assign a -1 and then update once the range 295 * actually appears... 296 */ 297 if (ibmphp_add_resource(new_mem) < 0) { 298 newbus = alloc_error_bus(curr, 0, 0); 299 if (!newbus) 300 return -ENOMEM; 301 newbus->firstMem = new_mem; 302 ++newbus->needMemUpdate; 303 new_mem->rangeno = -1; 304 } 305 debug("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end); 306 307 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) { 308 /* PFMemory resource */ 309 new_pfmem = alloc_resources(curr); 310 if (!new_pfmem) 311 return -ENOMEM; 312 new_pfmem->type = PFMEM; 313 new_pfmem->fromMem = 0; 314 if (ibmphp_add_resource(new_pfmem) < 0) { 315 newbus = alloc_error_bus(curr, 0, 0); 316 if (!newbus) 317 return -ENOMEM; 318 newbus->firstPFMem = new_pfmem; 319 ++newbus->needPFMemUpdate; 320 new_pfmem->rangeno = -1; 321 } 322 323 debug("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end); 324 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) { 325 /* IO resource */ 326 new_io = alloc_resources(curr); 327 if (!new_io) 328 return -ENOMEM; 329 new_io->type = IO; 330 331 /* 332 * if it didn't find the bus, means PCI dev 333 * came b4 the Primary Bus info, so need to 334 * create a bus rangeno becomes a problem... 335 * Can assign a -1 and then update once the 336 * range actually appears... 337 */ 338 if (ibmphp_add_resource(new_io) < 0) { 339 newbus = alloc_error_bus(curr, 0, 0); 340 if (!newbus) 341 return -ENOMEM; 342 newbus->firstIO = new_io; 343 ++newbus->needIOUpdate; 344 new_io->rangeno = -1; 345 } 346 debug("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end); 347 } 348 } 349 } 350 351 list_for_each_entry(bus_cur, &gbuses, bus_list) { 352 /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */ 353 rc = update_bridge_ranges(&bus_cur); 354 if (rc) 355 return rc; 356 } 357 return once_over(); /* This is to align ranges (so no -1) */ 358 } 359 360 /******************************************************************************** 361 * This function adds a range into a sorted list of ranges per bus for a particular 362 * range type, it then calls another routine to update the range numbers on the 363 * pci devices' resources for the appropriate resource 364 * 365 * Input: type of the resource, range to add, current bus 366 * Output: 0 or -1, bus and range ptrs 367 ********************************************************************************/ 368 static int add_bus_range(int type, struct range_node *range, struct bus_node *bus_cur) 369 { 370 struct range_node *range_cur = NULL; 371 struct range_node *range_prev; 372 int count = 0, i_init; 373 int noRanges = 0; 374 375 switch (type) { 376 case MEM: 377 range_cur = bus_cur->rangeMem; 378 noRanges = bus_cur->noMemRanges; 379 break; 380 case PFMEM: 381 range_cur = bus_cur->rangePFMem; 382 noRanges = bus_cur->noPFMemRanges; 383 break; 384 case IO: 385 range_cur = bus_cur->rangeIO; 386 noRanges = bus_cur->noIORanges; 387 break; 388 } 389 390 range_prev = NULL; 391 while (range_cur) { 392 if (range->start < range_cur->start) 393 break; 394 range_prev = range_cur; 395 range_cur = range_cur->next; 396 count = count + 1; 397 } 398 if (!count) { 399 /* our range will go at the beginning of the list */ 400 switch (type) { 401 case MEM: 402 bus_cur->rangeMem = range; 403 break; 404 case PFMEM: 405 bus_cur->rangePFMem = range; 406 break; 407 case IO: 408 bus_cur->rangeIO = range; 409 break; 410 } 411 range->next = range_cur; 412 range->rangeno = 1; 413 i_init = 0; 414 } else if (!range_cur) { 415 /* our range will go at the end of the list */ 416 range->next = NULL; 417 range_prev->next = range; 418 range->rangeno = range_prev->rangeno + 1; 419 return 0; 420 } else { 421 /* the range is in the middle */ 422 range_prev->next = range; 423 range->next = range_cur; 424 range->rangeno = range_cur->rangeno; 425 i_init = range_prev->rangeno; 426 } 427 428 for (count = i_init; count < noRanges; ++count) { 429 ++range_cur->rangeno; 430 range_cur = range_cur->next; 431 } 432 433 update_resources(bus_cur, type, i_init + 1); 434 return 0; 435 } 436 437 /******************************************************************************* 438 * This routine goes through the list of resources of type 'type' and updates 439 * the range numbers that they correspond to. It was called from add_bus_range fnc 440 * 441 * Input: bus, type of the resource, the rangeno starting from which to update 442 ******************************************************************************/ 443 static void update_resources(struct bus_node *bus_cur, int type, int rangeno) 444 { 445 struct resource_node *res = NULL; 446 u8 eol = 0; /* end of list indicator */ 447 448 switch (type) { 449 case MEM: 450 if (bus_cur->firstMem) 451 res = bus_cur->firstMem; 452 break; 453 case PFMEM: 454 if (bus_cur->firstPFMem) 455 res = bus_cur->firstPFMem; 456 break; 457 case IO: 458 if (bus_cur->firstIO) 459 res = bus_cur->firstIO; 460 break; 461 } 462 463 if (res) { 464 while (res) { 465 if (res->rangeno == rangeno) 466 break; 467 if (res->next) 468 res = res->next; 469 else if (res->nextRange) 470 res = res->nextRange; 471 else { 472 eol = 1; 473 break; 474 } 475 } 476 477 if (!eol) { 478 /* found the range */ 479 while (res) { 480 ++res->rangeno; 481 res = res->next; 482 } 483 } 484 } 485 } 486 487 static void fix_me(struct resource_node *res, struct bus_node *bus_cur, struct range_node *range) 488 { 489 char *str = ""; 490 switch (res->type) { 491 case IO: 492 str = "io"; 493 break; 494 case MEM: 495 str = "mem"; 496 break; 497 case PFMEM: 498 str = "pfmem"; 499 break; 500 } 501 502 while (res) { 503 if (res->rangeno == -1) { 504 while (range) { 505 if ((res->start >= range->start) && (res->end <= range->end)) { 506 res->rangeno = range->rangeno; 507 debug("%s->rangeno in fix_resources is %d\n", str, res->rangeno); 508 switch (res->type) { 509 case IO: 510 --bus_cur->needIOUpdate; 511 break; 512 case MEM: 513 --bus_cur->needMemUpdate; 514 break; 515 case PFMEM: 516 --bus_cur->needPFMemUpdate; 517 break; 518 } 519 break; 520 } 521 range = range->next; 522 } 523 } 524 if (res->next) 525 res = res->next; 526 else 527 res = res->nextRange; 528 } 529 530 } 531 532 /***************************************************************************** 533 * This routine reassigns the range numbers to the resources that had a -1 534 * This case can happen only if upon initialization, resources taken by pci dev 535 * appear in EBDA before the resources allocated for that bus, since we don't 536 * know the range, we assign -1, and this routine is called after a new range 537 * is assigned to see the resources with unknown range belong to the added range 538 * 539 * Input: current bus 540 * Output: none, list of resources for that bus are fixed if can be 541 *******************************************************************************/ 542 static void fix_resources(struct bus_node *bus_cur) 543 { 544 struct range_node *range; 545 struct resource_node *res; 546 547 debug("%s - bus_cur->busno = %d\n", __func__, bus_cur->busno); 548 549 if (bus_cur->needIOUpdate) { 550 res = bus_cur->firstIO; 551 range = bus_cur->rangeIO; 552 fix_me(res, bus_cur, range); 553 } 554 if (bus_cur->needMemUpdate) { 555 res = bus_cur->firstMem; 556 range = bus_cur->rangeMem; 557 fix_me(res, bus_cur, range); 558 } 559 if (bus_cur->needPFMemUpdate) { 560 res = bus_cur->firstPFMem; 561 range = bus_cur->rangePFMem; 562 fix_me(res, bus_cur, range); 563 } 564 } 565 566 /******************************************************************************* 567 * This routine adds a resource to the list of resources to the appropriate bus 568 * based on their resource type and sorted by their starting addresses. It assigns 569 * the ptrs to next and nextRange if needed. 570 * 571 * Input: resource ptr 572 * Output: ptrs assigned (to the node) 573 * 0 or -1 574 *******************************************************************************/ 575 int ibmphp_add_resource(struct resource_node *res) 576 { 577 struct resource_node *res_cur; 578 struct resource_node *res_prev; 579 struct bus_node *bus_cur; 580 struct range_node *range_cur = NULL; 581 struct resource_node *res_start = NULL; 582 583 debug("%s - enter\n", __func__); 584 585 if (!res) { 586 err("NULL passed to add\n"); 587 return -ENODEV; 588 } 589 590 bus_cur = find_bus_wprev(res->busno, NULL, 0); 591 592 if (!bus_cur) { 593 /* didn't find a bus, something's wrong!!! */ 594 debug("no bus in the system, either pci_dev's wrong or allocation failed\n"); 595 return -ENODEV; 596 } 597 598 /* Normal case */ 599 switch (res->type) { 600 case IO: 601 range_cur = bus_cur->rangeIO; 602 res_start = bus_cur->firstIO; 603 break; 604 case MEM: 605 range_cur = bus_cur->rangeMem; 606 res_start = bus_cur->firstMem; 607 break; 608 case PFMEM: 609 range_cur = bus_cur->rangePFMem; 610 res_start = bus_cur->firstPFMem; 611 break; 612 default: 613 err("cannot read the type of the resource to add... problem\n"); 614 return -EINVAL; 615 } 616 while (range_cur) { 617 if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) { 618 res->rangeno = range_cur->rangeno; 619 break; 620 } 621 range_cur = range_cur->next; 622 } 623 624 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 625 * this is again the case of rangeno = -1 626 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 627 */ 628 629 if (!range_cur) { 630 switch (res->type) { 631 case IO: 632 ++bus_cur->needIOUpdate; 633 break; 634 case MEM: 635 ++bus_cur->needMemUpdate; 636 break; 637 case PFMEM: 638 ++bus_cur->needPFMemUpdate; 639 break; 640 } 641 res->rangeno = -1; 642 } 643 644 debug("The range is %d\n", res->rangeno); 645 if (!res_start) { 646 /* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */ 647 switch (res->type) { 648 case IO: 649 bus_cur->firstIO = res; 650 break; 651 case MEM: 652 bus_cur->firstMem = res; 653 break; 654 case PFMEM: 655 bus_cur->firstPFMem = res; 656 break; 657 } 658 res->next = NULL; 659 res->nextRange = NULL; 660 } else { 661 res_cur = res_start; 662 res_prev = NULL; 663 664 debug("res_cur->rangeno is %d\n", res_cur->rangeno); 665 666 while (res_cur) { 667 if (res_cur->rangeno >= res->rangeno) 668 break; 669 res_prev = res_cur; 670 if (res_cur->next) 671 res_cur = res_cur->next; 672 else 673 res_cur = res_cur->nextRange; 674 } 675 676 if (!res_cur) { 677 /* at the end of the resource list */ 678 debug("i should be here, [%x - %x]\n", res->start, res->end); 679 res_prev->nextRange = res; 680 res->next = NULL; 681 res->nextRange = NULL; 682 } else if (res_cur->rangeno == res->rangeno) { 683 /* in the same range */ 684 while (res_cur) { 685 if (res->start < res_cur->start) 686 break; 687 res_prev = res_cur; 688 res_cur = res_cur->next; 689 } 690 if (!res_cur) { 691 /* the last resource in this range */ 692 res_prev->next = res; 693 res->next = NULL; 694 res->nextRange = res_prev->nextRange; 695 res_prev->nextRange = NULL; 696 } else if (res->start < res_cur->start) { 697 /* at the beginning or middle of the range */ 698 if (!res_prev) { 699 switch (res->type) { 700 case IO: 701 bus_cur->firstIO = res; 702 break; 703 case MEM: 704 bus_cur->firstMem = res; 705 break; 706 case PFMEM: 707 bus_cur->firstPFMem = res; 708 break; 709 } 710 } else if (res_prev->rangeno == res_cur->rangeno) 711 res_prev->next = res; 712 else 713 res_prev->nextRange = res; 714 715 res->next = res_cur; 716 res->nextRange = NULL; 717 } 718 } else { 719 /* this is the case where it is 1st occurrence of the range */ 720 if (!res_prev) { 721 /* at the beginning of the resource list */ 722 res->next = NULL; 723 switch (res->type) { 724 case IO: 725 res->nextRange = bus_cur->firstIO; 726 bus_cur->firstIO = res; 727 break; 728 case MEM: 729 res->nextRange = bus_cur->firstMem; 730 bus_cur->firstMem = res; 731 break; 732 case PFMEM: 733 res->nextRange = bus_cur->firstPFMem; 734 bus_cur->firstPFMem = res; 735 break; 736 } 737 } else if (res_cur->rangeno > res->rangeno) { 738 /* in the middle of the resource list */ 739 res_prev->nextRange = res; 740 res->next = NULL; 741 res->nextRange = res_cur; 742 } 743 } 744 } 745 746 debug("%s - exit\n", __func__); 747 return 0; 748 } 749 750 /**************************************************************************** 751 * This routine will remove the resource from the list of resources 752 * 753 * Input: io, mem, and/or pfmem resource to be deleted 754 * Output: modified resource list 755 * 0 or error code 756 ****************************************************************************/ 757 int ibmphp_remove_resource(struct resource_node *res) 758 { 759 struct bus_node *bus_cur; 760 struct resource_node *res_cur = NULL; 761 struct resource_node *res_prev; 762 struct resource_node *mem_cur; 763 char *type = ""; 764 765 if (!res) { 766 err("resource to remove is NULL\n"); 767 return -ENODEV; 768 } 769 770 bus_cur = find_bus_wprev(res->busno, NULL, 0); 771 772 if (!bus_cur) { 773 err("cannot find corresponding bus of the io resource to remove bailing out...\n"); 774 return -ENODEV; 775 } 776 777 switch (res->type) { 778 case IO: 779 res_cur = bus_cur->firstIO; 780 type = "io"; 781 break; 782 case MEM: 783 res_cur = bus_cur->firstMem; 784 type = "mem"; 785 break; 786 case PFMEM: 787 res_cur = bus_cur->firstPFMem; 788 type = "pfmem"; 789 break; 790 default: 791 err("unknown type for resource to remove\n"); 792 return -EINVAL; 793 } 794 res_prev = NULL; 795 796 while (res_cur) { 797 if ((res_cur->start == res->start) && (res_cur->end == res->end)) 798 break; 799 res_prev = res_cur; 800 if (res_cur->next) 801 res_cur = res_cur->next; 802 else 803 res_cur = res_cur->nextRange; 804 } 805 806 if (!res_cur) { 807 if (res->type == PFMEM) { 808 /* 809 * case where pfmem might be in the PFMemFromMem list 810 * so will also need to remove the corresponding mem 811 * entry 812 */ 813 res_cur = bus_cur->firstPFMemFromMem; 814 res_prev = NULL; 815 816 while (res_cur) { 817 if ((res_cur->start == res->start) && (res_cur->end == res->end)) { 818 mem_cur = bus_cur->firstMem; 819 while (mem_cur) { 820 if ((mem_cur->start == res_cur->start) 821 && (mem_cur->end == res_cur->end)) 822 break; 823 if (mem_cur->next) 824 mem_cur = mem_cur->next; 825 else 826 mem_cur = mem_cur->nextRange; 827 } 828 if (!mem_cur) { 829 err("cannot find corresponding mem node for pfmem...\n"); 830 return -EINVAL; 831 } 832 833 ibmphp_remove_resource(mem_cur); 834 if (!res_prev) 835 bus_cur->firstPFMemFromMem = res_cur->next; 836 else 837 res_prev->next = res_cur->next; 838 kfree(res_cur); 839 return 0; 840 } 841 res_prev = res_cur; 842 if (res_cur->next) 843 res_cur = res_cur->next; 844 else 845 res_cur = res_cur->nextRange; 846 } 847 if (!res_cur) { 848 err("cannot find pfmem to delete...\n"); 849 return -EINVAL; 850 } 851 } else { 852 err("the %s resource is not in the list to be deleted...\n", type); 853 return -EINVAL; 854 } 855 } 856 if (!res_prev) { 857 /* first device to be deleted */ 858 if (res_cur->next) { 859 switch (res->type) { 860 case IO: 861 bus_cur->firstIO = res_cur->next; 862 break; 863 case MEM: 864 bus_cur->firstMem = res_cur->next; 865 break; 866 case PFMEM: 867 bus_cur->firstPFMem = res_cur->next; 868 break; 869 } 870 } else if (res_cur->nextRange) { 871 switch (res->type) { 872 case IO: 873 bus_cur->firstIO = res_cur->nextRange; 874 break; 875 case MEM: 876 bus_cur->firstMem = res_cur->nextRange; 877 break; 878 case PFMEM: 879 bus_cur->firstPFMem = res_cur->nextRange; 880 break; 881 } 882 } else { 883 switch (res->type) { 884 case IO: 885 bus_cur->firstIO = NULL; 886 break; 887 case MEM: 888 bus_cur->firstMem = NULL; 889 break; 890 case PFMEM: 891 bus_cur->firstPFMem = NULL; 892 break; 893 } 894 } 895 kfree(res_cur); 896 return 0; 897 } else { 898 if (res_cur->next) { 899 if (res_prev->rangeno == res_cur->rangeno) 900 res_prev->next = res_cur->next; 901 else 902 res_prev->nextRange = res_cur->next; 903 } else if (res_cur->nextRange) { 904 res_prev->next = NULL; 905 res_prev->nextRange = res_cur->nextRange; 906 } else { 907 res_prev->next = NULL; 908 res_prev->nextRange = NULL; 909 } 910 kfree(res_cur); 911 return 0; 912 } 913 914 return 0; 915 } 916 917 static struct range_node *find_range(struct bus_node *bus_cur, struct resource_node *res) 918 { 919 struct range_node *range = NULL; 920 921 switch (res->type) { 922 case IO: 923 range = bus_cur->rangeIO; 924 break; 925 case MEM: 926 range = bus_cur->rangeMem; 927 break; 928 case PFMEM: 929 range = bus_cur->rangePFMem; 930 break; 931 default: 932 err("cannot read resource type in find_range\n"); 933 } 934 935 while (range) { 936 if (res->rangeno == range->rangeno) 937 break; 938 range = range->next; 939 } 940 return range; 941 } 942 943 /***************************************************************************** 944 * This routine will check to make sure the io/mem/pfmem->len that the device asked for 945 * can fit w/i our list of available IO/MEM/PFMEM resources. If cannot, returns -EINVAL, 946 * otherwise, returns 0 947 * 948 * Input: resource 949 * Output: the correct start and end address are inputted into the resource node, 950 * 0 or -EINVAL 951 *****************************************************************************/ 952 int ibmphp_check_resource(struct resource_node *res, u8 bridge) 953 { 954 struct bus_node *bus_cur; 955 struct range_node *range = NULL; 956 struct resource_node *res_prev; 957 struct resource_node *res_cur = NULL; 958 u32 len_cur = 0, start_cur = 0, len_tmp = 0; 959 int noranges = 0; 960 u32 tmp_start; /* this is to make sure start address is divisible by the length needed */ 961 u32 tmp_divide; 962 u8 flag = 0; 963 964 if (!res) 965 return -EINVAL; 966 967 if (bridge) { 968 /* The rules for bridges are different, 4K divisible for IO, 1M for (pf)mem*/ 969 if (res->type == IO) 970 tmp_divide = IOBRIDGE; 971 else 972 tmp_divide = MEMBRIDGE; 973 } else 974 tmp_divide = res->len; 975 976 bus_cur = find_bus_wprev(res->busno, NULL, 0); 977 978 if (!bus_cur) { 979 /* didn't find a bus, something's wrong!!! */ 980 debug("no bus in the system, either pci_dev's wrong or allocation failed\n"); 981 return -EINVAL; 982 } 983 984 debug("%s - enter\n", __func__); 985 debug("bus_cur->busno is %d\n", bus_cur->busno); 986 987 /* This is a quick fix to not mess up with the code very much. i.e., 988 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */ 989 res->len -= 1; 990 991 switch (res->type) { 992 case IO: 993 res_cur = bus_cur->firstIO; 994 noranges = bus_cur->noIORanges; 995 break; 996 case MEM: 997 res_cur = bus_cur->firstMem; 998 noranges = bus_cur->noMemRanges; 999 break; 1000 case PFMEM: 1001 res_cur = bus_cur->firstPFMem; 1002 noranges = bus_cur->noPFMemRanges; 1003 break; 1004 default: 1005 err("wrong type of resource to check\n"); 1006 return -EINVAL; 1007 } 1008 res_prev = NULL; 1009 1010 while (res_cur) { 1011 range = find_range(bus_cur, res_cur); 1012 debug("%s - rangeno = %d\n", __func__, res_cur->rangeno); 1013 1014 if (!range) { 1015 err("no range for the device exists... bailing out...\n"); 1016 return -EINVAL; 1017 } 1018 1019 /* found our range */ 1020 if (!res_prev) { 1021 /* first time in the loop */ 1022 len_tmp = res_cur->start - 1 - range->start; 1023 1024 if ((res_cur->start != range->start) && (len_tmp >= res->len)) { 1025 debug("len_tmp = %x\n", len_tmp); 1026 1027 if ((len_tmp < len_cur) || (len_cur == 0)) { 1028 1029 if ((range->start % tmp_divide) == 0) { 1030 /* just perfect, starting address is divisible by length */ 1031 flag = 1; 1032 len_cur = len_tmp; 1033 start_cur = range->start; 1034 } else { 1035 /* Needs adjusting */ 1036 tmp_start = range->start; 1037 flag = 0; 1038 1039 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) { 1040 if ((tmp_start % tmp_divide) == 0) { 1041 flag = 1; 1042 len_cur = len_tmp; 1043 start_cur = tmp_start; 1044 break; 1045 } 1046 tmp_start += tmp_divide - tmp_start % tmp_divide; 1047 if (tmp_start >= res_cur->start - 1) 1048 break; 1049 } 1050 } 1051 1052 if (flag && len_cur == res->len) { 1053 debug("but we are not here, right?\n"); 1054 res->start = start_cur; 1055 res->len += 1; /* To restore the balance */ 1056 res->end = res->start + res->len - 1; 1057 return 0; 1058 } 1059 } 1060 } 1061 } 1062 if (!res_cur->next) { 1063 /* last device on the range */ 1064 len_tmp = range->end - (res_cur->end + 1); 1065 1066 if ((range->end != res_cur->end) && (len_tmp >= res->len)) { 1067 debug("len_tmp = %x\n", len_tmp); 1068 if ((len_tmp < len_cur) || (len_cur == 0)) { 1069 1070 if (((res_cur->end + 1) % tmp_divide) == 0) { 1071 /* just perfect, starting address is divisible by length */ 1072 flag = 1; 1073 len_cur = len_tmp; 1074 start_cur = res_cur->end + 1; 1075 } else { 1076 /* Needs adjusting */ 1077 tmp_start = res_cur->end + 1; 1078 flag = 0; 1079 1080 while ((len_tmp = range->end - tmp_start) >= res->len) { 1081 if ((tmp_start % tmp_divide) == 0) { 1082 flag = 1; 1083 len_cur = len_tmp; 1084 start_cur = tmp_start; 1085 break; 1086 } 1087 tmp_start += tmp_divide - tmp_start % tmp_divide; 1088 if (tmp_start >= range->end) 1089 break; 1090 } 1091 } 1092 if (flag && len_cur == res->len) { 1093 res->start = start_cur; 1094 res->len += 1; /* To restore the balance */ 1095 res->end = res->start + res->len - 1; 1096 return 0; 1097 } 1098 } 1099 } 1100 } 1101 1102 if (res_prev) { 1103 if (res_prev->rangeno != res_cur->rangeno) { 1104 /* 1st device on this range */ 1105 len_tmp = res_cur->start - 1 - range->start; 1106 1107 if ((res_cur->start != range->start) && (len_tmp >= res->len)) { 1108 if ((len_tmp < len_cur) || (len_cur == 0)) { 1109 if ((range->start % tmp_divide) == 0) { 1110 /* just perfect, starting address is divisible by length */ 1111 flag = 1; 1112 len_cur = len_tmp; 1113 start_cur = range->start; 1114 } else { 1115 /* Needs adjusting */ 1116 tmp_start = range->start; 1117 flag = 0; 1118 1119 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) { 1120 if ((tmp_start % tmp_divide) == 0) { 1121 flag = 1; 1122 len_cur = len_tmp; 1123 start_cur = tmp_start; 1124 break; 1125 } 1126 tmp_start += tmp_divide - tmp_start % tmp_divide; 1127 if (tmp_start >= res_cur->start - 1) 1128 break; 1129 } 1130 } 1131 1132 if (flag && len_cur == res->len) { 1133 res->start = start_cur; 1134 res->len += 1; /* To restore the balance */ 1135 res->end = res->start + res->len - 1; 1136 return 0; 1137 } 1138 } 1139 } 1140 } else { 1141 /* in the same range */ 1142 len_tmp = res_cur->start - 1 - res_prev->end - 1; 1143 1144 if (len_tmp >= res->len) { 1145 if ((len_tmp < len_cur) || (len_cur == 0)) { 1146 if (((res_prev->end + 1) % tmp_divide) == 0) { 1147 /* just perfect, starting address's divisible by length */ 1148 flag = 1; 1149 len_cur = len_tmp; 1150 start_cur = res_prev->end + 1; 1151 } else { 1152 /* Needs adjusting */ 1153 tmp_start = res_prev->end + 1; 1154 flag = 0; 1155 1156 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) { 1157 if ((tmp_start % tmp_divide) == 0) { 1158 flag = 1; 1159 len_cur = len_tmp; 1160 start_cur = tmp_start; 1161 break; 1162 } 1163 tmp_start += tmp_divide - tmp_start % tmp_divide; 1164 if (tmp_start >= res_cur->start - 1) 1165 break; 1166 } 1167 } 1168 1169 if (flag && len_cur == res->len) { 1170 res->start = start_cur; 1171 res->len += 1; /* To restore the balance */ 1172 res->end = res->start + res->len - 1; 1173 return 0; 1174 } 1175 } 1176 } 1177 } 1178 } 1179 /* end if (res_prev) */ 1180 res_prev = res_cur; 1181 if (res_cur->next) 1182 res_cur = res_cur->next; 1183 else 1184 res_cur = res_cur->nextRange; 1185 } /* end of while */ 1186 1187 1188 if (!res_prev) { 1189 /* 1st device ever */ 1190 /* need to find appropriate range */ 1191 switch (res->type) { 1192 case IO: 1193 range = bus_cur->rangeIO; 1194 break; 1195 case MEM: 1196 range = bus_cur->rangeMem; 1197 break; 1198 case PFMEM: 1199 range = bus_cur->rangePFMem; 1200 break; 1201 } 1202 while (range) { 1203 len_tmp = range->end - range->start; 1204 1205 if (len_tmp >= res->len) { 1206 if ((len_tmp < len_cur) || (len_cur == 0)) { 1207 if ((range->start % tmp_divide) == 0) { 1208 /* just perfect, starting address's divisible by length */ 1209 flag = 1; 1210 len_cur = len_tmp; 1211 start_cur = range->start; 1212 } else { 1213 /* Needs adjusting */ 1214 tmp_start = range->start; 1215 flag = 0; 1216 1217 while ((len_tmp = range->end - tmp_start) >= res->len) { 1218 if ((tmp_start % tmp_divide) == 0) { 1219 flag = 1; 1220 len_cur = len_tmp; 1221 start_cur = tmp_start; 1222 break; 1223 } 1224 tmp_start += tmp_divide - tmp_start % tmp_divide; 1225 if (tmp_start >= range->end) 1226 break; 1227 } 1228 } 1229 1230 if (flag && len_cur == res->len) { 1231 res->start = start_cur; 1232 res->len += 1; /* To restore the balance */ 1233 res->end = res->start + res->len - 1; 1234 return 0; 1235 } 1236 } 1237 } 1238 range = range->next; 1239 } /* end of while */ 1240 1241 if ((!range) && (len_cur == 0)) { 1242 /* have gone through the list of devices and ranges and haven't found n.e.thing */ 1243 err("no appropriate range.. bailing out...\n"); 1244 return -EINVAL; 1245 } else if (len_cur) { 1246 res->start = start_cur; 1247 res->len += 1; /* To restore the balance */ 1248 res->end = res->start + res->len - 1; 1249 return 0; 1250 } 1251 } 1252 1253 if (!res_cur) { 1254 debug("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges); 1255 if (res_prev->rangeno < noranges) { 1256 /* if there're more ranges out there to check */ 1257 switch (res->type) { 1258 case IO: 1259 range = bus_cur->rangeIO; 1260 break; 1261 case MEM: 1262 range = bus_cur->rangeMem; 1263 break; 1264 case PFMEM: 1265 range = bus_cur->rangePFMem; 1266 break; 1267 } 1268 while (range) { 1269 len_tmp = range->end - range->start; 1270 1271 if (len_tmp >= res->len) { 1272 if ((len_tmp < len_cur) || (len_cur == 0)) { 1273 if ((range->start % tmp_divide) == 0) { 1274 /* just perfect, starting address's divisible by length */ 1275 flag = 1; 1276 len_cur = len_tmp; 1277 start_cur = range->start; 1278 } else { 1279 /* Needs adjusting */ 1280 tmp_start = range->start; 1281 flag = 0; 1282 1283 while ((len_tmp = range->end - tmp_start) >= res->len) { 1284 if ((tmp_start % tmp_divide) == 0) { 1285 flag = 1; 1286 len_cur = len_tmp; 1287 start_cur = tmp_start; 1288 break; 1289 } 1290 tmp_start += tmp_divide - tmp_start % tmp_divide; 1291 if (tmp_start >= range->end) 1292 break; 1293 } 1294 } 1295 1296 if (flag && len_cur == res->len) { 1297 res->start = start_cur; 1298 res->len += 1; /* To restore the balance */ 1299 res->end = res->start + res->len - 1; 1300 return 0; 1301 } 1302 } 1303 } 1304 range = range->next; 1305 } /* end of while */ 1306 1307 if ((!range) && (len_cur == 0)) { 1308 /* have gone through the list of devices and ranges and haven't found n.e.thing */ 1309 err("no appropriate range.. bailing out...\n"); 1310 return -EINVAL; 1311 } else if (len_cur) { 1312 res->start = start_cur; 1313 res->len += 1; /* To restore the balance */ 1314 res->end = res->start + res->len - 1; 1315 return 0; 1316 } 1317 } else { 1318 /* no more ranges to check on */ 1319 if (len_cur) { 1320 res->start = start_cur; 1321 res->len += 1; /* To restore the balance */ 1322 res->end = res->start + res->len - 1; 1323 return 0; 1324 } else { 1325 /* have gone through the list of devices and haven't found n.e.thing */ 1326 err("no appropriate range.. bailing out...\n"); 1327 return -EINVAL; 1328 } 1329 } 1330 } /* end if (!res_cur) */ 1331 return -EINVAL; 1332 } 1333 1334 /******************************************************************************** 1335 * This routine is called from remove_card if the card contained PPB. 1336 * It will remove all the resources on the bus as well as the bus itself 1337 * Input: Bus 1338 * Output: 0, -ENODEV 1339 ********************************************************************************/ 1340 int ibmphp_remove_bus(struct bus_node *bus, u8 parent_busno) 1341 { 1342 struct resource_node *res_cur; 1343 struct resource_node *res_tmp; 1344 struct bus_node *prev_bus; 1345 int rc; 1346 1347 prev_bus = find_bus_wprev(parent_busno, NULL, 0); 1348 1349 if (!prev_bus) { 1350 debug("something terribly wrong. Cannot find parent bus to the one to remove\n"); 1351 return -ENODEV; 1352 } 1353 1354 debug("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno); 1355 1356 rc = remove_ranges(bus, prev_bus); 1357 if (rc) 1358 return rc; 1359 1360 if (bus->firstIO) { 1361 res_cur = bus->firstIO; 1362 while (res_cur) { 1363 res_tmp = res_cur; 1364 if (res_cur->next) 1365 res_cur = res_cur->next; 1366 else 1367 res_cur = res_cur->nextRange; 1368 kfree(res_tmp); 1369 res_tmp = NULL; 1370 } 1371 bus->firstIO = NULL; 1372 } 1373 if (bus->firstMem) { 1374 res_cur = bus->firstMem; 1375 while (res_cur) { 1376 res_tmp = res_cur; 1377 if (res_cur->next) 1378 res_cur = res_cur->next; 1379 else 1380 res_cur = res_cur->nextRange; 1381 kfree(res_tmp); 1382 res_tmp = NULL; 1383 } 1384 bus->firstMem = NULL; 1385 } 1386 if (bus->firstPFMem) { 1387 res_cur = bus->firstPFMem; 1388 while (res_cur) { 1389 res_tmp = res_cur; 1390 if (res_cur->next) 1391 res_cur = res_cur->next; 1392 else 1393 res_cur = res_cur->nextRange; 1394 kfree(res_tmp); 1395 res_tmp = NULL; 1396 } 1397 bus->firstPFMem = NULL; 1398 } 1399 1400 if (bus->firstPFMemFromMem) { 1401 res_cur = bus->firstPFMemFromMem; 1402 while (res_cur) { 1403 res_tmp = res_cur; 1404 res_cur = res_cur->next; 1405 1406 kfree(res_tmp); 1407 res_tmp = NULL; 1408 } 1409 bus->firstPFMemFromMem = NULL; 1410 } 1411 1412 list_del(&bus->bus_list); 1413 kfree(bus); 1414 return 0; 1415 } 1416 1417 /****************************************************************************** 1418 * This routine deletes the ranges from a given bus, and the entries from the 1419 * parent's bus in the resources 1420 * Input: current bus, previous bus 1421 * Output: 0, -EINVAL 1422 ******************************************************************************/ 1423 static int remove_ranges(struct bus_node *bus_cur, struct bus_node *bus_prev) 1424 { 1425 struct range_node *range_cur; 1426 struct range_node *range_tmp; 1427 int i; 1428 struct resource_node *res = NULL; 1429 1430 if (bus_cur->noIORanges) { 1431 range_cur = bus_cur->rangeIO; 1432 for (i = 0; i < bus_cur->noIORanges; i++) { 1433 if (ibmphp_find_resource(bus_prev, range_cur->start, &res, IO) < 0) 1434 return -EINVAL; 1435 ibmphp_remove_resource(res); 1436 1437 range_tmp = range_cur; 1438 range_cur = range_cur->next; 1439 kfree(range_tmp); 1440 range_tmp = NULL; 1441 } 1442 bus_cur->rangeIO = NULL; 1443 } 1444 if (bus_cur->noMemRanges) { 1445 range_cur = bus_cur->rangeMem; 1446 for (i = 0; i < bus_cur->noMemRanges; i++) { 1447 if (ibmphp_find_resource(bus_prev, range_cur->start, &res, MEM) < 0) 1448 return -EINVAL; 1449 1450 ibmphp_remove_resource(res); 1451 range_tmp = range_cur; 1452 range_cur = range_cur->next; 1453 kfree(range_tmp); 1454 range_tmp = NULL; 1455 } 1456 bus_cur->rangeMem = NULL; 1457 } 1458 if (bus_cur->noPFMemRanges) { 1459 range_cur = bus_cur->rangePFMem; 1460 for (i = 0; i < bus_cur->noPFMemRanges; i++) { 1461 if (ibmphp_find_resource(bus_prev, range_cur->start, &res, PFMEM) < 0) 1462 return -EINVAL; 1463 1464 ibmphp_remove_resource(res); 1465 range_tmp = range_cur; 1466 range_cur = range_cur->next; 1467 kfree(range_tmp); 1468 range_tmp = NULL; 1469 } 1470 bus_cur->rangePFMem = NULL; 1471 } 1472 return 0; 1473 } 1474 1475 /* 1476 * find the resource node in the bus 1477 * Input: Resource needed, start address of the resource, type of resource 1478 */ 1479 int ibmphp_find_resource(struct bus_node *bus, u32 start_address, struct resource_node **res, int flag) 1480 { 1481 struct resource_node *res_cur = NULL; 1482 char *type = ""; 1483 1484 if (!bus) { 1485 err("The bus passed in NULL to find resource\n"); 1486 return -ENODEV; 1487 } 1488 1489 switch (flag) { 1490 case IO: 1491 res_cur = bus->firstIO; 1492 type = "io"; 1493 break; 1494 case MEM: 1495 res_cur = bus->firstMem; 1496 type = "mem"; 1497 break; 1498 case PFMEM: 1499 res_cur = bus->firstPFMem; 1500 type = "pfmem"; 1501 break; 1502 default: 1503 err("wrong type of flag\n"); 1504 return -EINVAL; 1505 } 1506 1507 while (res_cur) { 1508 if (res_cur->start == start_address) { 1509 *res = res_cur; 1510 break; 1511 } 1512 if (res_cur->next) 1513 res_cur = res_cur->next; 1514 else 1515 res_cur = res_cur->nextRange; 1516 } 1517 1518 if (!res_cur) { 1519 if (flag == PFMEM) { 1520 res_cur = bus->firstPFMemFromMem; 1521 while (res_cur) { 1522 if (res_cur->start == start_address) { 1523 *res = res_cur; 1524 break; 1525 } 1526 res_cur = res_cur->next; 1527 } 1528 if (!res_cur) { 1529 debug("SOS...cannot find %s resource in the bus.\n", type); 1530 return -EINVAL; 1531 } 1532 } else { 1533 debug("SOS... cannot find %s resource in the bus.\n", type); 1534 return -EINVAL; 1535 } 1536 } 1537 1538 if (*res) 1539 debug("*res->start = %x\n", (*res)->start); 1540 1541 return 0; 1542 } 1543 1544 /*********************************************************************** 1545 * This routine will free the resource structures used by the 1546 * system. It is called from cleanup routine for the module 1547 * Parameters: none 1548 * Returns: none 1549 ***********************************************************************/ 1550 void ibmphp_free_resources(void) 1551 { 1552 struct bus_node *bus_cur = NULL, *next; 1553 struct bus_node *bus_tmp; 1554 struct range_node *range_cur; 1555 struct range_node *range_tmp; 1556 struct resource_node *res_cur; 1557 struct resource_node *res_tmp; 1558 int i = 0; 1559 flags = 1; 1560 1561 list_for_each_entry_safe(bus_cur, next, &gbuses, bus_list) { 1562 if (bus_cur->noIORanges) { 1563 range_cur = bus_cur->rangeIO; 1564 for (i = 0; i < bus_cur->noIORanges; i++) { 1565 if (!range_cur) 1566 break; 1567 range_tmp = range_cur; 1568 range_cur = range_cur->next; 1569 kfree(range_tmp); 1570 range_tmp = NULL; 1571 } 1572 } 1573 if (bus_cur->noMemRanges) { 1574 range_cur = bus_cur->rangeMem; 1575 for (i = 0; i < bus_cur->noMemRanges; i++) { 1576 if (!range_cur) 1577 break; 1578 range_tmp = range_cur; 1579 range_cur = range_cur->next; 1580 kfree(range_tmp); 1581 range_tmp = NULL; 1582 } 1583 } 1584 if (bus_cur->noPFMemRanges) { 1585 range_cur = bus_cur->rangePFMem; 1586 for (i = 0; i < bus_cur->noPFMemRanges; i++) { 1587 if (!range_cur) 1588 break; 1589 range_tmp = range_cur; 1590 range_cur = range_cur->next; 1591 kfree(range_tmp); 1592 range_tmp = NULL; 1593 } 1594 } 1595 1596 if (bus_cur->firstIO) { 1597 res_cur = bus_cur->firstIO; 1598 while (res_cur) { 1599 res_tmp = res_cur; 1600 if (res_cur->next) 1601 res_cur = res_cur->next; 1602 else 1603 res_cur = res_cur->nextRange; 1604 kfree(res_tmp); 1605 res_tmp = NULL; 1606 } 1607 bus_cur->firstIO = NULL; 1608 } 1609 if (bus_cur->firstMem) { 1610 res_cur = bus_cur->firstMem; 1611 while (res_cur) { 1612 res_tmp = res_cur; 1613 if (res_cur->next) 1614 res_cur = res_cur->next; 1615 else 1616 res_cur = res_cur->nextRange; 1617 kfree(res_tmp); 1618 res_tmp = NULL; 1619 } 1620 bus_cur->firstMem = NULL; 1621 } 1622 if (bus_cur->firstPFMem) { 1623 res_cur = bus_cur->firstPFMem; 1624 while (res_cur) { 1625 res_tmp = res_cur; 1626 if (res_cur->next) 1627 res_cur = res_cur->next; 1628 else 1629 res_cur = res_cur->nextRange; 1630 kfree(res_tmp); 1631 res_tmp = NULL; 1632 } 1633 bus_cur->firstPFMem = NULL; 1634 } 1635 1636 if (bus_cur->firstPFMemFromMem) { 1637 res_cur = bus_cur->firstPFMemFromMem; 1638 while (res_cur) { 1639 res_tmp = res_cur; 1640 res_cur = res_cur->next; 1641 1642 kfree(res_tmp); 1643 res_tmp = NULL; 1644 } 1645 bus_cur->firstPFMemFromMem = NULL; 1646 } 1647 1648 bus_tmp = bus_cur; 1649 list_del(&bus_cur->bus_list); 1650 kfree(bus_tmp); 1651 bus_tmp = NULL; 1652 } 1653 } 1654 1655 /********************************************************************************* 1656 * This function will go over the PFmem resources to check if the EBDA allocated 1657 * pfmem out of memory buckets of the bus. If so, it will change the range numbers 1658 * and a flag to indicate that this resource is out of memory. It will also move the 1659 * Pfmem out of the pfmem resource list to the PFMemFromMem list, and will create 1660 * a new Mem node 1661 * This routine is called right after initialization 1662 *******************************************************************************/ 1663 static int __init once_over(void) 1664 { 1665 struct resource_node *pfmem_cur; 1666 struct resource_node *pfmem_prev; 1667 struct resource_node *mem; 1668 struct bus_node *bus_cur; 1669 1670 list_for_each_entry(bus_cur, &gbuses, bus_list) { 1671 if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) { 1672 for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) { 1673 pfmem_cur->fromMem = 1; 1674 if (pfmem_prev) 1675 pfmem_prev->next = pfmem_cur->next; 1676 else 1677 bus_cur->firstPFMem = pfmem_cur->next; 1678 1679 if (!bus_cur->firstPFMemFromMem) 1680 pfmem_cur->next = NULL; 1681 else 1682 /* we don't need to sort PFMemFromMem since we're using mem node for 1683 all the real work anyways, so just insert at the beginning of the 1684 list 1685 */ 1686 pfmem_cur->next = bus_cur->firstPFMemFromMem; 1687 1688 bus_cur->firstPFMemFromMem = pfmem_cur; 1689 1690 mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); 1691 if (!mem) 1692 return -ENOMEM; 1693 1694 mem->type = MEM; 1695 mem->busno = pfmem_cur->busno; 1696 mem->devfunc = pfmem_cur->devfunc; 1697 mem->start = pfmem_cur->start; 1698 mem->end = pfmem_cur->end; 1699 mem->len = pfmem_cur->len; 1700 if (ibmphp_add_resource(mem) < 0) 1701 err("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n"); 1702 pfmem_cur->rangeno = mem->rangeno; 1703 } /* end for pfmem */ 1704 } /* end if */ 1705 } /* end list_for_each bus */ 1706 return 0; 1707 } 1708 1709 int ibmphp_add_pfmem_from_mem(struct resource_node *pfmem) 1710 { 1711 struct bus_node *bus_cur = find_bus_wprev(pfmem->busno, NULL, 0); 1712 1713 if (!bus_cur) { 1714 err("cannot find bus of pfmem to add...\n"); 1715 return -ENODEV; 1716 } 1717 1718 if (bus_cur->firstPFMemFromMem) 1719 pfmem->next = bus_cur->firstPFMemFromMem; 1720 else 1721 pfmem->next = NULL; 1722 1723 bus_cur->firstPFMemFromMem = pfmem; 1724 1725 return 0; 1726 } 1727 1728 /* This routine just goes through the buses to see if the bus already exists. 1729 * It is called from ibmphp_find_sec_number, to find out a secondary bus number for 1730 * bridged cards 1731 * Parameters: bus_number 1732 * Returns: Bus pointer or NULL 1733 */ 1734 struct bus_node *ibmphp_find_res_bus(u8 bus_number) 1735 { 1736 return find_bus_wprev(bus_number, NULL, 0); 1737 } 1738 1739 static struct bus_node *find_bus_wprev(u8 bus_number, struct bus_node **prev, u8 flag) 1740 { 1741 struct bus_node *bus_cur; 1742 1743 list_for_each_entry(bus_cur, &gbuses, bus_list) { 1744 if (flag) 1745 *prev = list_prev_entry(bus_cur, bus_list); 1746 if (bus_cur->busno == bus_number) 1747 return bus_cur; 1748 } 1749 1750 return NULL; 1751 } 1752 1753 void ibmphp_print_test(void) 1754 { 1755 int i = 0; 1756 struct bus_node *bus_cur = NULL; 1757 struct range_node *range; 1758 struct resource_node *res; 1759 1760 debug_pci("*****************START**********************\n"); 1761 1762 if ((!list_empty(&gbuses)) && flags) { 1763 err("The GBUSES is not NULL?!?!?!?!?\n"); 1764 return; 1765 } 1766 1767 list_for_each_entry(bus_cur, &gbuses, bus_list) { 1768 debug_pci ("This is bus # %d. There are\n", bus_cur->busno); 1769 debug_pci ("IORanges = %d\t", bus_cur->noIORanges); 1770 debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges); 1771 debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges); 1772 debug_pci ("The IO Ranges are as follows:\n"); 1773 if (bus_cur->rangeIO) { 1774 range = bus_cur->rangeIO; 1775 for (i = 0; i < bus_cur->noIORanges; i++) { 1776 debug_pci("rangeno is %d\n", range->rangeno); 1777 debug_pci("[%x - %x]\n", range->start, range->end); 1778 range = range->next; 1779 } 1780 } 1781 1782 debug_pci("The Mem Ranges are as follows:\n"); 1783 if (bus_cur->rangeMem) { 1784 range = bus_cur->rangeMem; 1785 for (i = 0; i < bus_cur->noMemRanges; i++) { 1786 debug_pci("rangeno is %d\n", range->rangeno); 1787 debug_pci("[%x - %x]\n", range->start, range->end); 1788 range = range->next; 1789 } 1790 } 1791 1792 debug_pci("The PFMem Ranges are as follows:\n"); 1793 1794 if (bus_cur->rangePFMem) { 1795 range = bus_cur->rangePFMem; 1796 for (i = 0; i < bus_cur->noPFMemRanges; i++) { 1797 debug_pci("rangeno is %d\n", range->rangeno); 1798 debug_pci("[%x - %x]\n", range->start, range->end); 1799 range = range->next; 1800 } 1801 } 1802 1803 debug_pci("The resources on this bus are as follows\n"); 1804 1805 debug_pci("IO...\n"); 1806 if (bus_cur->firstIO) { 1807 res = bus_cur->firstIO; 1808 while (res) { 1809 debug_pci("The range # is %d\n", res->rangeno); 1810 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); 1811 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len); 1812 if (res->next) 1813 res = res->next; 1814 else if (res->nextRange) 1815 res = res->nextRange; 1816 else 1817 break; 1818 } 1819 } 1820 debug_pci("Mem...\n"); 1821 if (bus_cur->firstMem) { 1822 res = bus_cur->firstMem; 1823 while (res) { 1824 debug_pci("The range # is %d\n", res->rangeno); 1825 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); 1826 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len); 1827 if (res->next) 1828 res = res->next; 1829 else if (res->nextRange) 1830 res = res->nextRange; 1831 else 1832 break; 1833 } 1834 } 1835 debug_pci("PFMem...\n"); 1836 if (bus_cur->firstPFMem) { 1837 res = bus_cur->firstPFMem; 1838 while (res) { 1839 debug_pci("The range # is %d\n", res->rangeno); 1840 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); 1841 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len); 1842 if (res->next) 1843 res = res->next; 1844 else if (res->nextRange) 1845 res = res->nextRange; 1846 else 1847 break; 1848 } 1849 } 1850 1851 debug_pci("PFMemFromMem...\n"); 1852 if (bus_cur->firstPFMemFromMem) { 1853 res = bus_cur->firstPFMemFromMem; 1854 while (res) { 1855 debug_pci("The range # is %d\n", res->rangeno); 1856 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); 1857 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len); 1858 res = res->next; 1859 } 1860 } 1861 } 1862 debug_pci("***********************END***********************\n"); 1863 } 1864 1865 static int range_exists_already(struct range_node *range, struct bus_node *bus_cur, u8 type) 1866 { 1867 struct range_node *range_cur = NULL; 1868 switch (type) { 1869 case IO: 1870 range_cur = bus_cur->rangeIO; 1871 break; 1872 case MEM: 1873 range_cur = bus_cur->rangeMem; 1874 break; 1875 case PFMEM: 1876 range_cur = bus_cur->rangePFMem; 1877 break; 1878 default: 1879 err("wrong type passed to find out if range already exists\n"); 1880 return -ENODEV; 1881 } 1882 1883 while (range_cur) { 1884 if ((range_cur->start == range->start) && (range_cur->end == range->end)) 1885 return 1; 1886 range_cur = range_cur->next; 1887 } 1888 1889 return 0; 1890 } 1891 1892 /* This routine will read the windows for any PPB we have and update the 1893 * range info for the secondary bus, and will also input this info into 1894 * primary bus, since BIOS doesn't. This is for PPB that are in the system 1895 * on bootup. For bridged cards that were added during previous load of the 1896 * driver, only the ranges and the bus structure are added, the devices are 1897 * added from NVRAM 1898 * Input: primary busno 1899 * Returns: none 1900 * Note: this function doesn't take into account IO restrictions etc, 1901 * so will only work for bridges with no video/ISA devices behind them It 1902 * also will not work for onboard PPBs that can have more than 1 *bus 1903 * behind them All these are TO DO. 1904 * Also need to add more error checkings... (from fnc returns etc) 1905 */ 1906 static int __init update_bridge_ranges(struct bus_node **bus) 1907 { 1908 u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address; 1909 u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address; 1910 u32 start_address, end_address, upper_start, upper_end; 1911 struct bus_node *bus_sec; 1912 struct bus_node *bus_cur; 1913 struct resource_node *io; 1914 struct resource_node *mem; 1915 struct resource_node *pfmem; 1916 struct range_node *range; 1917 unsigned int devfn; 1918 1919 bus_cur = *bus; 1920 if (!bus_cur) 1921 return -ENODEV; 1922 ibmphp_pci_bus->number = bus_cur->busno; 1923 1924 debug("inside %s\n", __func__); 1925 debug("bus_cur->busno = %x\n", bus_cur->busno); 1926 1927 for (device = 0; device < 32; device++) { 1928 for (function = 0x00; function < 0x08; function++) { 1929 devfn = PCI_DEVFN(device, function); 1930 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id); 1931 1932 if (vendor_id != PCI_VENDOR_ID_NOTVALID) { 1933 /* found correct device!!! */ 1934 pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type); 1935 1936 switch (hdr_type) { 1937 case PCI_HEADER_TYPE_NORMAL: 1938 function = 0x8; 1939 break; 1940 case PCI_HEADER_TYPE_MULTIDEVICE: 1941 break; 1942 case PCI_HEADER_TYPE_BRIDGE: 1943 function = 0x8; 1944 /* fall through */ 1945 case PCI_HEADER_TYPE_MULTIBRIDGE: 1946 /* We assume here that only 1 bus behind the bridge 1947 TO DO: add functionality for several: 1948 temp = secondary; 1949 while (temp < subordinate) { 1950 ... 1951 temp++; 1952 } 1953 */ 1954 pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno); 1955 bus_sec = find_bus_wprev(sec_busno, NULL, 0); 1956 /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */ 1957 if (!bus_sec) { 1958 bus_sec = alloc_error_bus(NULL, sec_busno, 1); 1959 /* the rest will be populated during NVRAM call */ 1960 return 0; 1961 } 1962 pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address); 1963 pci_bus_read_config_byte(ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address); 1964 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start); 1965 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end); 1966 start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8; 1967 start_address |= (upper_io_start << 16); 1968 end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8; 1969 end_address |= (upper_io_end << 16); 1970 1971 if ((start_address) && (start_address <= end_address)) { 1972 range = kzalloc(sizeof(struct range_node), GFP_KERNEL); 1973 if (!range) 1974 return -ENOMEM; 1975 1976 range->start = start_address; 1977 range->end = end_address + 0xfff; 1978 1979 if (bus_sec->noIORanges > 0) { 1980 if (!range_exists_already(range, bus_sec, IO)) { 1981 add_bus_range(IO, range, bus_sec); 1982 ++bus_sec->noIORanges; 1983 } else { 1984 kfree(range); 1985 range = NULL; 1986 } 1987 } else { 1988 /* 1st IO Range on the bus */ 1989 range->rangeno = 1; 1990 bus_sec->rangeIO = range; 1991 ++bus_sec->noIORanges; 1992 } 1993 fix_resources(bus_sec); 1994 1995 if (ibmphp_find_resource(bus_cur, start_address, &io, IO)) { 1996 io = kzalloc(sizeof(struct resource_node), GFP_KERNEL); 1997 if (!io) { 1998 kfree(range); 1999 return -ENOMEM; 2000 } 2001 io->type = IO; 2002 io->busno = bus_cur->busno; 2003 io->devfunc = ((device << 3) | (function & 0x7)); 2004 io->start = start_address; 2005 io->end = end_address + 0xfff; 2006 io->len = io->end - io->start + 1; 2007 ibmphp_add_resource(io); 2008 } 2009 } 2010 2011 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address); 2012 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address); 2013 2014 start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16; 2015 end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16; 2016 2017 if ((start_address) && (start_address <= end_address)) { 2018 2019 range = kzalloc(sizeof(struct range_node), GFP_KERNEL); 2020 if (!range) 2021 return -ENOMEM; 2022 2023 range->start = start_address; 2024 range->end = end_address + 0xfffff; 2025 2026 if (bus_sec->noMemRanges > 0) { 2027 if (!range_exists_already(range, bus_sec, MEM)) { 2028 add_bus_range(MEM, range, bus_sec); 2029 ++bus_sec->noMemRanges; 2030 } else { 2031 kfree(range); 2032 range = NULL; 2033 } 2034 } else { 2035 /* 1st Mem Range on the bus */ 2036 range->rangeno = 1; 2037 bus_sec->rangeMem = range; 2038 ++bus_sec->noMemRanges; 2039 } 2040 2041 fix_resources(bus_sec); 2042 2043 if (ibmphp_find_resource(bus_cur, start_address, &mem, MEM)) { 2044 mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); 2045 if (!mem) { 2046 kfree(range); 2047 return -ENOMEM; 2048 } 2049 mem->type = MEM; 2050 mem->busno = bus_cur->busno; 2051 mem->devfunc = ((device << 3) | (function & 0x7)); 2052 mem->start = start_address; 2053 mem->end = end_address + 0xfffff; 2054 mem->len = mem->end - mem->start + 1; 2055 ibmphp_add_resource(mem); 2056 } 2057 } 2058 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address); 2059 pci_bus_read_config_word(ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address); 2060 pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start); 2061 pci_bus_read_config_dword(ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end); 2062 start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16; 2063 end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16; 2064 #if BITS_PER_LONG == 64 2065 start_address |= ((long) upper_start) << 32; 2066 end_address |= ((long) upper_end) << 32; 2067 #endif 2068 2069 if ((start_address) && (start_address <= end_address)) { 2070 2071 range = kzalloc(sizeof(struct range_node), GFP_KERNEL); 2072 if (!range) 2073 return -ENOMEM; 2074 2075 range->start = start_address; 2076 range->end = end_address + 0xfffff; 2077 2078 if (bus_sec->noPFMemRanges > 0) { 2079 if (!range_exists_already(range, bus_sec, PFMEM)) { 2080 add_bus_range(PFMEM, range, bus_sec); 2081 ++bus_sec->noPFMemRanges; 2082 } else { 2083 kfree(range); 2084 range = NULL; 2085 } 2086 } else { 2087 /* 1st PFMem Range on the bus */ 2088 range->rangeno = 1; 2089 bus_sec->rangePFMem = range; 2090 ++bus_sec->noPFMemRanges; 2091 } 2092 2093 fix_resources(bus_sec); 2094 if (ibmphp_find_resource(bus_cur, start_address, &pfmem, PFMEM)) { 2095 pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); 2096 if (!pfmem) { 2097 kfree(range); 2098 return -ENOMEM; 2099 } 2100 pfmem->type = PFMEM; 2101 pfmem->busno = bus_cur->busno; 2102 pfmem->devfunc = ((device << 3) | (function & 0x7)); 2103 pfmem->start = start_address; 2104 pfmem->end = end_address + 0xfffff; 2105 pfmem->len = pfmem->end - pfmem->start + 1; 2106 pfmem->fromMem = 0; 2107 2108 ibmphp_add_resource(pfmem); 2109 } 2110 } 2111 break; 2112 } /* end of switch */ 2113 } /* end if vendor */ 2114 } /* end for function */ 2115 } /* end for device */ 2116 2117 bus = &bus_cur; 2118 return 0; 2119 } 2120