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