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

Commit 0fa1986f authored by Jay Fenlason's avatar Jay Fenlason Committed by Stefan Richter
Browse files

firewire: improve refcounting of fw_card



Take a reference to the card whenever fw_card_bm_work() is scheduled on
that card and release it when the work is done.  This allows us to
remove the cancel_delayed_work_sync() in fw_core_remove_card().

Signed-off-by: default avatarJay Fenlason <fenlason@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (patch update)
parent 2cc489c2
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -189,6 +189,17 @@ static const char gap_count_table[] = {
	63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
};

void
fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
{
	int scheduled;

	fw_card_get(card);
	scheduled = schedule_delayed_work(&card->work, delay);
	if (!scheduled)
		fw_card_put(card);
}

static void
fw_card_bm_work(struct work_struct *work)
{
@@ -206,7 +217,7 @@ fw_card_bm_work(struct work_struct *work)

	if (local_node == NULL) {
		spin_unlock_irqrestore(&card->lock, flags);
		return;
		goto out_put_card;
	}
	fw_node_get(local_node);
	fw_node_get(root_node);
@@ -280,7 +291,7 @@ fw_card_bm_work(struct work_struct *work)
		 * this task 100ms from now.
		 */
		spin_unlock_irqrestore(&card->lock, flags);
		schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10));
		fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 10));
		goto out;
	}

@@ -355,6 +366,8 @@ fw_card_bm_work(struct work_struct *work)
		fw_device_put(root_device);
	fw_node_put(root_node);
	fw_node_put(local_node);
 out_put_card:
	fw_card_put(card);
}

static void
@@ -510,7 +523,6 @@ fw_core_remove_card(struct fw_card *card)
	fw_card_put(card);
	wait_for_completion(&card->done);

	cancel_delayed_work_sync(&card->work);
	WARN_ON(!list_empty(&card->transaction_list));
	del_timer_sync(&card->flush_timer);
}
+3 −3
Original line number Diff line number Diff line
@@ -689,7 +689,7 @@ static void fw_device_init(struct work_struct *work)
			fw_notify("giving up on config rom for node id %x\n",
				  device->node_id);
			if (device->node == device->card->root_node)
				schedule_delayed_work(&device->card->work, 0);
				fw_schedule_bm_work(device->card, 0);
			fw_device_release(&device->device);
		}
		return;
@@ -758,7 +758,7 @@ static void fw_device_init(struct work_struct *work)
	 * pretty harmless.
	 */
	if (device->node == device->card->root_node)
		schedule_delayed_work(&device->card->work, 0);
		fw_schedule_bm_work(device->card, 0);

	return;

@@ -892,7 +892,7 @@ static void fw_device_refresh(struct work_struct *work)
	fw_device_shutdown(work);
 out:
	if (node_id == card->root_node->node_id)
		schedule_delayed_work(&card->work, 0);
		fw_schedule_bm_work(card, 0);
}

void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
+1 −1
Original line number Diff line number Diff line
@@ -530,7 +530,7 @@ fw_core_handle_bus_reset(struct fw_card *card,
	smp_wmb();
	card->generation = generation;
	card->reset_jiffies = jiffies;
	schedule_delayed_work(&card->work, 0);
	fw_schedule_bm_work(card, 0);

	local_node = build_tree(card, self_ids, self_id_count);

+2 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ static inline void fw_card_put(struct fw_card *card)
	kref_put(&card->kref, fw_card_release);
}

extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);

/*
 * The iso packet format allows for an immediate header/payload part
 * stored in 'header' immediately after the packet info plus an