30 #include <linux/module.h>
31 #include <linux/slab.h>
32 #include <linux/pci.h>
33 #include <linux/list.h>
39 static void update_resources (
struct bus_node *bus_cur,
int type,
int rangeno);
40 static int once_over (
void);
42 static int update_bridge_ranges (
struct bus_node **);
44 static void fix_resources (
struct bus_node *);
53 if (!(curr) && !(flag)) {
54 err (
"NULL pointer passed\n");
60 err (
"out of system memory\n");
77 err (
"NULL passed to allocate\n");
83 err (
"out of system memory\n");
103 err (
"out of system memory.\n");
126 err (
"out of system memory\n");
132 if (first_bus || (!num_ranges))
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);
146 debug (
"First Memory Primary on bus %x, [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
148 fix_resources (newbus);
156 debug (
"First IO Primary on bus %x, [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
158 fix_resources (newbus);
166 debug (
"1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
168 fix_resources (newbus);
175 *new_range = newrange;
217 debug (
"this is not a PCI DEVICE in rsrc_init, please take care\n");
226 if (list_empty (&gbuses)) {
227 if ((rc = alloc_bus_range (&newbus, &newrange, curr,
MEM, 1)))
230 debug (
"gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
232 bus_cur = find_bus_wprev (curr->
bus_num, &bus_prev, 1);
235 rc = alloc_bus_range (&bus_cur, &newrange, curr,
MEM, 0);
240 if ((rc = alloc_bus_range (&newbus, &newrange, curr,
MEM, 1)))
244 debug (
"New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
249 if (list_empty (&gbuses)) {
251 if ((rc = alloc_bus_range (&newbus, &newrange, curr,
PFMEM, 1)))
254 debug (
"gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
256 bus_cur = find_bus_wprev (curr->
bus_num, &bus_prev, 1);
259 rc = alloc_bus_range (&bus_cur, &newrange, curr,
PFMEM, 0);
264 if ((rc = alloc_bus_range (&newbus, &newrange, curr,
PFMEM, 1)))
267 debug (
"1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
272 if (list_empty (&gbuses)) {
274 if ((rc = alloc_bus_range (&newbus, &newrange, curr,
IO, 1)))
277 debug (
"gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
279 bus_cur = find_bus_wprev (curr->
bus_num, &bus_prev, 1);
281 rc = alloc_bus_range (&bus_cur, &newrange, curr,
IO, 0);
286 if ((rc = alloc_bus_range (&newbus, &newrange, curr,
IO, 1)))
289 debug (
"1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->
busno, newrange->
start, newrange->
end);
301 new_mem = alloc_resources (curr);
313 newbus = alloc_error_bus (curr, 0, 0);
320 debug (
"Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->
devfunc, new_mem->
busno, new_mem->
start, new_mem->
end);
324 new_pfmem = alloc_resources (curr);
330 newbus = alloc_error_bus (curr, 0, 0);
338 debug (
"PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->
devfunc, new_pfmem->
busno, new_pfmem->
start, new_pfmem->
end);
341 new_io = alloc_resources (curr);
354 newbus = alloc_error_bus (curr, 0, 0);
369 rc = update_bridge_ranges (&bus_cur);
391 int count = 0, i_init;
413 range_prev = range_cur;
414 range_cur = range_cur->
next;
430 range->
next = range_cur;
433 }
else if (!range_cur) {
442 range->
next = range_cur;
447 for (count = i_init; count < noRanges; ++
count) {
449 range_cur = range_cur->
next;
452 update_resources (bus_cur, type, i_init + 1);
462 static void update_resources (
struct bus_node *bus_cur,
int type,
int rangeno)
526 debug (
"%s->rangeno in fix_resources is %d\n", str, res->
rangeno);
561 static void fix_resources (
struct bus_node *bus_cur)
566 debug (
"%s - bus_cur->busno = %d\n", __func__, bus_cur->
busno);
571 fix_me (res, bus_cur, range);
576 fix_me (res, bus_cur, range);
581 fix_me (res, bus_cur, range);
602 debug (
"%s - enter\n", __func__);
605 err (
"NULL passed to add\n");
609 bus_cur = find_bus_wprev (res->
busno,
NULL, 0);
613 debug (
"no bus in the system, either pci_dev's wrong or allocation failed\n");
632 err (
"cannot read the type of the resource to add... problem\n");
640 range_cur = range_cur->
next;
690 res_cur = res_cur->
next;
697 debug (
"i should be here, [%x - %x]\n", res->
start, res->
end);
707 res_cur = res_cur->
next;
765 debug (
"%s - exit\n", __func__);
785 err (
"resource to remove is NULL\n");
789 bus_cur = find_bus_wprev (res->
busno,
NULL, 0);
792 err (
"cannot find corresponding bus of the io resource to remove "
811 err (
"unknown type for resource to remove\n");
821 res_cur = res_cur->
next;
841 && (mem_cur->
end == res_cur->
end))
844 mem_cur = mem_cur->
next;
849 err (
"cannot find corresponding mem node for pfmem...\n");
863 res_cur = res_cur->
next;
868 err (
"cannot find pfmem to delete...\n");
872 err (
"the %s resource is not in the list to be deleted...\n", type);
952 err (
"cannot read resource type in find_range\n");
978 u32 len_cur = 0, start_cur = 0, len_tmp = 0;
994 tmp_divide = res->
len;
996 bus_cur = find_bus_wprev (res->
busno,
NULL, 0);
1000 debug (
"no bus in the system, either pci_dev's wrong or allocation failed\n");
1004 debug (
"%s - enter\n", __func__);
1005 debug (
"bus_cur->busno is %d\n", bus_cur->
busno);
1011 switch (res->
type) {
1025 err (
"wrong type of resource to check\n");
1031 range = find_range (bus_cur, res_cur);
1032 debug (
"%s - rangeno = %d\n", __func__, res_cur->
rangeno);
1035 err (
"no range for the device exists... bailing out...\n");
1043 debug (
"len_tmp = %x\n", len_tmp);
1045 if ((len_tmp < len_cur) || (len_cur == 0)) {
1047 if ((range->
start % tmp_divide) == 0) {
1051 start_cur = range->
start;
1054 tmp_start = range->
start;
1057 while ((len_tmp = res_cur->
start - 1 - tmp_start) >= res->
len) {
1058 if ((tmp_start % tmp_divide) == 0) {
1061 start_cur = tmp_start;
1064 tmp_start += tmp_divide - tmp_start % tmp_divide;
1065 if (tmp_start >= res_cur->
start - 1)
1070 if (flag && len_cur == res->
len) {
1071 debug (
"but we are not here, right?\n");
1072 res->
start = start_cur;
1080 if (!res_cur->
next) {
1082 if ((range->
end != res_cur->
end) && ((len_tmp = range->
end - (res_cur->
end + 1)) >= res->
len)) {
1083 debug (
"len_tmp = %x\n", len_tmp);
1084 if ((len_tmp < len_cur) || (len_cur == 0)) {
1086 if (((res_cur->
end + 1) % tmp_divide) == 0) {
1090 start_cur = res_cur->
end + 1;
1093 tmp_start = res_cur->
end + 1;
1096 while ((len_tmp = range->
end - tmp_start) >= res->
len) {
1097 if ((tmp_start % tmp_divide) == 0) {
1100 start_cur = tmp_start;
1103 tmp_start += tmp_divide - tmp_start % tmp_divide;
1104 if (tmp_start >= range->
end)
1108 if (flag && len_cur == res->
len) {
1109 res->
start = start_cur;
1122 ((len_tmp = res_cur->
start - 1 - range->
start) >= res->
len)) {
1123 if ((len_tmp < len_cur) || (len_cur == 0)) {
1124 if ((range->
start % tmp_divide) == 0) {
1128 start_cur = range->
start;
1131 tmp_start = range->
start;
1134 while ((len_tmp = res_cur->
start - 1 - tmp_start) >= res->
len) {
1135 if ((tmp_start % tmp_divide) == 0) {
1138 start_cur = tmp_start;
1141 tmp_start += tmp_divide - tmp_start % tmp_divide;
1142 if (tmp_start >= res_cur->
start - 1)
1147 if (flag && len_cur == res->
len) {
1148 res->
start = start_cur;
1157 if ((len_tmp = res_cur->
start - 1 - res_prev->
end - 1) >= res->
len) {
1158 if ((len_tmp < len_cur) || (len_cur == 0)) {
1159 if (((res_prev->
end + 1) % tmp_divide) == 0) {
1163 start_cur = res_prev->
end + 1;
1166 tmp_start = res_prev->
end + 1;
1169 while ((len_tmp = res_cur->
start - 1 - tmp_start) >= res->
len) {
1170 if ((tmp_start % tmp_divide) == 0) {
1173 start_cur = tmp_start;
1176 tmp_start += tmp_divide - tmp_start % tmp_divide;
1177 if (tmp_start >= res_cur->
start - 1)
1182 if (flag && len_cur == res->
len) {
1183 res->
start = start_cur;
1195 res_cur = res_cur->
next;
1204 switch (res->
type) {
1216 if ((len_tmp = range->
end - range->
start) >= res->
len) {
1217 if ((len_tmp < len_cur) || (len_cur == 0)) {
1218 if ((range->
start % tmp_divide) == 0) {
1222 start_cur = range->
start;
1225 tmp_start = range->
start;
1228 while ((len_tmp = range->
end - tmp_start) >= res->
len) {
1229 if ((tmp_start % tmp_divide) == 0) {
1232 start_cur = tmp_start;
1235 tmp_start += tmp_divide - tmp_start % tmp_divide;
1236 if (tmp_start >= range->
end)
1241 if (flag && len_cur == res->
len) {
1242 res->
start = start_cur;
1249 range = range->
next;
1252 if ((!range) && (len_cur == 0)) {
1254 err (
"no appropriate range.. bailing out...\n");
1256 }
else if (len_cur) {
1257 res->
start = start_cur;
1265 debug (
"prev->rangeno = %d, noranges = %d\n", res_prev->
rangeno, noranges);
1266 if (res_prev->
rangeno < noranges) {
1268 switch (res->
type) {
1280 if ((len_tmp = range->
end - range->
start) >= res->
len) {
1281 if ((len_tmp < len_cur) || (len_cur == 0)) {
1282 if ((range->
start % tmp_divide) == 0) {
1286 start_cur = range->
start;
1289 tmp_start = range->
start;
1292 while ((len_tmp = range->
end - tmp_start) >= res->
len) {
1293 if ((tmp_start % tmp_divide) == 0) {
1296 start_cur = tmp_start;
1299 tmp_start += tmp_divide - tmp_start % tmp_divide;
1300 if (tmp_start >= range->
end)
1305 if (flag && len_cur == res->
len) {
1306 res->
start = start_cur;
1313 range = range->
next;
1316 if ((!range) && (len_cur == 0)) {
1318 err (
"no appropriate range.. bailing out...\n");
1320 }
else if (len_cur) {
1321 res->
start = start_cur;
1329 res->
start = start_cur;
1335 err (
"no appropriate range.. bailing out...\n");
1356 prev_bus = find_bus_wprev (parent_busno,
NULL, 0);
1359 debug (
"something terribly wrong. Cannot find parent bus to the one to remove\n");
1363 debug (
"In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->
busno);
1365 rc = remove_ranges (bus, prev_bus);
1374 res_cur = res_cur->
next;
1387 res_cur = res_cur->
next;
1400 res_cur = res_cur->
next;
1413 res_cur = res_cur->
next;
1432 static int remove_ranges (
struct bus_node *bus_cur,
struct bus_node *bus_prev)
1446 range_tmp = range_cur;
1447 range_cur = range_cur->
next;
1460 range_tmp = range_cur;
1461 range_cur = range_cur->
next;
1474 range_tmp = range_cur;
1475 range_cur = range_cur->
next;
1494 err (
"The bus passed in NULL to find resource\n");
1512 err (
"wrong type of flag\n");
1517 if (res_cur->
start == start_address) {
1522 res_cur = res_cur->
next;
1528 if (flag ==
PFMEM) {
1531 if (res_cur->
start == start_address) {
1535 res_cur = res_cur->
next;
1538 debug (
"SOS...cannot find %s resource in the bus.\n", type);
1542 debug (
"SOS... cannot find %s resource in the bus.\n", type);
1548 debug (
"*res->start = %x\n", (*res)->start);
1579 range_tmp = range_cur;
1580 range_cur = range_cur->
next;
1590 range_tmp = range_cur;
1591 range_cur = range_cur->
next;
1601 range_tmp = range_cur;
1602 range_cur = range_cur->
next;
1613 res_cur = res_cur->
next;
1626 res_cur = res_cur->
next;
1639 res_cur = res_cur->
next;
1652 res_cur = res_cur->
next;
1675 static int __init once_over (
void)
1686 for (pfmem_cur = bus_cur->
firstPFMem, pfmem_prev =
NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->
next) {
1689 pfmem_prev->
next = pfmem_cur->
next;
1706 err (
"out of system memory\n");
1713 mem->
end = pfmem_cur->
end;
1714 mem->
len = pfmem_cur->
len;
1716 err (
"Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
1729 err (
"cannot find bus of pfmem to add...\n");
1751 return find_bus_wprev (bus_number,
NULL, 0);
1761 tmp_prev = tmp->
prev;
1765 if (bus_cur->
busno == bus_number)
1780 debug_pci (
"*****************START**********************\n");
1782 if ((!list_empty(&gbuses)) &&
flags) {
1783 err (
"The GBUSES is not NULL?!?!?!?!?\n");
1793 debug_pci (
"The IO Ranges are as follows:\n");
1799 range = range->
next;
1803 debug_pci (
"The Mem Ranges are as follows:\n");
1809 range = range->
next;
1813 debug_pci (
"The PFMem Ranges are as follows:\n");
1820 range = range->
next;
1824 debug_pci (
"The resources on this bus are as follows\n");
1883 debug_pci (
"***********************END***********************\n");
1886 static int range_exists_already (
struct range_node * range,
struct bus_node * bus_cur,
u8 type)
1900 err (
"wrong type passed to find out if range already exists\n");
1907 range_cur = range_cur->
next;
1929 u8 sec_busno,
device,
function,
hdr_type, start_io_address, end_io_address;
1930 u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
1931 u32 start_address, end_address, upper_start, upper_end;
1945 debug (
"inside %s\n", __func__);
1946 debug (
"bus_cur->busno = %x\n", bus_cur->
busno);
1948 for (device = 0; device < 32; device++) {
1949 for (
function = 0x00;
function < 0x08;
function++) {
1975 bus_sec = find_bus_wprev (sec_busno,
NULL, 0);
1978 bus_sec = alloc_error_bus (
NULL, sec_busno, 1);
1987 start_address |= (upper_io_start << 16);
1989 end_address |= (upper_io_end << 16);
1991 if ((start_address) && (start_address <= end_address)) {
1994 err (
"out of system memory\n");
1997 range->
start = start_address;
1998 range->
end = end_address + 0xfff;
2001 if (!range_exists_already (range, bus_sec,
IO)) {
2002 add_bus_range (
IO, range, bus_sec);
2014 fix_resources (bus_sec);
2020 err (
"out of system memory\n");
2025 io->
devfunc = ((device << 3) | (
function & 0x7));
2026 io->
start = start_address;
2027 io->
end = end_address + 0xfff;
2039 if ((start_address) && (start_address <= end_address)) {
2043 err (
"out of system memory\n");
2046 range->
start = start_address;
2047 range->
end = end_address + 0xfffff;
2050 if (!range_exists_already (range, bus_sec,
MEM)) {
2051 add_bus_range (
MEM, range, bus_sec);
2064 fix_resources (bus_sec);
2070 err (
"out of system memory\n");
2075 mem->
devfunc = ((device << 3) | (
function & 0x7));
2076 mem->
start = start_address;
2077 mem->
end = end_address + 0xfffff;
2088 #if BITS_PER_LONG == 64
2089 start_address |= ((
long) upper_start) << 32;
2090 end_address |= ((
long) upper_end) << 32;
2093 if ((start_address) && (start_address <= end_address)) {
2097 err (
"out of system memory\n");
2100 range->
start = start_address;
2101 range->
end = end_address + 0xfffff;
2104 if (!range_exists_already (range, bus_sec,
PFMEM)) {
2105 add_bus_range (
PFMEM, range, bus_sec);
2118 fix_resources (bus_sec);
2123 err (
"out of system memory\n");
2128 pfmem->
devfunc = ((device << 3) | (
function & 0x7));
2129 pfmem->
start = start_address;
2130 pfmem->
end = end_address + 0xfffff;