Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 333269
b: refs/heads/master
c: 2574740
h: refs/heads/master
i:
  333267: 2329add
v: v3
  • Loading branch information
Alexandre Bounine authored and Linus Torvalds committed Oct 10, 2012
1 parent 25f6941 commit 550b55f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 29 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: f4c9c0e83bdfab6d3de7bc9ad728d99bf6adde92
refs/heads/master: 2574740d1fe946803caa6b0c06fbb4bf397af35d
75 changes: 47 additions & 28 deletions trunk/drivers/rapidio/rio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,49 +1275,68 @@ static void __devinit disc_work_handler(struct work_struct *_work)
pr_debug("RIO: discovery work for mport %d %s\n",
work->mport->id, work->mport->name);
rio_disc_mport(work->mport);

kfree(work);
}

int __devinit rio_init_mports(void)
{
struct rio_mport *port;
struct rio_disc_work *work;
int no_disc = 0;
int n = 0;

if (!next_portid)
return -ENODEV;

/*
* First, run enumerations and check if we need to perform discovery
* on any of the registered mports.
*/
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid >= 0)
rio_enum_mport(port);
else if (!no_disc) {
if (!rio_wq) {
rio_wq = alloc_workqueue("riodisc", 0, 0);
if (!rio_wq) {
pr_err("RIO: unable allocate rio_wq\n");
no_disc = 1;
continue;
}
}

work = kzalloc(sizeof *work, GFP_KERNEL);
if (!work) {
pr_err("RIO: no memory for work struct\n");
no_disc = 1;
continue;
}

work->mport = port;
INIT_WORK(&work->work, disc_work_handler);
queue_work(rio_wq, &work->work);
}
else
n++;
}

if (!n)
goto no_disc;

/*
* If we have mports that require discovery schedule a discovery work
* for each of them. If the code below fails to allocate needed
* resources, exit without error to keep results of enumeration
* process (if any).
* TODO: Implement restart of dicovery process for all or
* individual discovering mports.
*/
rio_wq = alloc_workqueue("riodisc", 0, 0);
if (!rio_wq) {
pr_err("RIO: unable allocate rio_wq\n");
goto no_disc;
}

if (rio_wq) {
pr_debug("RIO: flush discovery workqueue\n");
flush_workqueue(rio_wq);
pr_debug("RIO: flush discovery workqueue finished\n");
work = kcalloc(n, sizeof *work, GFP_KERNEL);
if (!work) {
pr_err("RIO: no memory for work struct\n");
destroy_workqueue(rio_wq);
goto no_disc;
}

n = 0;
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid < 0) {
work[n].mport = port;
INIT_WORK(&work[n].work, disc_work_handler);
queue_work(rio_wq, &work[n].work);
n++;
}
}

flush_workqueue(rio_wq);
pr_debug("RIO: destroy discovery workqueue\n");
destroy_workqueue(rio_wq);
kfree(work);

no_disc:
rio_init();

return 0;
Expand Down

0 comments on commit 550b55f

Please sign in to comment.