Commit d30185f0 authored by Rolf Eike Beer's avatar Rolf Eike Beer Committed by Deepak Saxena

[PATCH] PCI Hotplug: Move an often used while loop to an inline function

Walking through a pci_resource list and freeing all members is done a lot of
times in unload functions. This patch moves this to an inline function in
pciehp_core.c, pciehp_pci.c, shpchp_core.c and shpchp_pci.c. This shrinks the
code a lot (some 200 lines) and makes it much easier to read. Also adds some
__exit.
parent a20313b1
...@@ -535,49 +535,35 @@ static int pcie_start_thread(void) ...@@ -535,49 +535,35 @@ static int pcie_start_thread(void)
return retval; return retval;
} }
static inline void __exit
free_pciehp_res(struct pci_resource *res)
{
struct pci_resource *tres;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
}
static void unload_pciehpd(void) static void __exit unload_pciehpd(void)
{ {
struct pci_func *next; struct pci_func *next;
struct pci_func *TempSlot; struct pci_func *TempSlot;
int loop; int loop;
struct controller *ctrl; struct controller *ctrl;
struct controller *tctrl; struct controller *tctrl;
struct pci_resource *res;
struct pci_resource *tres;
ctrl = pciehp_ctrl_list; ctrl = pciehp_ctrl_list;
while (ctrl) { while (ctrl) {
cleanup_slots(ctrl); cleanup_slots(ctrl);
res = ctrl->io_head; free_pciehp_res(ctrl->io_head);
while (res) { free_pciehp_res(ctrl->mem_head);
tres = res; free_pciehp_res(ctrl->p_mem_head);
res = res->next; free_pciehp_res(ctrl->bus_head);
kfree(tres);
}
res = ctrl->mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = ctrl->p_mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = ctrl->bus_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
kfree (ctrl->pci_bus); kfree (ctrl->pci_bus);
...@@ -592,33 +578,10 @@ static void unload_pciehpd(void) ...@@ -592,33 +578,10 @@ static void unload_pciehpd(void)
for (loop = 0; loop < 256; loop++) { for (loop = 0; loop < 256; loop++) {
next = pciehp_slot_list[loop]; next = pciehp_slot_list[loop];
while (next != NULL) { while (next != NULL) {
res = next->io_head; free_pciehp_res(ctrl->io_head);
while (res) { free_pciehp_res(ctrl->mem_head);
tres = res; free_pciehp_res(ctrl->p_mem_head);
res = res->next; free_pciehp_res(ctrl->bus_head);
kfree(tres);
}
res = next->mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = next->p_mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = next->bus_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
TempSlot = next; TempSlot = next;
next = next->next; next = next->next;
...@@ -700,8 +663,5 @@ static void __exit pcied_cleanup(void) ...@@ -700,8 +663,5 @@ static void __exit pcied_cleanup(void)
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
} }
module_init(pcied_init); module_init(pcied_init);
module_exit(pcied_cleanup); module_exit(pcied_cleanup);
...@@ -674,10 +674,29 @@ int pciehp_save_used_resources (struct controller *ctrl, struct pci_func *func, ...@@ -674,10 +674,29 @@ int pciehp_save_used_resources (struct controller *ctrl, struct pci_func *func,
func = pciehp_slot_find(func->bus, func->device, index++); func = pciehp_slot_find(func->bus, func->device, index++);
} }
return(0); return 0;
} }
/**
* kfree_resource_list: release memory of all list members
* @res: resource list to free
*/
static inline void
return_resource_list(struct pci_resource **func, struct pci_resource **res)
{
struct pci_resource *node;
struct pci_resource *t_node;
node = *func;
*func = NULL;
while (node) {
t_node = node->next;
return_resource(res, node);
node = t_node;
}
}
/* /*
* pciehp_return_board_resources * pciehp_return_board_resources
* *
...@@ -686,95 +705,40 @@ int pciehp_save_used_resources (struct controller *ctrl, struct pci_func *func, ...@@ -686,95 +705,40 @@ int pciehp_save_used_resources (struct controller *ctrl, struct pci_func *func,
* *
* returns 0 if success * returns 0 if success
*/ */
int pciehp_return_board_resources(struct pci_func * func, struct resource_lists * resources) int pciehp_return_board_resources(struct pci_func * func,
struct resource_lists * resources)
{ {
int rc = 0; int rc;
struct pci_resource *node;
struct pci_resource *t_node;
dbg("%s\n", __FUNCTION__); dbg("%s\n", __FUNCTION__);
if (!func) if (!func)
return(1); return 1;
node = func->io_head; return_resource_list(&(func->io_head),&(resources->io_head));
func->io_head = NULL; return_resource_list(&(func->mem_head),&(resources->mem_head));
while (node) { return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
t_node = node->next; return_resource_list(&(func->bus_head),&(resources->bus_head));
return_resource(&(resources->io_head), node);
node = t_node;
}
node = func->mem_head; rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
func->mem_head = NULL;
while (node) {
t_node = node->next;
return_resource(&(resources->mem_head), node);
node = t_node;
}
node = func->p_mem_head;
func->p_mem_head = NULL;
while (node) {
t_node = node->next;
return_resource(&(resources->p_mem_head), node);
node = t_node;
}
node = func->bus_head;
func->bus_head = NULL;
while (node) {
t_node = node->next;
return_resource(&(resources->bus_head), node);
node = t_node;
}
rc |= pciehp_resource_sort_and_combine(&(resources->mem_head));
rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head)); rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
rc |= pciehp_resource_sort_and_combine(&(resources->io_head)); rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
rc |= pciehp_resource_sort_and_combine(&(resources->bus_head)); rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
return(rc); return rc;
} }
/**
/* * kfree_resource_list: release memory of all list members
* pciehp_destroy_resource_list * @res: resource list to free
*
* Puts node back in the resource list pointed to by head
*/ */
void pciehp_destroy_resource_list (struct resource_lists * resources) static inline void
kfree_resource_list(struct pci_resource **r)
{ {
struct pci_resource *res, *tres; struct pci_resource *res, *tres;
res = resources->io_head; res = *r;
resources->io_head = NULL; *r = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = resources->mem_head;
resources->mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = resources->p_mem_head;
resources->p_mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = resources->bus_head;
resources->bus_head = NULL;
while (res) { while (res) {
tres = res; tres = res;
...@@ -783,50 +747,26 @@ void pciehp_destroy_resource_list (struct resource_lists * resources) ...@@ -783,50 +747,26 @@ void pciehp_destroy_resource_list (struct resource_lists * resources)
} }
} }
/**
/* * pciehp_destroy_resource_list: put node back in the resource list
* pciehp_destroy_board_resources * @resources: list to put nodes back
*
* Puts node back in the resource list pointed to by head
*/ */
void pciehp_destroy_board_resources (struct pci_func * func) void pciehp_destroy_resource_list(struct resource_lists * resources)
{ {
struct pci_resource *res, *tres; kfree_resource_list(&(resources->io_head));
kfree_resource_list(&(resources->mem_head));
res = func->io_head; kfree_resource_list(&(resources->p_mem_head));
func->io_head = NULL; kfree_resource_list(&(resources->bus_head));
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = func->mem_head;
func->mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = func->p_mem_head;
func->p_mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = func->bus_head;
func->bus_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
} }
/**
* pciehp_destroy_board_resources: put node back in the resource list
* @resources: list to put nodes back
*/
void pciehp_destroy_board_resources(struct pci_func * func)
{
kfree_resource_list(&(func->io_head));
kfree_resource_list(&(func->mem_head));
kfree_resource_list(&(func->p_mem_head));
kfree_resource_list(&(func->bus_head));
}
...@@ -531,49 +531,35 @@ static int shpc_start_thread(void) ...@@ -531,49 +531,35 @@ static int shpc_start_thread(void)
return retval; return retval;
} }
static inline void __exit
free_shpchp_res(struct pci_resource *res)
{
struct pci_resource *tres;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
}
static void unload_shpchpd(void) static void __exit unload_shpchpd(void)
{ {
struct pci_func *next; struct pci_func *next;
struct pci_func *TempSlot; struct pci_func *TempSlot;
int loop; int loop;
struct controller *ctrl; struct controller *ctrl;
struct controller *tctrl; struct controller *tctrl;
struct pci_resource *res;
struct pci_resource *tres;
ctrl = shpchp_ctrl_list; ctrl = shpchp_ctrl_list;
while (ctrl) { while (ctrl) {
cleanup_slots(ctrl); cleanup_slots(ctrl);
res = ctrl->io_head; free_shpchp_res(ctrl->io_head);
while (res) { free_shpchp_res(ctrl->mem_head);
tres = res; free_shpchp_res(ctrl->p_mem_head);
res = res->next; free_shpchp_res(ctrl->bus_head);
kfree(tres);
}
res = ctrl->mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = ctrl->p_mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = ctrl->bus_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
kfree (ctrl->pci_bus); kfree (ctrl->pci_bus);
...@@ -589,33 +575,10 @@ static void unload_shpchpd(void) ...@@ -589,33 +575,10 @@ static void unload_shpchpd(void)
for (loop = 0; loop < 256; loop++) { for (loop = 0; loop < 256; loop++) {
next = shpchp_slot_list[loop]; next = shpchp_slot_list[loop];
while (next != NULL) { while (next != NULL) {
res = next->io_head; free_shpchp_res(ctrl->io_head);
while (res) { free_shpchp_res(ctrl->mem_head);
tres = res; free_shpchp_res(ctrl->p_mem_head);
res = res->next; free_shpchp_res(ctrl->bus_head);
kfree(tres);
}
res = next->mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = next->p_mem_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = next->bus_head;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
TempSlot = next; TempSlot = next;
next = next->next; next = next->next;
...@@ -697,8 +660,5 @@ static void __exit shpcd_cleanup(void) ...@@ -697,8 +660,5 @@ static void __exit shpcd_cleanup(void)
info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
} }
module_init(shpcd_init); module_init(shpcd_init);
module_exit(shpcd_cleanup); module_exit(shpcd_cleanup);
...@@ -664,9 +664,27 @@ int shpchp_save_used_resources (struct controller *ctrl, struct pci_func *func, ...@@ -664,9 +664,27 @@ int shpchp_save_used_resources (struct controller *ctrl, struct pci_func *func,
func = shpchp_slot_find(func->bus, func->device, index++); func = shpchp_slot_find(func->bus, func->device, index++);
} }
return(0); return 0;
} }
/**
* kfree_resource_list: release memory of all list members
* @res: resource list to free
*/
static inline void
return_resource_list(struct pci_resource **func, struct pci_resource **res)
{
struct pci_resource *node;
struct pci_resource *t_node;
node = *func;
*func = NULL;
while (node) {
t_node = node->next;
return_resource(res, node);
node = t_node;
}
}
/* /*
* shpchp_return_board_resources * shpchp_return_board_resources
...@@ -676,95 +694,39 @@ int shpchp_save_used_resources (struct controller *ctrl, struct pci_func *func, ...@@ -676,95 +694,39 @@ int shpchp_save_used_resources (struct controller *ctrl, struct pci_func *func,
* *
* returns 0 if success * returns 0 if success
*/ */
int shpchp_return_board_resources(struct pci_func * func, struct resource_lists * resources) int shpchp_return_board_resources(struct pci_func * func,
struct resource_lists * resources)
{ {
int rc = 0; int rc;
struct pci_resource *node;
struct pci_resource *t_node;
dbg("%s\n", __FUNCTION__); dbg("%s\n", __FUNCTION__);
if (!func) if (!func)
return(1); return 1;
node = func->io_head;
func->io_head = NULL;
while (node) {
t_node = node->next;
return_resource(&(resources->io_head), node);
node = t_node;
}
node = func->mem_head;
func->mem_head = NULL;
while (node) {
t_node = node->next;
return_resource(&(resources->mem_head), node);
node = t_node;
}
node = func->p_mem_head;
func->p_mem_head = NULL;
while (node) {
t_node = node->next;
return_resource(&(resources->p_mem_head), node);
node = t_node;
}
node = func->bus_head; return_resource_list(&(func->io_head),&(resources->io_head));
func->bus_head = NULL; return_resource_list(&(func->mem_head),&(resources->mem_head));
while (node) { return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
t_node = node->next; return_resource_list(&(func->bus_head),&(resources->bus_head));
return_resource(&(resources->bus_head), node);
node = t_node;
}
rc |= shpchp_resource_sort_and_combine(&(resources->mem_head)); rc = shpchp_resource_sort_and_combine(&(resources->mem_head));
rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head)); rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head));
rc |= shpchp_resource_sort_and_combine(&(resources->io_head)); rc |= shpchp_resource_sort_and_combine(&(resources->io_head));
rc |= shpchp_resource_sort_and_combine(&(resources->bus_head)); rc |= shpchp_resource_sort_and_combine(&(resources->bus_head));
return(rc); return rc;
} }
/**
/* * kfree_resource_list: release memory of all list members
* shpchp_destroy_resource_list * @res: resource list to free
*
* Puts node back in the resource list pointed to by head
*/ */
void shpchp_destroy_resource_list (struct resource_lists * resources) static inline void
kfree_resource_list(struct pci_resource **r)
{ {
struct pci_resource *res, *tres; struct pci_resource *res, *tres;
res = resources->io_head; res = *r;
resources->io_head = NULL; *r = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = resources->mem_head;
resources->mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = resources->p_mem_head;
resources->p_mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = resources->bus_head;
resources->bus_head = NULL;
while (res) { while (res) {
tres = res; tres = res;
...@@ -773,50 +735,26 @@ void shpchp_destroy_resource_list (struct resource_lists * resources) ...@@ -773,50 +735,26 @@ void shpchp_destroy_resource_list (struct resource_lists * resources)
} }
} }
/**
/* * shpchp_destroy_resource_list: put node back in the resource list
* shpchp_destroy_board_resources * @resources: list to put nodes back
*
* Puts node back in the resource list pointed to by head
*/ */
void shpchp_destroy_board_resources (struct pci_func * func) void shpchp_destroy_resource_list(struct resource_lists *resources)
{ {
struct pci_resource *res, *tres; kfree_resource_list(&(resources->io_head));
kfree_resource_list(&(resources->mem_head));
res = func->io_head; kfree_resource_list(&(resources->p_mem_head));
func->io_head = NULL; kfree_resource_list(&(resources->bus_head));
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = func->mem_head;
func->mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = func->p_mem_head;
func->p_mem_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
res = func->bus_head;
func->bus_head = NULL;
while (res) {
tres = res;
res = res->next;
kfree(tres);
}
} }
/**
* shpchp_destroy_board_resources: put node back in the resource list
* @resources: list to put nodes back
*/
void shpchp_destroy_board_resources(struct pci_func * func)
{
kfree_resource_list(&(func->io_head));
kfree_resource_list(&(func->mem_head));
kfree_resource_list(&(func->p_mem_head));
kfree_resource_list(&(func->bus_head));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment