Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0fb2eb7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: core: fix sleep in atomic context due to driver core change
parents 32b838b8 62305823
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -209,6 +209,8 @@ fw_card_bm_work(struct work_struct *work)
	unsigned long flags;
	unsigned long flags;
	int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
	int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
	bool do_reset = false;
	bool do_reset = false;
	bool root_device_is_running;
	bool root_device_is_cmc;
	__be32 lock_data[2];
	__be32 lock_data[2];


	spin_lock_irqsave(&card->lock, flags);
	spin_lock_irqsave(&card->lock, flags);
@@ -224,8 +226,9 @@ fw_card_bm_work(struct work_struct *work)


	generation = card->generation;
	generation = card->generation;
	root_device = root_node->data;
	root_device = root_node->data;
	if (root_device)
	root_device_is_running = root_device &&
		fw_device_get(root_device);
			atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
	root_device_is_cmc = root_device && root_device->cmc;
	root_id = root_node->node_id;
	root_id = root_node->node_id;
	grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
	grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));


@@ -308,14 +311,14 @@ fw_card_bm_work(struct work_struct *work)
		 * config rom.  In either case, pick another root.
		 * config rom.  In either case, pick another root.
		 */
		 */
		new_root_id = local_node->node_id;
		new_root_id = local_node->node_id;
	} else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) {
	} else if (!root_device_is_running) {
		/*
		/*
		 * If we haven't probed this device yet, bail out now
		 * If we haven't probed this device yet, bail out now
		 * and let's try again once that's done.
		 * and let's try again once that's done.
		 */
		 */
		spin_unlock_irqrestore(&card->lock, flags);
		spin_unlock_irqrestore(&card->lock, flags);
		goto out;
		goto out;
	} else if (root_device->cmc) {
	} else if (root_device_is_cmc) {
		/*
		/*
		 * FIXME: I suppose we should set the cmstr bit in the
		 * FIXME: I suppose we should set the cmstr bit in the
		 * STATE_CLEAR register of this node, as described in
		 * STATE_CLEAR register of this node, as described in
@@ -362,8 +365,6 @@ fw_card_bm_work(struct work_struct *work)
		fw_core_initiate_bus_reset(card, 1);
		fw_core_initiate_bus_reset(card, 1);
	}
	}
 out:
 out:
	if (root_device)
		fw_device_put(root_device);
	fw_node_put(root_node);
	fw_node_put(root_node);
	fw_node_put(local_node);
	fw_node_put(local_node);
 out_put_card:
 out_put_card:
+13 −10
Original line number Original line Diff line number Diff line
@@ -159,7 +159,8 @@ static void fw_device_release(struct device *dev)


	/*
	/*
	 * Take the card lock so we don't set this to NULL while a
	 * Take the card lock so we don't set this to NULL while a
	 * FW_NODE_UPDATED callback is being handled.
	 * FW_NODE_UPDATED callback is being handled or while the
	 * bus manager work looks at this node.
	 */
	 */
	spin_lock_irqsave(&card->lock, flags);
	spin_lock_irqsave(&card->lock, flags);
	device->node->data = NULL;
	device->node->data = NULL;
@@ -695,12 +696,13 @@ static void fw_device_init(struct work_struct *work)
		return;
		return;
	}
	}


	err = -ENOMEM;
	device_initialize(&device->device);


	fw_device_get(device);
	fw_device_get(device);
	down_write(&fw_device_rwsem);
	down_write(&fw_device_rwsem);
	if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
	err = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
		err = idr_get_new(&fw_device_idr, device, &minor);
	      idr_get_new(&fw_device_idr, device, &minor) :
	      -ENOMEM;
	up_write(&fw_device_rwsem);
	up_write(&fw_device_rwsem);


	if (err < 0)
	if (err < 0)
@@ -911,13 +913,14 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)


		/*
		/*
		 * Do minimal intialization of the device here, the
		 * Do minimal intialization of the device here, the
		 * rest will happen in fw_device_init().  We need the
		 * rest will happen in fw_device_init().
		 * card and node so we can read the config rom and we
		 *
		 * need to do device_initialize() now so
		 * Attention:  A lot of things, even fw_device_get(),
		 * device_for_each_child() in FW_NODE_UPDATED is
		 * cannot be done before fw_device_init() finished!
		 * doesn't freak out.
		 * You can basically just check device->state and
		 * schedule work until then, but only while holding
		 * card->lock.
		 */
		 */
		device_initialize(&device->device);
		atomic_set(&device->state, FW_DEVICE_INITIALIZING);
		atomic_set(&device->state, FW_DEVICE_INITIALIZING);
		device->card = fw_card_get(card);
		device->card = fw_card_get(card);
		device->node = fw_node_get(node);
		device->node = fw_node_get(node);