aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device.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-device.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-device.c')
-rw-r--r--drivers/firewire/fw-device.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index c173be383725..2af5a8d1e012 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -159,7 +159,8 @@ static void fw_device_release(struct device *dev)
159 159
160 /* 160 /*
161 * Take the card lock so we don't set this to NULL while a 161 * Take the card lock so we don't set this to NULL while a
162 * FW_NODE_UPDATED callback is being handled. 162 * FW_NODE_UPDATED callback is being handled or while the
163 * bus manager work looks at this node.
163 */ 164 */
164 spin_lock_irqsave(&card->lock, flags); 165 spin_lock_irqsave(&card->lock, flags);
165 device->node->data = NULL; 166 device->node->data = NULL;
@@ -695,12 +696,13 @@ static void fw_device_init(struct work_struct *work)
695 return; 696 return;
696 } 697 }
697 698
698 err = -ENOMEM; 699 device_initialize(&device->device);
699 700
700 fw_device_get(device); 701 fw_device_get(device);
701 down_write(&fw_device_rwsem); 702 down_write(&fw_device_rwsem);
702 if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) 703 err = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
703 err = idr_get_new(&fw_device_idr, device, &minor); 704 idr_get_new(&fw_device_idr, device, &minor) :
705 -ENOMEM;
704 up_write(&fw_device_rwsem); 706 up_write(&fw_device_rwsem);
705 707
706 if (err < 0) 708 if (err < 0)
@@ -911,13 +913,14 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
911 913
912 /* 914 /*
913 * Do minimal intialization of the device here, the 915 * Do minimal intialization of the device here, the
914 * rest will happen in fw_device_init(). We need the 916 * rest will happen in fw_device_init().
915 * card and node so we can read the config rom and we 917 *
916 * need to do device_initialize() now so 918 * Attention: A lot of things, even fw_device_get(),
917 * device_for_each_child() in FW_NODE_UPDATED is 919 * cannot be done before fw_device_init() finished!
918 * doesn't freak out. 920 * You can basically just check device->state and
921 * schedule work until then, but only while holding
922 * card->lock.
919 */ 923 */
920 device_initialize(&device->device);
921 atomic_set(&device->state, FW_DEVICE_INITIALIZING); 924 atomic_set(&device->state, FW_DEVICE_INITIALIZING);
922 device->card = fw_card_get(card); 925 device->card = fw_card_get(card);
923 device->node = fw_node_get(node); 926 device->node = fw_node_get(node);