Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 294697
b: refs/heads/master
c: 3e6e0d8
h: refs/heads/master
i:
  294695: 3c8793c
v: v3
  • Loading branch information
Yinghai Lu authored and Jesse Barnes committed Feb 14, 2012
1 parent 80b3369 commit c7ab63e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1c372353e9c681b127f21030f8a0f0c2afd82429
refs/heads/master: 3e6e0d80941773a6d0ac94354b083b74967f06fb
83 changes: 82 additions & 1 deletion trunk/drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ static void add_to_failed_list(struct resource_list_x *head,
0 /* dont care */);
}

static void remove_from_list(struct resource_list_x *realloc_head,
struct resource *res)
{
struct resource_list_x *prev, *tmp, *list;

prev = realloc_head;
for (list = realloc_head->next; list;) {
if (list->res != res) {
prev = list;
list = list->next;
continue;
}
tmp = list;
prev->next = list = list->next;
kfree(tmp);
}
}

static resource_size_t get_res_add_size(struct resource_list_x *realloc_head,
struct resource *res)
{
Expand All @@ -108,8 +126,13 @@ static resource_size_t get_res_add_size(struct resource_list_x *realloc_head,
for (list = realloc_head->next; list && list->res != res;
list = list->next)
;
if (list)

if (list) {
dev_printk(KERN_DEBUG, &list->dev->dev,
"%pR get_res_add_size add_size %llx\n",
list->res, (unsigned long long)list->add_size);
return list->add_size;
}

return 0;
}
Expand Down Expand Up @@ -238,6 +261,64 @@ static void __assign_resources_sorted(struct resource_list *head,
struct resource_list_x *realloc_head,
struct resource_list_x *fail_head)
{
/*
* Should not assign requested resources at first.
* they could be adjacent, so later reassign can not reallocate
* them one by one in parent resource window.
* Try to assign requested + add_size at begining
* if could do that, could get out early.
* if could not do that, we still try to assign requested at first,
* then try to reassign add_size for some resources.
*/
struct resource_list_x save_head, local_fail_head, *list;
struct resource_list *l;

/* Check if optional add_size is there */
if (!realloc_head || !realloc_head->next)
goto requested_and_reassign;

/* Save original start, end, flags etc at first */
save_head.next = NULL;
for (l = head->next; l; l = l->next)
if (add_to_list(&save_head, l->dev, l->res, 0, 0)) {
free_list(resource_list_x, &save_head);
goto requested_and_reassign;
}

/* Update res in head list with add_size in realloc_head list */
for (l = head->next; l; l = l->next)
l->res->end += get_res_add_size(realloc_head, l->res);

/* Try updated head list with add_size added */
local_fail_head.next = NULL;
assign_requested_resources_sorted(head, &local_fail_head);

/* all assigned with add_size ? */
if (!local_fail_head.next) {
/* Remove head list from realloc_head list */
for (l = head->next; l; l = l->next)
remove_from_list(realloc_head, l->res);
free_list(resource_list_x, &save_head);
free_list(resource_list, head);
return;
}

free_list(resource_list_x, &local_fail_head);
/* Release assigned resource */
for (l = head->next; l; l = l->next)
if (l->res->parent)
release_resource(l->res);
/* Restore start/end/flags from saved list */
for (list = save_head.next; list; list = list->next) {
struct resource *res = list->res;

res->start = list->start;
res->end = list->end;
res->flags = list->flags;
}
free_list(resource_list_x, &save_head);

requested_and_reassign:
/* Satisfy the must-have resource requests */
assign_requested_resources_sorted(head, fail_head);

Expand Down

0 comments on commit c7ab63e

Please sign in to comment.