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