aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-card.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-01-09 14:49:37 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-01-09 17:22:32 -0500
commit6230582320b721e6cf2581d048cb688dca97f504 (patch)
tree2babcf29c086cf77b8df9fbe54303214b1be01ad /drivers/firewire/fw-card.c
parent73d59314e6ed268d6f322ae1bdd723b23fa5a4ed (diff)
firewire: core: fix sleep in atomic context due to driver core change
Due to commit 2831fe6f9cc4e16c103504ee09a47a084297c0f3, "driver core: create a private portion of struct device", device_initialize() can no longer be called from atomic contexts. We now defer it until after config ROM probing. This requires changes to the bus manager code because this may use a device before it was probed. Reported-by: Jay Fenlason <fenlason@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-card.c')
-rw-r--r--drivers/firewire/fw-card.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 799f94424c8a..6bd91a15d5e6 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -209,6 +209,8 @@ fw_card_bm_work(struct work_struct *work)
209 unsigned long flags; 209 unsigned long flags;
210 int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode; 210 int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
211 bool do_reset = false; 211 bool do_reset = false;
212 bool root_device_is_running;
213 bool root_device_is_cmc;
212 __be32 lock_data[2]; 214 __be32 lock_data[2];
213 215
214 spin_lock_irqsave(&card->lock, flags); 216 spin_lock_irqsave(&card->lock, flags);
@@ -224,8 +226,9 @@ fw_card_bm_work(struct work_struct *work)
224 226
225 generation = card->generation; 227 generation = card->generation;
226 root_device = root_node->data; 228 root_device = root_node->data;
227 if (root_device) 229 root_device_is_running = root_device &&
228 fw_device_get(root_device); 230 atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
231 root_device_is_cmc = root_device && root_device->cmc;
229 root_id = root_node->node_id; 232 root_id = root_node->node_id;
230 grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); 233 grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
231 234
@@ -308,14 +311,14 @@ fw_card_bm_work(struct work_struct *work)
308 * config rom. In either case, pick another root. 311 * config rom. In either case, pick another root.
309 */ 312 */
310 new_root_id = local_node->node_id; 313 new_root_id = local_node->node_id;
311 } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) { 314 } else if (!root_device_is_running) {
312 /* 315 /*
313 * If we haven't probed this device yet, bail out now 316 * If we haven't probed this device yet, bail out now
314 * and let's try again once that's done. 317 * and let's try again once that's done.
315 */ 318 */
316 spin_unlock_irqrestore(&card->lock, flags); 319 spin_unlock_irqrestore(&card->lock, flags);
317 goto out; 320 goto out;
318 } else if (root_device->cmc) { 321 } else if (root_device_is_cmc) {
319 /* 322 /*
320 * FIXME: I suppose we should set the cmstr bit in the 323 * FIXME: I suppose we should set the cmstr bit in the
321 * STATE_CLEAR register of this node, as described in 324 * STATE_CLEAR register of this node, as described in
@@ -362,8 +365,6 @@ fw_card_bm_work(struct work_struct *work)
362 fw_core_initiate_bus_reset(card, 1); 365 fw_core_initiate_bus_reset(card, 1);
363 } 366 }
364 out: 367 out:
365 if (root_device)
366 fw_device_put(root_device);
367 fw_node_put(root_node); 368 fw_node_put(root_node);
368 fw_node_put(local_node); 369 fw_node_put(local_node);
369 out_put_card: 370 out_put_card: