Lines Matching +full:bus +full:- +full:range
1 // SPDX-License-Identifier: GPL-2.0+
7 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
49 newbus->busno = busno;
51 newbus->busno = curr->bus_num;
52 list_add_tail(&newbus->bus_list, &gbuses);
69 rs->busno = curr->bus_num;
70 rs->devfunc = curr->dev_fun;
71 rs->start = curr->start_addr;
72 rs->end = curr->end_addr;
73 rs->len = curr->end_addr - curr->start_addr + 1;
86 return -ENOMEM;
88 newbus->busno = curr->bus_num;
93 num_ranges = newbus->noMemRanges;
96 num_ranges = newbus->noPFMemRanges;
99 num_ranges = newbus->noIORanges;
108 return -ENOMEM;
110 newrange->start = curr->start_addr;
111 newrange->end = curr->end_addr;
114 newrange->rangeno = 1;
116 /* need to insert our range */
118 debug("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
123 newbus->rangeMem = newrange;
125 newbus->noMemRanges = 1;
127 debug("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
128 ++newbus->noMemRanges;
133 newbus->rangeIO = newrange;
135 newbus->noIORanges = 1;
137 debug("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
138 ++newbus->noIORanges;
143 newbus->rangePFMem = newrange;
145 newbus->noPFMemRanges = 1;
147 debug("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
148 ++newbus->noPFMemRanges;
164 * 2. If cannot allocate out of PFMem range, allocate from Mem ranges. PFmemFromMem
178 * Output: 0, -1 or error codes
194 if (!(curr->rsrc_type & PCIDEVMASK)) {
200 /* this is a primary bus resource */
201 if (curr->rsrc_type & PRIMARYBUSMASK) {
203 if ((curr->rsrc_type & RESTYPE) == MMASK) {
204 /* no bus structure exists in place yet */
209 list_add_tail(&newbus->bus_list, &gbuses);
210 debug("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
212 bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
213 /* found our bus */
219 /* went through all the buses and didn't find ours, need to create a new bus node */
224 list_add_tail(&newbus->bus_list, &gbuses);
225 debug("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
228 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
231 /* no bus structure exists in place yet */
235 list_add_tail(&newbus->bus_list, &gbuses);
236 debug("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
238 bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
240 /* found our bus */
245 /* went through all the buses and didn't find ours, need to create a new bus node */
249 list_add_tail(&newbus->bus_list, &gbuses);
250 debug("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
253 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
256 /* no bus structure exists in place yet */
260 list_add_tail(&newbus->bus_list, &gbuses);
261 debug("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
263 bus_cur = find_bus_wprev(curr->bus_num, &bus_prev, 1);
269 /* went through all the buses and didn't find ours, need to create a new bus node */
273 list_add_tail(&newbus->bus_list, &gbuses);
274 debug("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
284 if ((curr->rsrc_type & RESTYPE) == MMASK) {
288 return -ENOMEM;
289 new_mem->type = MEM;
291 * if it didn't find the bus, means PCI dev
292 * came b4 the Primary Bus info, so need to
293 * create a bus rangeno becomes a problem...
294 * assign a -1 and then update once the range
300 return -ENOMEM;
301 newbus->firstMem = new_mem;
302 ++newbus->needMemUpdate;
303 new_mem->rangeno = -1;
305 debug("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
307 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
311 return -ENOMEM;
312 new_pfmem->type = PFMEM;
313 new_pfmem->fromMem = 0;
317 return -ENOMEM;
318 newbus->firstPFMem = new_pfmem;
319 ++newbus->needPFMemUpdate;
320 new_pfmem->rangeno = -1;
323 debug("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
324 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
328 return -ENOMEM;
329 new_io->type = IO;
332 * if it didn't find the bus, means PCI dev
333 * came b4 the Primary Bus info, so need to
334 * create a bus rangeno becomes a problem...
335 * Can assign a -1 and then update once the
336 * range actually appears...
341 return -ENOMEM;
342 newbus->firstIO = new_io;
343 ++newbus->needIOUpdate;
344 new_io->rangeno = -1;
346 debug("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
352 /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
357 return once_over(); /* This is to align ranges (so no -1) */
361 * This function adds a range into a sorted list of ranges per bus for a particular
362 * range type, it then calls another routine to update the range numbers on the
365 * Input: type of the resource, range to add, current bus
366 * Output: 0 or -1, bus and range ptrs
368 static int add_bus_range(int type, struct range_node *range, struct bus_node *bus_cur)
377 range_cur = bus_cur->rangeMem;
378 noRanges = bus_cur->noMemRanges;
381 range_cur = bus_cur->rangePFMem;
382 noRanges = bus_cur->noPFMemRanges;
385 range_cur = bus_cur->rangeIO;
386 noRanges = bus_cur->noIORanges;
392 if (range->start < range_cur->start)
395 range_cur = range_cur->next;
399 /* our range will go at the beginning of the list */
402 bus_cur->rangeMem = range;
405 bus_cur->rangePFMem = range;
408 bus_cur->rangeIO = range;
411 range->next = range_cur;
412 range->rangeno = 1;
415 /* our range will go at the end of the list */
416 range->next = NULL;
417 range_prev->next = range;
418 range->rangeno = range_prev->rangeno + 1;
421 /* the range is in the middle */
422 range_prev->next = range;
423 range->next = range_cur;
424 range->rangeno = range_cur->rangeno;
425 i_init = range_prev->rangeno;
429 ++range_cur->rangeno;
430 range_cur = range_cur->next;
439 * the range numbers that they correspond to. It was called from add_bus_range fnc
441 * Input: bus, type of the resource, the rangeno starting from which to update
450 if (bus_cur->firstMem)
451 res = bus_cur->firstMem;
454 if (bus_cur->firstPFMem)
455 res = bus_cur->firstPFMem;
458 if (bus_cur->firstIO)
459 res = bus_cur->firstIO;
465 if (res->rangeno == rangeno)
467 if (res->next)
468 res = res->next;
469 else if (res->nextRange)
470 res = res->nextRange;
478 /* found the range */
480 ++res->rangeno;
481 res = res->next;
487 static void fix_me(struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
490 switch (res->type) {
503 if (res->rangeno == -1) {
504 while (range) {
505 if ((res->start >= range->start) && (res->end <= range->end)) {
506 res->rangeno = range->rangeno;
507 debug("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
508 switch (res->type) {
510 --bus_cur->needIOUpdate;
513 --bus_cur->needMemUpdate;
516 --bus_cur->needPFMemUpdate;
521 range = range->next;
524 if (res->next)
525 res = res->next;
527 res = res->nextRange;
533 * This routine reassigns the range numbers to the resources that had a -1
535 * appear in EBDA before the resources allocated for that bus, since we don't
536 * know the range, we assign -1, and this routine is called after a new range
537 * is assigned to see the resources with unknown range belong to the added range
539 * Input: current bus
540 * Output: none, list of resources for that bus are fixed if can be
544 struct range_node *range;
547 debug("%s - bus_cur->busno = %d\n", __func__, bus_cur->busno);
549 if (bus_cur->needIOUpdate) {
550 res = bus_cur->firstIO;
551 range = bus_cur->rangeIO;
552 fix_me(res, bus_cur, range);
554 if (bus_cur->needMemUpdate) {
555 res = bus_cur->firstMem;
556 range = bus_cur->rangeMem;
557 fix_me(res, bus_cur, range);
559 if (bus_cur->needPFMemUpdate) {
560 res = bus_cur->firstPFMem;
561 range = bus_cur->rangePFMem;
562 fix_me(res, bus_cur, range);
567 * This routine adds a resource to the list of resources to the appropriate bus
573 * 0 or -1
583 debug("%s - enter\n", __func__);
587 return -ENODEV;
590 bus_cur = find_bus_wprev(res->busno, NULL, 0);
593 /* didn't find a bus, something's wrong!!! */
594 debug("no bus in the system, either pci_dev's wrong or allocation failed\n");
595 return -ENODEV;
599 switch (res->type) {
601 range_cur = bus_cur->rangeIO;
602 res_start = bus_cur->firstIO;
605 range_cur = bus_cur->rangeMem;
606 res_start = bus_cur->firstMem;
609 range_cur = bus_cur->rangePFMem;
610 res_start = bus_cur->firstPFMem;
614 return -EINVAL;
617 if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) {
618 res->rangeno = range_cur->rangeno;
621 range_cur = range_cur->next;
625 * this is again the case of rangeno = -1
630 switch (res->type) {
632 ++bus_cur->needIOUpdate;
635 ++bus_cur->needMemUpdate;
638 ++bus_cur->needPFMemUpdate;
641 res->rangeno = -1;
644 debug("The range is %d\n", res->rangeno);
646 /* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
647 switch (res->type) {
649 bus_cur->firstIO = res;
652 bus_cur->firstMem = res;
655 bus_cur->firstPFMem = res;
658 res->next = NULL;
659 res->nextRange = NULL;
664 debug("res_cur->rangeno is %d\n", res_cur->rangeno);
667 if (res_cur->rangeno >= res->rangeno)
670 if (res_cur->next)
671 res_cur = res_cur->next;
673 res_cur = res_cur->nextRange;
678 debug("i should be here, [%x - %x]\n", res->start, res->end);
679 res_prev->nextRange = res;
680 res->next = NULL;
681 res->nextRange = NULL;
682 } else if (res_cur->rangeno == res->rangeno) {
683 /* in the same range */
685 if (res->start < res_cur->start)
688 res_cur = res_cur->next;
691 /* the last resource in this range */
692 res_prev->next = res;
693 res->next = NULL;
694 res->nextRange = res_prev->nextRange;
695 res_prev->nextRange = NULL;
696 } else if (res->start < res_cur->start) {
697 /* at the beginning or middle of the range */
699 switch (res->type) {
701 bus_cur->firstIO = res;
704 bus_cur->firstMem = res;
707 bus_cur->firstPFMem = res;
710 } else if (res_prev->rangeno == res_cur->rangeno)
711 res_prev->next = res;
713 res_prev->nextRange = res;
715 res->next = res_cur;
716 res->nextRange = NULL;
719 /* this is the case where it is 1st occurrence of the range */
722 res->next = NULL;
723 switch (res->type) {
725 res->nextRange = bus_cur->firstIO;
726 bus_cur->firstIO = res;
729 res->nextRange = bus_cur->firstMem;
730 bus_cur->firstMem = res;
733 res->nextRange = bus_cur->firstPFMem;
734 bus_cur->firstPFMem = res;
737 } else if (res_cur->rangeno > res->rangeno) {
739 res_prev->nextRange = res;
740 res->next = NULL;
741 res->nextRange = res_cur;
746 debug("%s - exit\n", __func__);
767 return -ENODEV;
770 bus_cur = find_bus_wprev(res->busno, NULL, 0);
773 err("cannot find corresponding bus of the io resource to remove bailing out...\n");
774 return -ENODEV;
777 switch (res->type) {
779 res_cur = bus_cur->firstIO;
783 res_cur = bus_cur->firstMem;
787 res_cur = bus_cur->firstPFMem;
792 return -EINVAL;
797 if ((res_cur->start == res->start) && (res_cur->end == res->end))
800 if (res_cur->next)
801 res_cur = res_cur->next;
803 res_cur = res_cur->nextRange;
807 if (res->type == PFMEM) {
813 res_cur = bus_cur->firstPFMemFromMem;
817 if ((res_cur->start == res->start) && (res_cur->end == res->end)) {
818 mem_cur = bus_cur->firstMem;
820 if ((mem_cur->start == res_cur->start)
821 && (mem_cur->end == res_cur->end))
823 if (mem_cur->next)
824 mem_cur = mem_cur->next;
826 mem_cur = mem_cur->nextRange;
830 return -EINVAL;
835 bus_cur->firstPFMemFromMem = res_cur->next;
837 res_prev->next = res_cur->next;
842 if (res_cur->next)
843 res_cur = res_cur->next;
845 res_cur = res_cur->nextRange;
849 return -EINVAL;
853 return -EINVAL;
858 if (res_cur->next) {
859 switch (res->type) {
861 bus_cur->firstIO = res_cur->next;
864 bus_cur->firstMem = res_cur->next;
867 bus_cur->firstPFMem = res_cur->next;
870 } else if (res_cur->nextRange) {
871 switch (res->type) {
873 bus_cur->firstIO = res_cur->nextRange;
876 bus_cur->firstMem = res_cur->nextRange;
879 bus_cur->firstPFMem = res_cur->nextRange;
883 switch (res->type) {
885 bus_cur->firstIO = NULL;
888 bus_cur->firstMem = NULL;
891 bus_cur->firstPFMem = NULL;
898 if (res_cur->next) {
899 if (res_prev->rangeno == res_cur->rangeno)
900 res_prev->next = res_cur->next;
902 res_prev->nextRange = res_cur->next;
903 } else if (res_cur->nextRange) {
904 res_prev->next = NULL;
905 res_prev->nextRange = res_cur->nextRange;
907 res_prev->next = NULL;
908 res_prev->nextRange = NULL;
919 struct range_node *range = NULL;
921 switch (res->type) {
923 range = bus_cur->rangeIO;
926 range = bus_cur->rangeMem;
929 range = bus_cur->rangePFMem;
935 while (range) {
936 if (res->rangeno == range->rangeno)
938 range = range->next;
940 return range;
944 * This routine will check to make sure the io/mem/pfmem->len that the device asked for
945 * can fit w/i our list of available IO/MEM/PFMEM resources. If cannot, returns -EINVAL,
950 * 0 or -EINVAL
955 struct range_node *range = NULL;
965 return -EINVAL;
969 if (res->type == IO)
974 tmp_divide = res->len;
976 bus_cur = find_bus_wprev(res->busno, NULL, 0);
979 /* didn't find a bus, something's wrong!!! */
980 debug("no bus in the system, either pci_dev's wrong or allocation failed\n");
981 return -EINVAL;
984 debug("%s - enter\n", __func__);
985 debug("bus_cur->busno is %d\n", bus_cur->busno);
988 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
989 res->len -= 1;
991 switch (res->type) {
993 res_cur = bus_cur->firstIO;
994 noranges = bus_cur->noIORanges;
997 res_cur = bus_cur->firstMem;
998 noranges = bus_cur->noMemRanges;
1001 res_cur = bus_cur->firstPFMem;
1002 noranges = bus_cur->noPFMemRanges;
1006 return -EINVAL;
1011 range = find_range(bus_cur, res_cur);
1012 debug("%s - rangeno = %d\n", __func__, res_cur->rangeno);
1014 if (!range) {
1015 err("no range for the device exists... bailing out...\n");
1016 return -EINVAL;
1019 /* found our range */
1022 len_tmp = res_cur->start - 1 - range->start;
1024 if ((res_cur->start != range->start) && (len_tmp >= res->len)) {
1029 if ((range->start % tmp_divide) == 0) {
1033 start_cur = range->start;
1036 tmp_start = range->start;
1039 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1046 tmp_start += tmp_divide - tmp_start % tmp_divide;
1047 if (tmp_start >= res_cur->start - 1)
1052 if (flag && len_cur == res->len) {
1054 res->start = start_cur;
1055 res->len += 1; /* To restore the balance */
1056 res->end = res->start + res->len - 1;
1062 if (!res_cur->next) {
1063 /* last device on the range */
1064 len_tmp = range->end - (res_cur->end + 1);
1066 if ((range->end != res_cur->end) && (len_tmp >= res->len)) {
1070 if (((res_cur->end + 1) % tmp_divide) == 0) {
1074 start_cur = res_cur->end + 1;
1077 tmp_start = res_cur->end + 1;
1080 while ((len_tmp = range->end - tmp_start) >= res->len) {
1087 tmp_start += tmp_divide - tmp_start % tmp_divide;
1088 if (tmp_start >= range->end)
1092 if (flag && len_cur == res->len) {
1093 res->start = start_cur;
1094 res->len += 1; /* To restore the balance */
1095 res->end = res->start + res->len - 1;
1103 if (res_prev->rangeno != res_cur->rangeno) {
1104 /* 1st device on this range */
1105 len_tmp = res_cur->start - 1 - range->start;
1107 if ((res_cur->start != range->start) && (len_tmp >= res->len)) {
1109 if ((range->start % tmp_divide) == 0) {
1113 start_cur = range->start;
1116 tmp_start = range->start;
1119 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1126 tmp_start += tmp_divide - tmp_start % tmp_divide;
1127 if (tmp_start >= res_cur->start - 1)
1132 if (flag && len_cur == res->len) {
1133 res->start = start_cur;
1134 res->len += 1; /* To restore the balance */
1135 res->end = res->start + res->len - 1;
1141 /* in the same range */
1142 len_tmp = res_cur->start - 1 - res_prev->end - 1;
1144 if (len_tmp >= res->len) {
1146 if (((res_prev->end + 1) % tmp_divide) == 0) {
1150 start_cur = res_prev->end + 1;
1153 tmp_start = res_prev->end + 1;
1156 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1163 tmp_start += tmp_divide - tmp_start % tmp_divide;
1164 if (tmp_start >= res_cur->start - 1)
1169 if (flag && len_cur == res->len) {
1170 res->start = start_cur;
1171 res->len += 1; /* To restore the balance */
1172 res->end = res->start + res->len - 1;
1181 if (res_cur->next)
1182 res_cur = res_cur->next;
1184 res_cur = res_cur->nextRange;
1190 /* need to find appropriate range */
1191 switch (res->type) {
1193 range = bus_cur->rangeIO;
1196 range = bus_cur->rangeMem;
1199 range = bus_cur->rangePFMem;
1202 while (range) {
1203 len_tmp = range->end - range->start;
1205 if (len_tmp >= res->len) {
1207 if ((range->start % tmp_divide) == 0) {
1211 start_cur = range->start;
1214 tmp_start = range->start;
1217 while ((len_tmp = range->end - tmp_start) >= res->len) {
1224 tmp_start += tmp_divide - tmp_start % tmp_divide;
1225 if (tmp_start >= range->end)
1230 if (flag && len_cur == res->len) {
1231 res->start = start_cur;
1232 res->len += 1; /* To restore the balance */
1233 res->end = res->start + res->len - 1;
1238 range = range->next;
1241 if ((!range) && (len_cur == 0)) {
1243 err("no appropriate range.. bailing out...\n");
1244 return -EINVAL;
1246 res->start = start_cur;
1247 res->len += 1; /* To restore the balance */
1248 res->end = res->start + res->len - 1;
1254 debug("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
1255 if (res_prev->rangeno < noranges) {
1257 switch (res->type) {
1259 range = bus_cur->rangeIO;
1262 range = bus_cur->rangeMem;
1265 range = bus_cur->rangePFMem;
1268 while (range) {
1269 len_tmp = range->end - range->start;
1271 if (len_tmp >= res->len) {
1273 if ((range->start % tmp_divide) == 0) {
1277 start_cur = range->start;
1280 tmp_start = range->start;
1283 while ((len_tmp = range->end - tmp_start) >= res->len) {
1290 tmp_start += tmp_divide - tmp_start % tmp_divide;
1291 if (tmp_start >= range->end)
1296 if (flag && len_cur == res->len) {
1297 res->start = start_cur;
1298 res->len += 1; /* To restore the balance */
1299 res->end = res->start + res->len - 1;
1304 range = range->next;
1307 if ((!range) && (len_cur == 0)) {
1309 err("no appropriate range.. bailing out...\n");
1310 return -EINVAL;
1312 res->start = start_cur;
1313 res->len += 1; /* To restore the balance */
1314 res->end = res->start + res->len - 1;
1320 res->start = start_cur;
1321 res->len += 1; /* To restore the balance */
1322 res->end = res->start + res->len - 1;
1326 err("no appropriate range.. bailing out...\n");
1327 return -EINVAL;
1331 return -EINVAL;
1336 * It will remove all the resources on the bus as well as the bus itself
1337 * Input: Bus
1338 * Output: 0, -ENODEV
1340 int ibmphp_remove_bus(struct bus_node *bus, u8 parent_busno)
1350 debug("something terribly wrong. Cannot find parent bus to the one to remove\n");
1351 return -ENODEV;
1354 debug("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
1356 rc = remove_ranges(bus, prev_bus);
1360 if (bus->firstIO) {
1361 res_cur = bus->firstIO;
1364 if (res_cur->next)
1365 res_cur = res_cur->next;
1367 res_cur = res_cur->nextRange;
1371 bus->firstIO = NULL;
1373 if (bus->firstMem) {
1374 res_cur = bus->firstMem;
1377 if (res_cur->next)
1378 res_cur = res_cur->next;
1380 res_cur = res_cur->nextRange;
1384 bus->firstMem = NULL;
1386 if (bus->firstPFMem) {
1387 res_cur = bus->firstPFMem;
1390 if (res_cur->next)
1391 res_cur = res_cur->next;
1393 res_cur = res_cur->nextRange;
1397 bus->firstPFMem = NULL;
1400 if (bus->firstPFMemFromMem) {
1401 res_cur = bus->firstPFMemFromMem;
1404 res_cur = res_cur->next;
1409 bus->firstPFMemFromMem = NULL;
1412 list_del(&bus->bus_list);
1413 kfree(bus);
1418 * This routine deletes the ranges from a given bus, and the entries from the
1419 * parent's bus in the resources
1420 * Input: current bus, previous bus
1421 * Output: 0, -EINVAL
1430 if (bus_cur->noIORanges) {
1431 range_cur = bus_cur->rangeIO;
1432 for (i = 0; i < bus_cur->noIORanges; i++) {
1433 if (ibmphp_find_resource(bus_prev, range_cur->start, &res, IO) < 0)
1434 return -EINVAL;
1438 range_cur = range_cur->next;
1442 bus_cur->rangeIO = NULL;
1444 if (bus_cur->noMemRanges) {
1445 range_cur = bus_cur->rangeMem;
1446 for (i = 0; i < bus_cur->noMemRanges; i++) {
1447 if (ibmphp_find_resource(bus_prev, range_cur->start, &res, MEM) < 0)
1448 return -EINVAL;
1452 range_cur = range_cur->next;
1456 bus_cur->rangeMem = NULL;
1458 if (bus_cur->noPFMemRanges) {
1459 range_cur = bus_cur->rangePFMem;
1460 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1461 if (ibmphp_find_resource(bus_prev, range_cur->start, &res, PFMEM) < 0)
1462 return -EINVAL;
1466 range_cur = range_cur->next;
1470 bus_cur->rangePFMem = NULL;
1476 * find the resource node in the bus
1479 int ibmphp_find_resource(struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
1484 if (!bus) {
1485 err("The bus passed in NULL to find resource\n");
1486 return -ENODEV;
1491 res_cur = bus->firstIO;
1495 res_cur = bus->firstMem;
1499 res_cur = bus->firstPFMem;
1504 return -EINVAL;
1508 if (res_cur->start == start_address) {
1512 if (res_cur->next)
1513 res_cur = res_cur->next;
1515 res_cur = res_cur->nextRange;
1520 res_cur = bus->firstPFMemFromMem;
1522 if (res_cur->start == start_address) {
1526 res_cur = res_cur->next;
1529 debug("SOS...cannot find %s resource in the bus.\n", type);
1530 return -EINVAL;
1533 debug("SOS... cannot find %s resource in the bus.\n", type);
1534 return -EINVAL;
1539 debug("*res->start = %x\n", (*res)->start);
1562 if (bus_cur->noIORanges) {
1563 range_cur = bus_cur->rangeIO;
1564 for (i = 0; i < bus_cur->noIORanges; i++) {
1568 range_cur = range_cur->next;
1573 if (bus_cur->noMemRanges) {
1574 range_cur = bus_cur->rangeMem;
1575 for (i = 0; i < bus_cur->noMemRanges; i++) {
1579 range_cur = range_cur->next;
1584 if (bus_cur->noPFMemRanges) {
1585 range_cur = bus_cur->rangePFMem;
1586 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1590 range_cur = range_cur->next;
1596 if (bus_cur->firstIO) {
1597 res_cur = bus_cur->firstIO;
1600 if (res_cur->next)
1601 res_cur = res_cur->next;
1603 res_cur = res_cur->nextRange;
1607 bus_cur->firstIO = NULL;
1609 if (bus_cur->firstMem) {
1610 res_cur = bus_cur->firstMem;
1613 if (res_cur->next)
1614 res_cur = res_cur->next;
1616 res_cur = res_cur->nextRange;
1620 bus_cur->firstMem = NULL;
1622 if (bus_cur->firstPFMem) {
1623 res_cur = bus_cur->firstPFMem;
1626 if (res_cur->next)
1627 res_cur = res_cur->next;
1629 res_cur = res_cur->nextRange;
1633 bus_cur->firstPFMem = NULL;
1636 if (bus_cur->firstPFMemFromMem) {
1637 res_cur = bus_cur->firstPFMemFromMem;
1640 res_cur = res_cur->next;
1645 bus_cur->firstPFMemFromMem = NULL;
1649 list_del(&bus_cur->bus_list);
1657 * pfmem out of memory buckets of the bus. If so, it will change the range numbers
1671 if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
1672 for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
1673 pfmem_cur->fromMem = 1;
1675 pfmem_prev->next = pfmem_cur->next;
1677 bus_cur->firstPFMem = pfmem_cur->next;
1679 if (!bus_cur->firstPFMemFromMem)
1680 pfmem_cur->next = NULL;
1686 pfmem_cur->next = bus_cur->firstPFMemFromMem;
1688 bus_cur->firstPFMemFromMem = pfmem_cur;
1692 return -ENOMEM;
1694 mem->type = MEM;
1695 mem->busno = pfmem_cur->busno;
1696 mem->devfunc = pfmem_cur->devfunc;
1697 mem->start = pfmem_cur->start;
1698 mem->end = pfmem_cur->end;
1699 mem->len = pfmem_cur->len;
1702 pfmem_cur->rangeno = mem->rangeno;
1705 } /* end list_for_each bus */
1711 struct bus_node *bus_cur = find_bus_wprev(pfmem->busno, NULL, 0);
1714 err("cannot find bus of pfmem to add...\n");
1715 return -ENODEV;
1718 if (bus_cur->firstPFMemFromMem)
1719 pfmem->next = bus_cur->firstPFMemFromMem;
1721 pfmem->next = NULL;
1723 bus_cur->firstPFMemFromMem = pfmem;
1728 /* This routine just goes through the buses to see if the bus already exists.
1729 * It is called from ibmphp_find_sec_number, to find out a secondary bus number for
1732 * Returns: Bus pointer or NULL
1746 if (bus_cur->busno == bus_number)
1757 struct range_node *range;
1768 debug_pci ("This is bus # %d. There are\n", bus_cur->busno);
1769 debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
1770 debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
1771 debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
1773 if (bus_cur->rangeIO) {
1774 range = bus_cur->rangeIO;
1775 for (i = 0; i < bus_cur->noIORanges; i++) {
1776 debug_pci("rangeno is %d\n", range->rangeno);
1777 debug_pci("[%x - %x]\n", range->start, range->end);
1778 range = range->next;
1783 if (bus_cur->rangeMem) {
1784 range = bus_cur->rangeMem;
1785 for (i = 0; i < bus_cur->noMemRanges; i++) {
1786 debug_pci("rangeno is %d\n", range->rangeno);
1787 debug_pci("[%x - %x]\n", range->start, range->end);
1788 range = range->next;
1794 if (bus_cur->rangePFMem) {
1795 range = bus_cur->rangePFMem;
1796 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1797 debug_pci("rangeno is %d\n", range->rangeno);
1798 debug_pci("[%x - %x]\n", range->start, range->end);
1799 range = range->next;
1803 debug_pci("The resources on this bus are as follows\n");
1806 if (bus_cur->firstIO) {
1807 res = bus_cur->firstIO;
1809 debug_pci("The range # is %d\n", res->rangeno);
1810 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1811 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
1812 if (res->next)
1813 res = res->next;
1814 else if (res->nextRange)
1815 res = res->nextRange;
1821 if (bus_cur->firstMem) {
1822 res = bus_cur->firstMem;
1824 debug_pci("The range # is %d\n", res->rangeno);
1825 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1826 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
1827 if (res->next)
1828 res = res->next;
1829 else if (res->nextRange)
1830 res = res->nextRange;
1836 if (bus_cur->firstPFMem) {
1837 res = bus_cur->firstPFMem;
1839 debug_pci("The range # is %d\n", res->rangeno);
1840 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1841 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
1842 if (res->next)
1843 res = res->next;
1844 else if (res->nextRange)
1845 res = res->nextRange;
1852 if (bus_cur->firstPFMemFromMem) {
1853 res = bus_cur->firstPFMemFromMem;
1855 debug_pci("The range # is %d\n", res->rangeno);
1856 debug_pci("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1857 debug_pci("[%x - %x], len=%x\n", res->start, res->end, res->len);
1858 res = res->next;
1865 static int range_exists_already(struct range_node *range, struct bus_node *bus_cur, u8 type)
1870 range_cur = bus_cur->rangeIO;
1873 range_cur = bus_cur->rangeMem;
1876 range_cur = bus_cur->rangePFMem;
1879 err("wrong type passed to find out if range already exists\n");
1880 return -ENODEV;
1884 if ((range_cur->start == range->start) && (range_cur->end == range->end))
1886 range_cur = range_cur->next;
1893 * range info for the secondary bus, and will also input this info into
1894 * primary bus, since BIOS doesn't. This is for PPB that are in the system
1896 * driver, only the ranges and the bus structure are added, the devices are
1902 * also will not work for onboard PPBs that can have more than 1 *bus
1906 static int __init update_bridge_ranges(struct bus_node **bus)
1916 struct range_node *range;
1919 bus_cur = *bus;
1921 return -ENODEV;
1922 ibmphp_pci_bus->number = bus_cur->busno;
1925 debug("bus_cur->busno = %x\n", bus_cur->busno);
1946 /* We assume here that only 1 bus behind the bridge
1956 /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
1972 range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
1973 if (!range)
1974 return -ENOMEM;
1976 range->start = start_address;
1977 range->end = end_address + 0xfff;
1979 if (bus_sec->noIORanges > 0) {
1980 if (!range_exists_already(range, bus_sec, IO)) {
1981 add_bus_range(IO, range, bus_sec);
1982 ++bus_sec->noIORanges;
1984 kfree(range);
1985 range = NULL;
1988 /* 1st IO Range on the bus */
1989 range->rangeno = 1;
1990 bus_sec->rangeIO = range;
1991 ++bus_sec->noIORanges;
1998 kfree(range);
1999 return -ENOMEM;
2001 io->type = IO;
2002 io->busno = bus_cur->busno;
2003 io->devfunc = ((device << 3) | (function & 0x7));
2004 io->start = start_address;
2005 io->end = end_address + 0xfff;
2006 io->len = io->end - io->start + 1;
2019 range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
2020 if (!range)
2021 return -ENOMEM;
2023 range->start = start_address;
2024 range->end = end_address + 0xfffff;
2026 if (bus_sec->noMemRanges > 0) {
2027 if (!range_exists_already(range, bus_sec, MEM)) {
2028 add_bus_range(MEM, range, bus_sec);
2029 ++bus_sec->noMemRanges;
2031 kfree(range);
2032 range = NULL;
2035 /* 1st Mem Range on the bus */
2036 range->rangeno = 1;
2037 bus_sec->rangeMem = range;
2038 ++bus_sec->noMemRanges;
2046 kfree(range);
2047 return -ENOMEM;
2049 mem->type = MEM;
2050 mem->busno = bus_cur->busno;
2051 mem->devfunc = ((device << 3) | (function & 0x7));
2052 mem->start = start_address;
2053 mem->end = end_address + 0xfffff;
2054 mem->len = mem->end - mem->start + 1;
2071 range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
2072 if (!range)
2073 return -ENOMEM;
2075 range->start = start_address;
2076 range->end = end_address + 0xfffff;
2078 if (bus_sec->noPFMemRanges > 0) {
2079 if (!range_exists_already(range, bus_sec, PFMEM)) {
2080 add_bus_range(PFMEM, range, bus_sec);
2081 ++bus_sec->noPFMemRanges;
2083 kfree(range);
2084 range = NULL;
2087 /* 1st PFMem Range on the bus */
2088 range->rangeno = 1;
2089 bus_sec->rangePFMem = range;
2090 ++bus_sec->noPFMemRanges;
2097 kfree(range);
2098 return -ENOMEM;
2100 pfmem->type = PFMEM;
2101 pfmem->busno = bus_cur->busno;
2102 pfmem->devfunc = ((device << 3) | (function & 0x7));
2103 pfmem->start = start_address;
2104 pfmem->end = end_address + 0xfffff;
2105 pfmem->len = pfmem->end - pfmem->start + 1;
2106 pfmem->fromMem = 0;